Prerequisites: A configured integration in the ClickTerm Dashboard, a public HTTPS endpoint in your backend, and a completed signature verification flow.
When webhooks are sent
ClickTerm sends a webhook only after your backend successfully callsPOST /public-client/v1/clickwrap/verify and the clickwrap event is finalized.
Flow overview
Setup
Configure your webhook URL
Open your integration in the ClickTerm Dashboard and set a public HTTPS webhook URL for your backend.

The URL must use HTTPS and resolve to a public IP address. Localhost, private
networks (e.g.
10.x.x.x, 172.16.x.x, 192.168.x.x), and cloud metadata
endpoints are rejected.Store the signing secret
Save the webhook signing secret in your backend secret manager or environment configuration.
Expose a POST endpoint
Your endpoint must accept HTTP
POST requests and preserve the raw request body for signature verification.Verify before processing
Validate the timestamp and
X-Clickterm-Signature header before parsing or acting on the payload.Request format
Webhook callbacks are sent as HTTPPOST requests with Content-Type: application/json.
Headers
| Header | Format | Description |
|---|---|---|
Content-Type | application/json | Always application/json |
X-Clickterm-Signature | sha256={hex_digest} | HMAC SHA-256 signature prefixed with sha256= |
X-Clickterm-Timestamp | 1711800000 | Unix timestamp in seconds used in the signing payload |
Example raw request
Payload
Payload fields
| Field | Type | Description |
|---|---|---|
eventType | String | Event identifier |
data | Object | Event payload. The structure depends on eventType |
Event types
Currently supported webhook event types:| Event Type | Description |
|---|---|
CLICKWRAP_EVENT_VERIFIED | Sent when a clickwrap event has been successfully verified and finalized |
CLICKWRAP_EVENT_VERIFIED payload
| Field | Type | Description |
|---|---|---|
clickwrapEventId | UUID | Unique identifier of the clickwrap event |
clickwrapTemplateId | UUID | Unique identifier of the clickwrap template |
clickwrapTemplateVersion | Integer | Major version of the template associated with the event |
clickwrapTemplateVersionMinor | Integer | Minor version of the template associated with the event |
endUserId | String | Your end-user identifier provided during verification |
templatePlaceholders | String | JSON-encoded placeholder values provided during verification, or null |
technicalMetadata | String | JSON-encoded technical metadata such as IP address and user agent |
actionAt | Timestamp (UTC, ISO-8601) | When the end user accepted or declined |
effectiveAt | Timestamp (UTC, ISO-8601) | When the template version became effective |
clickwrapEventStatus | String | Final verified status, such as ACCEPTED or DECLINED |
Delivery behavior
ClickTerm considers a delivery successful only when your endpoint returns200 OK.
| Setting | Description |
|---|---|
| Success condition | Your endpoint returns 200 OK after verification and processing |
| Failed delivery | Any non-200 response, including 201, 204, and all 4xx/5xx responses |
| Retry count | Up to 3 retries after the initial failed attempt |
| Retry backoff | Exponential, starting at 60 seconds and increasing up to 300 seconds |
| Request timeout | 10 seconds per delivery attempt |
| Redirects | Not followed — your endpoint must respond directly |
Recovering missed webhooks
If all delivery attempts fail, the webhook is not retried further. Your event data is still stored in ClickTerm. To diagnose and recover:- Check the Delivery history in your integration settings to see request payloads, response status codes, and timestamps for recent delivery attempts
- Use
GET /clickwraps/{endUserId}/statusto poll for the current consent state of specific users - Check the Clickwrap Events page in the Dashboard for event history
Verify webhook signatures
To verify a webhook:Build the signing payload
Concatenate the
X-Clickterm-Timestamp header, a literal dot (.), and the raw request body:Compute the HMAC
Calculate the HMAC SHA-256 digest of the signing payload using your webhook signing secret as the key, then hex-encode the result.
Prepend the sha256= prefix
Prepend
sha256= to your computed hex digest to form the expected signature:Best practices
- Use the raw request body for signature verification. Do not reserialize JSON before computing the HMAC.
- Reject stale timestamps to reduce replay risk.
- Store webhook secrets in a secret manager or environment variables, not in source control.
- Make event processing idempotent by keying on
clickwrapEventId. - Return
200 OKquickly, and offload slow downstream work to a queue if needed.
Related
Verifying a signature
Verify the ClickTerm signature before the webhook is generated.
Checking consent status
Query consent state directly for specific end users.

