Skip to content

Concepts

Webhook deliveries

Each new response is POSTed to a brand's or form's webhooks as signed JSON, with retries.

Payload

Deliveries are POSTed as JSON { id, event, createdAt, data } with the headers Forms-Event, Forms-Delivery and Forms-Signature.

data is { submission, form: { id, name, version } }. It holds the response with its answers, contact and attribution, and the form and version it was answered on. The delivery log shows data as payload. A form webhook with a posting spec posts the buyer's own format instead, as described below.

Checking the signature

Forms-Signature is t=<unix>,v1=<hex>. The hex is HMAC-SHA256(secret, "<t>.<body>"), keyed with the webhook's signing secret, which starts with whsec_.

Retries

A non-2xx answer or a 10s timeout is retried after 60, 300, 1800, 7200 seconds. After 5 attempts the delivery is failed.

Inactive webhooks get no new deliveries. Every attempt shows in the webhook's delivery log, GET /v1/webhooks/{webhookId}/deliveries. Any delivery can be sent again as a new one with its own retries.

Posting in a buyer's format

A posting spec makes a form webhook post each lead in a buyer's own format. The body holds exactly the spec's keys, in order. With format: "json" it is a flat JSON object of strings, and with "form" it is form-encoded. It carries the spec's extra headers, such as the buyer's API key, plus the usual Forms-Event, Forms-Delivery and Forms-Signature. The signature covers that body.

Each key takes a question's answer, a contact or tracking value, or a constant. Every value is a string. A question that's gone or wasn't answered sends an empty string, and the webhook's postingSpec.warnings names the keys to check. Header values are never returned.

Set one with POST /v1/webhooks/{webhookId}/posting-spec and try it with POST /v1/webhooks/{webhookId}/posting-spec/preview.