Webhook event triggers
Every event your registered webhook receives, from cold email sends and replies to clicks, bounces, unsubscribes, and lead stage changes.
Open in Tantra
These open the app in a new tab. You may be asked to sign in.
Overview
A single webhook endpoint you register in Tantra receives more than calendar RSVP updates. Your cold email activity also fires events to the same endpoint: sends, replies, clicks, bounces, unsubscribes, sequence completions, lead stage changes, and reply intent classifications. This article lists every event, its payload, and how to tell them apart.
If you have not registered an endpoint yet, start with Receive outbound webhooks.
How it works
Every active webhook you register receives every event type. There is no per-event subscription in the app, so your endpoint should read the event type and ignore the events it does not care about.
Each event is delivered as an HTTP POST with a JSON body and these headers:
| Header | Value |
|---|---|
Content-Type | application/json |
X-Tantra-Event | the event type, for example email.replied |
X-Tantra-Event-Id | a unique id for this event |
Switch on the X-Tantra-Event header (or the event type in the body) to route each event. A response with a 2xx status counts as delivered.
Idempotency
Every event carries a stable X-Tantra-Event-Id. The same real-world event always produces the same id, and Tantra records delivery per endpoint and id, so a retried or duplicated event arrives with an id you have seen before. Store the ids you have processed and skip repeats. This makes your handler safe even if the same event is delivered more than once.
Event reference
Every event payload includes the recipient email, a timestamp (occurredAt, ISO 8601), and, where relevant, the campaign and enrollment it belongs to. The fields below are what each event adds on top of that.
Event (X-Tantra-Event) | Fires when | Notable fields |
|---|---|---|
email.sent | A sequence email is sent | subject, gmailMessageId, messageIdHeader |
email.clicked | A recipient clicks a tracked link | url, clickedAt, messageId, userAgent, trackingDomainHost |
email.replied | A genuine reply is detected | fromEmail, snippet, intentHint (positive, negative, neutral), inboundGmailMessageId |
email.intent.classified | A reply is classified by intent | newIntent, confidence, previousIntentHint, messageId |
email.bounced | A bounce or spam complaint is parsed | bounceCategory (hard, soft, spam_complaint), bounceCode, dsnSnippet |
email.unsubscribed | A recipient unsubscribes | source (list_unsubscribe_one_click, link_click, stop_word_reply, ai_intent_reply) |
email.sequence.completed | An enrollment ends | completionReason (all_steps_sent, replied, bounced, unsubscribed, manually_stopped) |
lead.stage.changed | A lead moves to a new stage | previousStage, newStage, reason |
Bot clicks are filtered out before email.clicked fires, so you only receive human clicks. See How click tracking works.
Example payloads
A reply event:
{
"eventType": "email.replied",
"eventId": "a1b2c3d4e5f6...",
"occurredAt": "2026-07-26T14:03:11.000Z",
"recipientEmail": "alice@example.com",
"campaignId": "email_campaign_123",
"enrollmentId": "enrollment_456",
"fromEmail": "alice@example.com",
"snippet": "This looks interesting, can you send pricing?",
"intentHint": "positive"
}
A click event:
{
"eventType": "email.clicked",
"eventId": "f6e5d4c3b2a1...",
"occurredAt": "2026-07-26T15:20:44.000Z",
"recipientEmail": "bob@example.com",
"campaignId": "email_campaign_123",
"url": "https://your-site.example.com/pricing",
"clickedAt": "2026-07-26T15:20:44.000Z"
}
Connect to a CRM or automation tool
Because every event is a plain HTTP POST to a URL you choose, you can send Tantra activity straight into automation platforms such as n8n, Zapier, or Make (formerly Integromat), and from there into a CRM like HubSpot, Pipedrive, or Salesforce. Tantra does not ship a dedicated app for these tools, so you use their generic webhook building block.
The pattern is the same in each:
- In n8n, Zapier, or Make, create a new flow that starts with an incoming webhook step. n8n calls it a Webhook node, Zapier calls it Catch Hook (Webhooks by Zapier), and Make calls it a Custom webhook. Each gives you a unique URL.
- Copy that URL and register it as your endpoint in Tantra. See Receive outbound webhooks.
- Add a filter or switch step that branches on the
X-Tantra-Eventheader or theeventTypefield, so each event routes to the right action. - Map the payload fields to your CRM. For example, on
email.repliedwithintentHintofpositive, create or update a lead and set its stage.
For two-way integration, pair the outbound events with Tantra's REST API. Events push activity out in real time, and the REST API lets your flow read or update Tantra data using an API key. See Create and manage API keys to issue a key, and Connect the Tantra MCP server if your automation runs through an AI assistant.
What happens next
Once your endpoint is active, these events start arriving as your cold email campaigns run. Sends fire as steps go out, clicks and replies fire as recipients engage, and sequence completions fire as enrollments finish. Calendar RSVP payloads arrive on the same endpoint on their own schedule, in the RSVP format described in Receive outbound webhooks.
Best practices
- Route on
X-Tantra-Event. Handle the events you use and return2xxfor the rest so Tantra does not retry them. - Deduplicate on
X-Tantra-Event-Id. Treat delivery as at-least-once, not exactly-once. - Reply
2xxquickly, then do slower work after responding, so you stay within the delivery timeout. - Do not assume only RSVP data arrives. Guard your handler against event types you have not seen before.
Common mistakes
- Writing a handler that assumes the RSVP payload shape. Cold email events have a different, flatter shape keyed by
eventType. - Treating every delivery as a new event. Retries reuse the same
X-Tantra-Event-Id. - Expecting a way to subscribe to only one event type. Every active webhook receives all events, so filter in your own code.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Receiving events you did not expect | Every active webhook receives every event type | Filter on X-Tantra-Event and ignore the rest |
| The same event arrives twice | A delivery was retried | Deduplicate on X-Tantra-Event-Id |
| No email events arrive | No cold email activity yet, or the webhook is inactive | Confirm the webhook Status is on and that a campaign is actively sending |
FAQ
Can I subscribe to only some events?
Not from the app. Every active webhook receives every event type. Filter on the X-Tantra-Event header in your handler.
How do I tell events apart?
Read the X-Tantra-Event header, or the eventType field in the body. Each type has its own set of fields.
Are deliveries exactly once?
No. Treat them as at-least-once and deduplicate on X-Tantra-Event-Id, which is stable for a given event.
Do click events include bot clicks?
No. Bot clicks are filtered out before the email.clicked event fires, so you receive human clicks only.
Do calendar RSVP updates use these events?
RSVP data arrives on the same endpoint but in its own payload format, covered in Receive outbound webhooks.
Can I connect Tantra to my CRM?
Yes, through an automation tool. Point a webhook at an n8n, Zapier, or Make flow, branch on the event type, and map the fields into your CRM. Pair it with the REST API and an API key for two-way sync. See the "Connect to a CRM or automation tool" section above.
Related articles
Was this article helpful?
Related articles
- Receive outbound webhooksRegister an endpoint URL to receive Tantra webhooks, from calendar RSVP counts to cold email events, and learn how delivery and retries work.
- Create and manage API keysCreate a Tantra API key, copy it once at creation, use it in the X-API-Key header, and revoke keys you no longer need.
- Connect the Tantra MCP serverInstall the Tantra MCP server, give it your API key, and use Tantra campaigns, contacts, and templates as tools inside Claude or Cursor.