Skip to the page

REST API

Webhooks

Events we send you and how to verify their signature.

Webhooks send a signed JSON event to your server when something happens: a click, an install, a link change, a domain verification. Create an endpoint in the dashboard (Webhooks) or with POST /v1/webhooks, choose the events, and keep the signing secret it shows once.

Events#

EventWhen
install.attributed, install.organicA first open was matched to a click, or was not
open.reengagedAn existing install opened your app through a link
event.trackedAn event from the SDK or your server was stored
link.created, link.updated, link.disabled, link.blockedA link changed
campaign.created, campaign.endedA campaign started or ended
domain.verified, domain.failedA domain check finished
click.createdEvery click. High volume: never preselected, choose it deliberately

The request#

POST to your https URL, with Content-Type: application/json:

JSON
HeaderMeaning
X-BeckLink-Signaturet=<unix seconds>,v1=<hex> (see below)
X-BeckLink-EventThe event type
X-BeckLink-DeliveryThe id of this delivery attempt
User-AgentBeckLink-Webhooks/1

The event id is stable: deduplicate on it, because an event can be delivered more than once (retries, replays).

Verify the signature#

Take the raw body exactly as received (before any JSON parsing), the timestamp t and every v1 value from the header. The signed text is t, a dot, and the body. Compute HMAC-SHA256(secret, "<t>.<body>") as lower-case hex, with the signing secret (whsec_…, used as is) as the key, and compare it to the v1 values with a constant-time comparison. We recommend rejecting a timestamp more than five minutes away from your clock, so an old request cannot be replayed (the examples do).

During a secret rotation (24 hours) the header holds one v1 per secret; accept the request if any matches.

verify.js

Answering and retrying#

Answer with any 2xx within 10 seconds; do the work after you have answered. Redirects are not followed. Anything else is a failure and is retried: up to 8 attempts, waiting about 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, 12 hours and 24 hours between them (with a little jitter).

  • An endpoint that fails with no success for 3 days is turned off (auto_disabled); enable it again once it works.
  • The delivery log keeps the first 2 KB of each request and response. Replay a delivery from the dashboard or with POST /v1/webhooks/{webhook}/deliveries/{delivery}/replay (a replay is one attempt without automatic retries).
  • Your URL must use a public host name over https: IP addresses, local and internal names are refused.

Verify it works#

Use Send test event in the dashboard (POST /v1/webhooks/{webhook}/test) and check that your endpoint verifies the signature and answers 200. Then break it on purpose (change one byte of the body) and check that it is rejected. See the Webhooks reference.