Webhooks & Events API

Outbound event subscriptions — Reply pushes every reply, open, click, bounce, and LinkedIn event to your endpoint instead of making you poll.

Base URL
https://api.reply.io/v3
Official reference
docs.reply.io/api-reference/webhooks/list-webhook-subscriptions
OpenAPI
webhooks-events.openapi.yaml
Markdown twin
webhooks-events.md
Scopes
webhooks:readwebhooks:writewebhooks:operate

What it does

The Webhooks & Events API is the push side of the platform: it manages subscriptions that make Reply POST a JSON payload to your URL every time an event fires. The management surface is ten operations — list, create, get, update (PUT), and delete subscriptions; enable and disable them without losing configuration; list the supported event types; send a test payload to a subscription’s URL; and read its delivery failure log. A subscription binds one eventType to one receiver URL, with a scope of personal (owner’s activity) or team (any team member), plus optional payload enrichment flags (email URL, email text, contact custom fields).

The event catalog covers the whole outreach loop: email engagement (email_sent, email_opened, email_link_clicked, email_replied, reply_categorized, email_bounced, email_auto_reply), email account health (email_account_connection_lost, email_account_error), LinkedIn (linkedin_connection_request_sent, linkedin_connection_request_accepted, linkedin_message_sent, linkedin_message_replied, linkedin_reply_categorized, linkedin_account_alerts), calls (contact_called), contact lifecycle (contact_finished, contact_opted_out), and sequence automation (autopilot_stopped).

Direction matters: the endpoints above are ordinary REST calls you make to Reply, but the deliveries are OUTBOUND — Reply POSTs to your endpoint. You need a publicly reachable https URL to receive them.

The problem it solves

A polling agent is always late and always wasteful. Checking the inbox every minute burns rate limit on empty responses and still reacts minutes after a prospect replies — which is exactly when interest is highest. Webhooks invert the flow: subscribe once, then react. A reply arrives, email_replied fires, the agent classifies the intent, drafts a response, and books the meeting — an event-driven pipeline instead of a polling loop. The same nervous system carries operational signals an agent should act on immediately: a bounce or opt-out prunes the contact list, email_account_connection_lost pauses sending before deliverability suffers, linkedin_account_alerts flags a channel that needs human attention, and autopilot_stopped tells the agent its evergreen sequence went quiet. If you cannot host an endpoint — a static agent with no server — the honest fallback is polling the Conversations & Inbox API; webhooks are strictly better only once you have somewhere for Reply to POST.

How an agent starts using it

Call GET /v3/webhooks/events to get the exact event type names, then POST /v3/webhooks with an eventType and your receiver url (scope webhooks:write). Verify the wiring with POST /v3/webhooks/{id}/test before relying on it, then handle the POSTs Reply sends to your endpoint. Use POST /v3/webhooks/{id}/enable and /disable (scope webhooks:operate) to pause during maintenance, and GET /v3/webhooks/{id}/logs (scope webhooks:read) when events stop arriving — it lists failed delivery attempts with event id, HTTP status, and timestamp. One subscription carries one event type, so an agent that needs replies, bounces, and opt-outs creates three subscriptions pointing at the same receiver.

Typical agent tasks

  • Subscribe to email_replied so every prospect reply triggers classify-and-respond within seconds
  • Send a test payload to verify the receiver endpoint parses events before going live
  • Subscribe to email_bounced and contact_opted_out to keep the contact list clean automatically
  • Disable a subscription during receiver maintenance and re-enable it without losing configuration
  • Read the delivery failure log to diagnose why events stopped arriving

Inputs

NameTypeRequiredDescription
eventType string yes Event to fire on — one name from GET /v3/webhooks/events (e.g. email_replied).
url string yes Absolute, publicly reachable https receiver URL (max 1,024 chars) that Reply will POST event payloads to.
scope string no personal (default) fires only on the owner's activity; team fires for any team member. organization is reserved and currently rejected.
enabled boolean no Create in a firing state (default true). After creation, toggle only via the enable/disable endpoints — PUT cannot change it.
payloadConfig WebhookPayloadConfig no Enrichment flags — includeEmailUrl, includeEmailText, includeProspectCustomFields.

Outputs

NameTypeDescription
id integer Subscription identifier used by every other webhook endpoint.
enabled boolean Whether the subscription currently fires.
events string[] Supported event type names from GET /v3/webhooks/events — the valid eventType values.
logs WebhookDeliveryLog[] Per-subscription failure log — triggering event id, HTTP status (null if the request never completed), and UTC attempt timestamp. Successful deliveries are not logged.

Authentication

API key as Bearer token. Send Authorization: Bearer <API_KEY> on every request. Get an API key in the Reply.io app under Settings → API Keyauthentication reference.

Rate limits

100 requests/minute and 3,000 requests/hour per user (shared across all of the user's API clients). On 429, honor the Retry-After header.

Example

Request — POST /v3/webhooks
curl -X POST https://api.reply.io/v3/webhooks \
  -H "Authorization: Bearer $REPLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "eventType": "email_replied", "url": "https://agent.example.com/hooks/reply", "scope": "personal" }'
Response — 201
{
  "id": 1823,
  "eventType": "email_replied",
  "url": "https://agent.example.com/hooks/reply",
  "scope": "personal",
  "enabled": true,
  "createdAt": "2026-07-04T09:15:00Z"
}
Error — 403
{
  "type": "https://docs.reply.io/api-reference/authentication",
  "title": "Forbidden",
  "status": 403,
  "detail": "This API key does not have the required scope: webhooks:write."
}

Related APIs

Modules are designed to chain — combining them is the point.

Frequently asked questions

Should an agent use webhooks or poll the Inbox API?

Webhooks are outbound: Reply POSTs each event to a public https URL you host, so you react in seconds without spending rate limit on polling. An agent with no server gets the same signals by polling the Conversations & Inbox API — webhooks just remove the latency and the wasted requests.

How do I test a subscription before real traffic hits it?

POST /v3/webhooks/{id}/test (scope webhooks:operate) sends a test payload to the subscription's URL, so you can verify parsing and response handling before enabling it in production.

How do I debug missing events?

GET /v3/webhooks/{id}/logs returns the subscription's delivery failure log — each entry has the triggering event id, the HTTP status (null when the request never completed), and the UTC attempt timestamp. It records failures only; successful deliveries are not listed. Also check that the subscription is enabled.