Webhooks
Webhooks send a signed JSON POST to your own endpoint whenever a contact is created, updated, merged, or erased. You register an endpoint at /settings/webhooks, verify each delivery with the subscription's HMAC-SHA256 secret, and watch attempts in a per-endpoint delivery log.
Webhooks push contact changes from Reach to your own systems in real time. You register one or more endpoints at /settings/webhooks, choose which events each endpoint subscribes to, and Reach sends a signed JSON POST to your URL every time a matching event happens. Each subscription is scoped to your account, and every delivery is tracked in a log you can inspect and re-trigger.
Registering an endpoint
On the Webhooks settings page, click Add webhook. The dialog asks for the following:
- Target URL — the endpoint that receives the POST. Required, and must match the pattern
^https?://.+(an HTTP or HTTPS URL). A blank field returns "Target URL is required." - Event types — a checkbox for each event the endpoint can subscribe to. All four are checked by default; uncheck any you don't want. At least one must stay selected, or the dialog returns "Pick at least one event type."
- Description — optional label that helps you tell endpoints apart in the list (for example,
Sync contacts to internal CRM).
Click Create webhook. The dialog then shows the signing secret in an amber box titled "Signing secret — copy it now." Use the Copy button, store the secret somewhere safe, then click I've saved it to close.
The signing secret is shown only once, at creation. Reach never stores it in a way it can display again. If you lose it, rotate the secret from the webhook detail page, which issues a new one and invalidates the old.
What you can subscribe to
Webhooks fire on contact lifecycle events. An endpoint can subscribe to any combination of:
contact.created— a contact is added to your workspace.contact.updated— an existing contact's fields change.contact.merged— two contacts are merged into one.contact.erased— a contact is erased.
These are the only event types Reach accepts; an endpoint with no valid event selected cannot be saved. You change an endpoint's subscriptions later from its detail page, covered below.
Verifying a delivery
Each delivery is a POST with Content-Type: application/json and a JSON body, signed with HMAC-SHA256 using your subscription's secret. The request carries these headers:
X-Mercleo-Signature— the signature, formatted assha256=<hex digest>.X-Mercleo-Event-Type— the event type for this delivery (for example,contact.updated).X-Mercleo-Delivery-IdandX-Mercleo-Webhook-Id— the delivery and subscription identifiers, useful for idempotency and correlating to the log.
To verify, compute HMAC-SHA256 over the raw request body bytes using your secret, hex-encode the result, and compare it to the value after sha256= in X-Mercleo-Signature. Reach serializes the body canonically — object keys sorted at every depth and no whitespace — so sign the bytes you receive rather than re-serializing the parsed JSON.
Reading the delivery log
Click an endpoint to open its detail page at /settings/webhooks/[id]. The Recent deliveries card lists the most recent 50 attempts, newest first, with columns for Event, Status, Attempts, and Last attempt.
A delivery's status is one of Pending (enqueued, not yet attempted), Succeeded, Retrying (failed but a further attempt is scheduled), or Failed (no more attempts). When available, the row shows the HTTP status code (for example, HTTP 500), the error message, and the scheduled Next: retry time.
The endpoint header also shows Last succeeded and Last failed timestamps, which update as deliveries complete.
Retries and failure handling
A failed delivery is retried with exponential backoff up to 5 total attempts. After each failure, the next attempt is scheduled at a growing delay: 1 minute, then 5 minutes, then 30 minutes, then 2 hours, then 12 hours. Once the fifth attempt fails, the delivery is marked Failed and is not retried again automatically.
A background sweep runs every 5 minutes to pick up pending deliveries and retries whose backoff window has arrived. Because the first retry delay is 1 minute but the sweep runs on a 5-minute cycle, a freshly failed delivery can wait up to about 5 minutes before its first retry.
The endpoint's status reflects its recent failure streak. As long as it stays active, an endpoint with one or more consecutive failures shows Degraded with the consecutive-failure count in parentheses (for example, Degraded (3)). A single success resets the count back to zero and the endpoint returns to Active.
To re-attempt a delivery yourself, use the redeliver button at the end of its row in the log. This re-queues the delivery as Pending, resets its attempt count, and clears the recorded status code and error. The next 5-minute sweep then attempts it, so it stays Pending until that sweep runs.
Editing, disabling, and deleting
From the detail page, Edit opens a dialog where you change the target URL, the event subscriptions, and the description. The signing secret is not part of this dialog — rotating it is a separate action.
Click Rotate secret to issue a fresh signing secret. A confirmation warns "Rotate the signing secret? The current secret will stop working immediately and the new one is shown once." The new secret then appears once for you to copy. Update your endpoint's verification before deliveries signed with the old secret arrive.
Click Disable to stop deliveries while keeping the subscription and its log. The status changes to Disabled, and Enable turns it back on. Disabling is the reversible choice when you want to pause an endpoint without losing its history.
| Effect | Disable | Delete |
|---|---|---|
| Stops future deliveries | ✓ | ✓ |
| Keeps the subscription | ✓ | — |
| Keeps the delivery log | ✓ | — |
| Reversible | ✓ | — |
Updated