Skip to main content
When a subscription fires, Reply POSTs a JSON body to your configured url. This page lists the shape for every event type. It’s a reference you can read without signing up — the samples mirror what a live delivery looks like.

Envelope

Every delivery carries a common event envelope at the top level:
{
  "event": {
    "date": "2026-04-21T09:30:00.000Z",
    "id": "4c1b9e74-5ac3-4b0f-9a60-2a37a9b4a2d1",
    "type": "email_replied",
    "user_id": 1234,
    "team_id": 100,
    "subscription_id": 42
  },
  // event-specific fields follow, flat at the top level
}
FieldTypeNotes
event.dateISO-8601 UTCWhen the event occurred in Reply.
event.idUUIDUnique id for this delivery. Use for idempotency if you persist events.
event.typestringEvent name — matches the eventType on the subscription (see below).
event.user_idintReply user id that owns the subscription.
event.team_idintTeam id the event belongs to.
event.subscription_idintSubscription id that fired.

Shared conventions

  • Keys are snake_case. event_type, sequence_fields, reply_blob_url.
  • Enum values are PascalCase strings. "Personal", "EmailDetected", "Hard".
  • Timestamps are ISO-8601 UTC with millisecond precision.
  • Contact reference — events tied to a prospect include a nested contact_fields object. Use contact_fields.id as the stable reference. Subscriptions created with includeProspectCustomFields: true also get contact_custom_fields alongside it.
  • Sequence reference — events tied to a sequence include a sequence_fields object. If SequenceId is 0 (manual action outside a sequence), the object is empty or omitted.
  • Email body toggles — events covering an email respect the subscription’s includeEmailUrl / includeEmailText flags. When false, the corresponding field is absent.

Reusable blocks

These appear in several events. Shown once here, referenced by name below.

contact_fields

{
  "id": 12345,
  "email": "prospect@example.com",
  "first_name": "Test",
  "last_name": "Prospect",
  "full_name": "Test Prospect",
  "title": "Test Title",
  "company": "Test Company",
  "linked_in_profile_url": "https://linkedin.com/in/test",
  "city": "Test City",
  "state": "Test State",
  "country": "Test Country",
  "time_zone_id": "America/Los_Angeles",
  "phone": "+1234567890",
  "domain": "example.com",
  "company_size": "51-200 employees",
  "industry": "Software",
  "sales_navigator": "https://www.linkedin.com/sales/people/test",
  "linked_in_recruiter": "https://www.linkedin.com/recruiter/people/test"
}

contact_custom_fields

Only present when the subscription was created with payloadConfig.includeProspectCustomFields: true. Keys are the custom field titles configured on the contact.
{
  "Custom Field 1": "Custom Value 1"
}

sequence_fields

{
  "id": 200,
  "name": "Test Sequence",
  "step_number": 1
}

Event reference

email_replied

When: a prospect replies to a sequence email, or a Reply user manually marks the prospect as replied.
{
  "event": { "date": "2026-04-21T09:30:00.000Z", "id": "…", "type": "email_replied", "user_id": 1234, "team_id": 100, "subscription_id": 42 },
  "email_account_id": 1,
  "sent_email_id": 999,
  "reply_date": "2026-04-21T09:30:00.000Z",
  "reply_message_id": "test-reply-msg-id",
  "reply_reason": "EmailDetected",
  "email_from": "account@example.com",
  "reply_blob_url": "https://example.com/test-email-blob",
  "reply_content": "<html>…</html>",
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200, "name": "Test Sequence", "step_number": 1 }
}
  • reply_reason"EmailDetected" when Reply detected the inbound message, "StatusSetManually" when a user flipped the status.
  • reply_blob_url — present when includeEmailUrl: true.
  • reply_content — present when includeEmailText: true.

reply_categorized

When: Reply auto-categorizes a received reply (e.g. Interested, Not Interested, Meeting Request).
{
  "event": { "…": "envelope", "type": "reply_categorized" },
  "sent_email_id": 999,
  "category_type": "Interested",
  "category_name": "Interested",
  "meeting_intent": false,
  "reply_date": "2026-04-21T09:30:00.000Z",
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200 }
}

email_sent

When: Reply successfully dispatches an email from a sequence step.
{
  "event": { "…": "envelope", "type": "email_sent" },
  "email_account_id": 1,
  "sent_email_id": 999,
  "message_id": "test-message-id",
  "sent_at": "2026-04-21T09:30:00.000Z",
  "email_blob_url": "https://example.com/test-email-blob",
  "email_content": "<html>…</html>",
  "email_from": "account@example.com",
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200, "step_number": 1 }
}

email_opened

When: a tracked email is opened.
{
  "event": { "…": "envelope", "type": "email_opened" },
  "email_account_id": 1,
  "sent_email_id": 999,
  "opening_date": "2026-04-21T09:30:00.000Z",
  "opens_count": 1,
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200, "step_number": 1 }
}
When: a recipient clicks a tracked link inside an email.
{
  "event": { "…": "envelope", "type": "email_link_clicked" },
  "email_account_id": 1,
  "email_link_url": "https://example.com/test-link",
  "clicks_count": 1,
  "action_date": "2026-04-21T09:30:00.000Z",
  "email_from": "account@example.com",
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200, "name": "Test Sequence", "step_number": 1 }
}

email_bounced

When: a sent email bounces (hard or soft).
{
  "event": { "…": "envelope", "type": "email_bounced" },
  "email_account_id": 1,
  "sent_email_id": 999,
  "bounce_date": "2026-04-21T09:30:00.000Z",
  "bounce_type": "Hard",
  "bounce_message_id": "test-bounce-id",
  "bounce_blob_url": "https://example.com/test-email-blob",
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200, "step_number": 1 }
}
  • bounce_type"Hard", "Soft", "Block", or "Unknown".

email_auto_reply

When: Reply detects an auto-reply (out-of-office, vacation responder) coming from the prospect.
{
  "event": { "…": "envelope", "type": "email_auto_reply" },
  "email_account_id": 1,
  "sent_email_id": 999,
  "reply_date": "2026-04-21T09:30:00.000Z",
  "reply_message_id": "test-reply-id",
  "subject": "Out of Office: Test Subject",
  "reply_detected_type": "AutoReply",
  "reply_blob_url": "https://example.com/test-email-blob",
  "reply_content": "<html>…</html>",
  "email_from": "account@example.com",
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200, "step_number": 1 }
}

email_account_connection_lost

When: a connected mailbox stops authenticating (OAuth revoked, password changed, etc.). No prospect context — this is an account-level event.
{
  "event": { "…": "envelope", "type": "email_account_connection_lost" },
  "email_account_id": 1,
  "email_account_address": "account@example.com"
}

email_account_error

When: a connected mailbox raises a warning (reputation issue, sending pause, limit hit).
{
  "event": { "…": "envelope", "type": "email_account_error" },
  "email_account_id": 1,
  "email_account_error": "Test error message",
  "email_account_address": "account@example.com"
}

contact_finished

When: a prospect completes all steps of a sequence (or is finished early for some reason — see finish_reason).
{
  "event": { "…": "envelope", "type": "contact_finished" },
  "finish_reason": "Replied",
  "finished_at": "2026-04-21T09:30:00.000Z",
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200 }
}
  • finish_reason"Replied", "OptedOut", "Bounced", "Failed", "FinishedNaturally", "FailedToFinish", "RemovedFromCampaign".

contact_opted_out

When: a prospect opts out (unsubscribes).
{
  "event": { "…": "envelope", "type": "contact_opted_out" },
  "sent_email_id": 999,
  "opt_out_date": "2026-04-21T09:30:00.000Z",
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200, "name": "Test Sequence", "step_number": 1 }
}

contact_called

When: a phone call with this prospect is completed (connected, missed, voicemail, etc.).
{
  "event": { "…": "envelope", "type": "contact_called" },
  "call_sid": "test-call-sid",
  "from_number": "+1234567890",
  "status": "Completed",
  "duration": 60,
  "resolution": "Positive",
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200, "step_number": 1 }
}
  • status"Completed", "Busy", "NoAnswer", "Failed", "Canceled", "InProgress".
  • resolution"Positive", "Negative", "FollowUp", "Voicemail", "WrongNumber", "NotInterested", etc.

linkedin_connection_request_sent

When: Reply sends a LinkedIn connection request on behalf of the user.
{
  "event": { "…": "envelope", "type": "linkedin_connection_request_sent" },
  "sender_linkedin_account_id": 50,
  "initial_message": "Test connection request",
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200 }
}

linkedin_connection_request_accepted

When: a previously-sent LinkedIn connection request is accepted.
{
  "event": { "…": "envelope", "type": "linkedin_connection_request_accepted" },
  "sender_linkedin_account_id": 50,
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200, "step_number": 1 }
}

linkedin_message_sent

When: Reply sends a LinkedIn message (including InMail and voice messages).
{
  "event": { "…": "envelope", "type": "linkedin_message_sent" },
  "sender_linkedin_account_id": 50,
  "initial_message": "Test message",
  "is_inmail": false,
  "is_voice_attached": false,
  "message_id": "test-msg-id",
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200, "step_number": 1 }
}

linkedin_message_replied

When: a prospect replies to a LinkedIn message.
{
  "event": { "…": "envelope", "type": "linkedin_message_replied" },
  "sender_linkedin_account_id": 50,
  "message_id": "01234567-89ab-cdef-0123-456789abcdef",
  "linked_in_message": "Test reply",
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200, "name": "Test Sequence" }
}

linkedin_reply_categorized

When: Reply auto-categorizes a LinkedIn reply.
{
  "event": { "…": "envelope", "type": "linkedin_reply_categorized" },
  "linked_in_thread_id": 1,
  "reply_inbox_category": "Interested",
  "last_reply_date": "2026-04-21T09:30:00.000Z",
  "contact_fields": { "…": "see above" },
  "sequence_fields": { "id": 200 }
}

autopilot_stopped

When: a sequence’s autopilot mode stops firing (e.g. account quota, reputation threshold, manual pause).
{
  "event": { "…": "envelope", "type": "autopilot_stopped" },
  "sequence_name": "Test Sequence",
  "error_message": "the active contacts limit has been reached",
  "sequence_fields": { "id": 200, "name": "Test Sequence" }
}

Verifying in your own account

Once you have a subscription, fire a synthetic delivery to your URL with POST /v3/webhooks/{id}/test — the body matches the shapes above exactly, with deterministic placeholder data.