Webhook events
Email activity
Sends, replies, categorization, and bounces.
Sends, replies, categorization, and bounces.
These pages are payload reference. For setup, verification, and retries, follow Webhook integration.
Examples use placeholder UUIDs. Live deliveries use real ids from your account.
email.sent
An outbound campaign email was sent. data.email is the lead recipient address for CRM matching. Includes the shared lead identity block and outbound body_text. node_id and flow_node_id are the email that went out. step_number and step_name name the sequence step: step_number counts the campaign's main-sequence emails sent to the lead up to and including that step (waits, the categorizer, emails after the categorizer and inbox replies don't count, and each email counts once); step_name is that email's current name in the flow builder, and both are left out when the lead got no sequence email from Furnace. On an email after the categorizer (such as the hand-off to an Interested lead), the step is the last sequence email the lead got, not the email sent.
{
"id": "00000000-0000-4000-8000-0000000000aa",
"type": "email.sent",
"occurred_at": "2026-06-25T12:00:00.000Z",
"data": {
"campaign_id": "22222222-2222-4222-8222-222222222222",
"campaign_name": "Example campaign",
"lead_id": "00000000-0000-4000-8000-000000000001",
"email": "lead@example.com",
"mailbox_id": "00000000-0000-4000-8000-000000000004",
"mailbox_email": "sender@example.com",
"first_name": "Casey",
"last_name": "Reed",
"full_name": "Casey Reed",
"company_name": "Wasatch Corridor",
"title": "VP Sales",
"website": "https://wasatch.example",
"linkedin_url": "https://linkedin.com/in/casey-reed",
"custom_fields": {
"title": "VP Sales",
"region": "west"
},
"enrollment_id": "00000000-0000-4000-8000-000000000002",
"message_job_id": "00000000-0000-4000-8000-000000000003",
"provider_message_id": "test-provider-message-id",
"sent_at": "2026-06-25T12:00:00.000Z",
"subject": "Example outbound subject (test)",
"body_text": "Hi Casey — quick check-in for next week.",
"step_number": 2,
"step_name": "Email 2: Follow-up",
"node_id": "00000000-0000-4000-8000-000000000009",
"flow_node_id": "email-2"
}
}reply.received
An inbound reply was received on a campaign thread (before categorization completes). data.from_email is the reply sender; data.email is the matched lead. data.body_text is the plain-text display body (quoted history stripped). data.attachments lists files on the reply in the MessageAttachment shape; download one with downloadMessageAttachment using thread_id, email_message_id and its index, soon after the webhook while the email is still in the mailbox inbox. step_number and step_name name the sequence email the reply answers: step_number counts the campaign's main-sequence emails sent to the lead up to and including that step (waits, the categorizer, emails after the categorizer and inbox replies don't count, and each email counts once); step_name is that email's current name in the flow builder, and both are left out when the lead got no sequence email from Furnace. A reply to an email after the categorizer or to an inbox reply gets the last sequence email sent before that email; a reply we can't match gets the last one sent before the reply. node_id and flow_node_id are that step's email.
{
"id": "00000000-0000-4000-8000-0000000000aa",
"type": "reply.received",
"occurred_at": "2026-06-25T12:00:00.000Z",
"data": {
"thread_id": "00000000-0000-4000-8000-000000000005",
"email_message_id": "00000000-0000-4000-8000-000000000006",
"campaign_id": "22222222-2222-4222-8222-222222222222",
"campaign_name": "Example campaign",
"lead_id": "00000000-0000-4000-8000-000000000001",
"email": "lead@example.com",
"mailbox_id": "00000000-0000-4000-8000-000000000004",
"mailbox_email": "sender@example.com",
"first_name": "Casey",
"last_name": "Reed",
"full_name": "Casey Reed",
"company_name": "Wasatch Corridor",
"title": "VP Sales",
"website": "https://wasatch.example",
"linkedin_url": "https://linkedin.com/in/casey-reed",
"custom_fields": {
"title": "VP Sales",
"region": "west"
},
"enrollment_id": "00000000-0000-4000-8000-000000000002",
"step_number": 2,
"step_name": "Email 2: Follow-up",
"node_id": "00000000-0000-4000-8000-000000000009",
"flow_node_id": "email-2",
"from_email": "lead@example.com",
"subject": "Re: Example outbound subject (test)",
"body_text": "Thursday works — send a hold.",
"received_at": "2026-06-25T12:00:00.000Z",
"attachments": [
{
"index": 0,
"filename": "bid.pdf",
"content_type": "application/pdf",
"size": 245644,
"downloadable": true,
"not_downloadable_reason": null
}
]
}
}reply.categorized
A thread reply category was assigned, changed, or cleared (manual, AI, system, or OOO). Includes the same lead identity block as send/reply, and the same step fields as reply.received for the latest reply on the thread (step_number, step_name, node_id, flow_node_id).
{
"id": "00000000-0000-4000-8000-0000000000aa",
"type": "reply.categorized",
"occurred_at": "2026-06-25T12:00:00.000Z",
"data": {
"thread_id": "00000000-0000-4000-8000-000000000005",
"email_message_id": "00000000-0000-4000-8000-000000000006",
"campaign_id": "22222222-2222-4222-8222-222222222222",
"campaign_name": "Example campaign",
"lead_id": "00000000-0000-4000-8000-000000000001",
"email": "lead@example.com",
"mailbox_id": "00000000-0000-4000-8000-000000000004",
"mailbox_email": "sender@example.com",
"first_name": "Casey",
"last_name": "Reed",
"full_name": "Casey Reed",
"company_name": "Wasatch Corridor",
"title": "VP Sales",
"website": "https://wasatch.example",
"linkedin_url": "https://linkedin.com/in/casey-reed",
"custom_fields": {
"title": "VP Sales",
"region": "west"
},
"enrollment_id": "00000000-0000-4000-8000-000000000002",
"step_number": 2,
"step_name": "Email 2: Follow-up",
"node_id": "00000000-0000-4000-8000-000000000009",
"flow_node_id": "email-2",
"category": "Interested",
"previous_category": null,
"category_source": "ai",
"from_email": "lead@example.com",
"subject": "Re: Example outbound subject (test)"
}
}bounce.detected
A hard or soft bounce was detected for a sent message. data.email is the matched lead; candidate_emails remains for diagnostics. reason is severity plus the SMTP code when present. code is the SMTP reply code (550), or the detailed code when the bounce has no reply code. status_code is the detailed status code (5.7.1), or null. bounce_cause says whose side the bounce is on: bad_address means the lead's address doesn't exist or can't receive mail; rejected_our_sender means the receiving server refused mail from the sending IP, domain or mailbox, so the lead may be fine; unclear means it can't be told. Only a hard bounce with bounce_cause: bad_address adds the lead to the block list and emits blocklist.entry_added, unless the account turned off bounce suppression. Every bounce stops that lead's enrollment in the campaign.
{
"id": "00000000-0000-4000-8000-0000000000aa",
"type": "bounce.detected",
"occurred_at": "2026-06-25T12:00:00.000Z",
"data": {
"campaign_id": "22222222-2222-4222-8222-222222222222",
"campaign_name": "Example campaign",
"lead_id": "00000000-0000-4000-8000-000000000001",
"email": "lead@example.com",
"mailbox_id": "00000000-0000-4000-8000-000000000004",
"mailbox_email": "sender@example.com",
"first_name": "Casey",
"last_name": "Reed",
"full_name": "Casey Reed",
"company_name": "Wasatch Corridor",
"title": "VP Sales",
"website": "https://wasatch.example",
"linkedin_url": "https://linkedin.com/in/casey-reed",
"custom_fields": {
"title": "VP Sales",
"region": "west"
},
"enrollment_id": "00000000-0000-4000-8000-000000000002",
"message_job_id": "00000000-0000-4000-8000-000000000003",
"severity": "hard",
"code": "550",
"reason": "hard 550",
"bounce_cause": "bad_address",
"status_code": "5.1.1",
"bounce_message_id": "test-bounce-message-id",
"bounce_uid": 42,
"candidate_emails": [
"lead@example.com"
],
"matched_job_count": 1
}
}