Webhooks
Kivra sends a webhook to your endpoint when a company activates or deactivates an integration with you, and when such a company receives content. These events drive the whole flow; the Integration guide describes what to do in response to each one. This page covers the deliveries themselves.
Kivra registers your endpoint and shares the signing secret with you as part of setting you up as a partner. Sandbox and production are registered separately.
Events
Section titled “Events”| Event | Sent when | Data |
|---|---|---|
integration.created |
A company activates an integration with you. | company_key, vat_number |
integration.deleted |
A company deactivates the integration. | company_key, vat_number |
content.created |
A company that has an integration with you receives content. | company_key, content_key, vat_number |
Every payload has the same envelope:
| Field | Description |
|---|---|
id |
Event identifier. It is the same across retries, so use it to deduplicate. |
event_created_at |
Unix timestamp in seconds when the event happened. |
event_type |
Which event this is. |
data_version |
Version of the data shape for this event type. |
data |
Event-specific data. |
Kivra may add fields to data without changing data_version, so ignore
fields you do not know. A breaking change increments data_version. The
payloads are also described in the
API reference.
Verify the signature
Section titled “Verify the signature”Each delivery carries a timestamp and one or more signatures:
X-KIVRA-TIMESTAMP: <unix seconds>X-KIVRA-SIGNATURE: v1=<hex HMAC-SHA256>To verify a delivery:
- Read the timestamp
tfromX-KIVRA-TIMESTAMPand reject it if it is outside the window you accept, to prevent replays. - Build the message
t + ":" + body, using the raw request body exactly as received. - Compute HMAC-SHA256 of the message with your shared secret, hex-encoded.
- Compare the result with the hex digest after
v1=in everyX-KIVRA-SIGNATUREheader, using a constant-time comparison. The delivery is authentic if any of them matches.
During a secret rotation Kivra sends one X-KIVRA-SIGNATURE header per
active secret, which is why there can be several.
Acknowledgement and retries
Section titled “Acknowledgement and retries”Respond with 200 OK once you have durably accepted the event. Any other
response causes a retry, so acknowledge first and do the actual work
asynchronously.
Kivra retries failed deliveries with increasing delays for a long time, so a temporary outage on your side does not lose events. Delivery is therefore at least once, and sometimes late, so:
- deduplicate on
id; and - treat
event_created_atas when the event happened andX-KIVRA-TIMESTAMPas when this attempt was sent.