Connect TalkOmni to the tools you already run
Every lead your assistant captures, every appointment it books and every call it finishes can reach your CRM, your automation platform or your own backend within seconds — over a signed webhook, with retries and a delivery log.
Push, pull, embed
Push: events out of TalkOmni
When something happens in a project we POST a signed JSON event to your endpoint. This is what n8n, Make, Zapier and your own backend consume.
Pull: your data inside the conversation
The assistant calls your backend mid-conversation to read a record, check availability or open a ticket. Whitelisted, parameter-validated and audit-logged.
Embed: your reps never leave your own panel
An SSO deep link signs a user who is already logged into your system straight into a TalkOmni screen, with no second login. Included from Pro.
Works with any platform that accepts a webhook
There is no plugin on either side. You create an inbound webhook in your tool, paste its URL into the TalkOmni panel, tick the events you want, and the next matching action is delivered.
n8n
Add a Webhook trigger, put its production URL into TalkOmni, and branch on the X-Talkomni-Event header. Self-hosted or cloud both work — the URL only has to be reachable over HTTPS.
Verify the signature in a code step before you act on the payload: the URL alone is not authentication.
Make
A custom webhook gives you a URL. Paste it into TalkOmni and map the payload fields onto whatever modules come next.
Same rule: check the signature before the scenario writes anything anywhere.
Zapier
Catch the event with Zapier's webhook trigger and route it into any of the thousands of apps Zapier already supports.
Zapier's webhook trigger sits on their paid plans. That is their limit, not ours.
Your own backend
One HTTPS endpoint and one HMAC check, and you have every event. The reference receivers below are the whole integration.
Return 2xx to acknowledge and 503 if you are temporarily down, so the retries can do their job.
Connect in three steps
- 1
Expose an endpoint
In your automation tool or your own service, expose an HTTPS URL that accepts POST. Plain http:// and private addresses are refused.
- 2
Subscribe in the panel
Webhooks → add the URL, name it, tick the events. The signing secret is shown exactly once at creation, so store it; if you lose it, rotate for a new one.
- 3
Verify and act
Check the signature, deduplicate on the delivery id, return 2xx. Every attempt is visible in the panel and a failed one can be replayed.
What actually arrives
One stable envelope for every event: an id, the event type, a timestamp and the event-specific payload. Switch on event_type; the headers carry the same type plus the delivery id you deduplicate on.
POST https://your-backend.example.com/talkomni
Content-Type: application/json
X-Talkomni-Event: lead.captured
X-Talkomni-Delivery-Id: 8f1b1c1e-...
X-Talkomni-Signature: t=1785312000,v1=9c4f...e1
{
"id": "8f1b1c1e-...",
"event_type": "lead.captured",
"created_at": "2026-08-06T12:00:00Z",
"payload": {
"lead_id": "0b7a...",
"project_id": "3c92...",
"conversation_id": "a41d...",
"name": "Jane Doe",
"phone": "+905551112233",
"email": "jane@example.com",
"note": "Asked for a quote for 40 seats"
}
}Verifying the signature
Your endpoint is public, so its URL is not authentication. Every delivery carries an HMAC-SHA256 signature computed with a secret only you and we hold. Reject anything that does not verify.
The recipe
X-Talkomni-Signature: t=<unix_seconds>,v1=<hex>
v1 = HMAC_SHA256(
key = <your webhook secret>,
message = "<unix_seconds>." + <raw request body>
)- Sign the raw body bytes. Re-serializing a parsed JSON body changes them and the signature will never match — this is the mistake that costs integrators the most time.
- Compare in constant time (timingSafeEqual, hmac.compare_digest, hash_equals). A plain equality check leaks the answer through timing.
- The replay window is yours. We send the timestamp and impose no limit, so reject anything older than a few minutes.
- Rotating the secret takes effect immediately, with no grace period. Deliveries your receiver then rejects are treated as a refusal and park as dead-letter, so swap your side promptly and replay whatever got parked.
import crypto from "node:crypto";
const SECRET = process.env.TALKOMNI_WEBHOOK_SECRET;
// `raw` must be the untouched body bytes. In Express:
// app.post("/talkomni", express.raw({ type: "application/json" }), handler)
export function verify(raw, signatureHeader) {
const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(signatureHeader || "");
if (!m) return false;
const [, ts, sig] = m;
// Replay window is yours to pick — we do not impose one. 5 minutes is sane.
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const expected = crypto
.createHmac("sha256", SECRET)
.update(`${ts}.`)
.update(raw)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(sig, "hex"),
Buffer.from(expected, "hex"),
);
}Event catalog
Nine events today. Subscribe to only what you need — a webhook receives nothing for the events it did not tick.
| Event | Fires when |
|---|---|
lead.captured | The assistant's capture_lead action stores a lead, or one of your TalkOmni forms or landing pages is submitted. Form submissions also carry every submitted field and the ad attribution the visitor arrived with. |
appointment.booked | The assistant books a slot. |
appointment.cancelled | Someone cancels an appointment from the panel. |
appointment.rescheduled | Someone moves an appointment to a new date or time from the panel. |
appointment.reminder | The 24-hour or 1-hour reminder goes out. The payload says which one. |
appointment.review | The post-visit review request goes out. |
voice.call.completed | A voice call ends and its report is processed: duration, end reason, summary and your structured-output analysis. |
handoff.requestedAPI access | The bot escalates a conversation to a human, so your own ops backend can pick it up over the API. |
member.joined | A new member accepts an invite to your organization. |
handoff.requested is emitted only for organizations with the API access entitlement (Enterprise, or the API access add-on); every other event is available on every plan. Field-by-field payload shapes live in the developer reference.
Delivery rules
- Retries with backoff
- 408, 429, any 5xx and transport errors are retried: up to five attempts, waiting 5 minutes, 30 minutes, 2 hours and 12 hours in between. After the last one the delivery is parked as dead-letter.
- Any other 4xx is final
- A 400 or a 404 means "I reject this payload", so we stop immediately. If you are only temporarily down, return 503 instead.
- At-least-once, so deduplicate
- The same delivery can arrive more than once. X-Talkomni-Delivery-Id is stable across retries — key your idempotency on it.
- Every attempt is logged
- The panel shows each attempt with its response code and the payload sent, and any delivery can be replayed by hand.
- 100 per minute per URL
- Deliveries to one endpoint are throttled. Over the cap a delivery is deferred to the next window, which does not spend a retry attempt.
- HTTPS only, checked every time
- Plain http:// is refused, and the host is re-resolved on every delivery — an endpoint whose DNS later points at a private address stops receiving.
Your reps never leave your own panel
Push and pull move data. This direction moves the person: your backend mints a one-time link for a user who is already logged into your system, and the link opens a TalkOmni screen with no second login and no password for them to manage.
- The link is single-use and expires in two minutes. The session it opens lasts 8 hours and has no refresh token, so when you remove someone on your side their access dies with the day.
- A user is created the first time you send them. Identity is keyed on your own external_user_id, not on the email, and an email belonging to an account outside your organization is refused.
- The session is always a rep of that one project, never an owner or an admin, whatever you send. Pass a target path to land the person on an exact screen.
- Included in Pro and Enterprise. It is the one API route that does not need the full API access entitlement, and the key it uses carries the sso:write scope alone.
# Your backend, for a user already logged into YOUR panel.
curl -X POST https://api.talkomni.com/v1/projects/<project_id>/sso/link \
-H "X-API-Key: $TALKOMNI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_user_id": "ops-4471",
"email": "ayse@musteri.com",
"name": "Ayşe Y.",
"target": "/dashboard/inbox?conversation=123"
}'
# 201 — redirect the person to url. Single-use, 2 minutes.
{
"url": "https://talkomni.com/api/auth/sso?t=6f1c...9ab",
"expires_in": 120,
"expires_at": "2026-08-06T12:02:00Z"
}Pair it with the handoff.requested event above: your own panel raises the alert, and the link opens that exact conversation.
Questions
- Do you have a native Zapier or Make app?
- Not today, and we would rather say so than show logos we have not built. What we do have is the signed webhook that every one of those platforms consumes with its own built-in webhook trigger. Native directory apps come when customers ask for a specific one.
- Which plan do I need?
- Outbound webhooks are on every plan; an owner or admin sets them up under Webhooks in the panel. Only handoff.requested needs the API access entitlement, because it belongs to the external inbox API.
- How do I test before going live?
- Point a webhook at your automation tool's test URL and then trigger the event for real: capture a lead from the widget, or book an appointment. Every attempt appears in the panel with the response code your endpoint returned.
- What happens when I rotate the secret?
- The new secret applies to the next delivery and the old one stops verifying. There is no grace period, so update your receiver right away and replay anything that failed in between.
- What if my endpoint is down for a day?
- The retry ladder covers about fifteen hours. Anything still failing after the last attempt is parked as dead-letter — not deleted — and you replay it from the panel once you are back.
- Are events delivered in order?
- No. Retries and parallel delivery mean order is not guaranteed. Treat each event as independent and use the timestamps in the payload when sequence matters.
Full payload shapes, the REST API and the tool gateway: developer reference