Receive completion webhooks
Goal
Get notified the moment a Patient finishes a Form or Packet, instead of polling GET /v2/responses on a schedule.
Prerequisites
- An API key pair, see Authentication.
- An HTTPS endpoint on your server that can accept
POSTrequests.
Steps
1. Create a webhook configuration
curl --request POST \
--url https://api.app.zentake.com/v2/webhooks \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <your_api_key>' \
--header 'X-API-SECRET: <your_api_secret>' \
--data '{
"target_url": "https://your-server.com/webhooks/zentake",
"event_types": ["created", "updated"],
"source": "packet_response",
"is_active": true
}'
sourceis one ofpatient,document,form,packet,response,packet_response, pickresponsefor single-form sends, orpacket_responsefor packet sends.event_typesis any subset ofcreated,updated,deleted.- The response includes a
signature_secret, read-only, shown only at creation. Store it immediately; you'll need it to verify incoming requests (see Signature verification).
Full reference: Create a new webhook configuration.
There's no endpoint to retrieve signature_secret again later. If you
lose it, delete the webhook config and create a new one.
2. (Optional) Send yourself a test event
curl --request POST \
--url https://api.app.zentake.com/v2/webhooks/events/test \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <your_api_key>' \
--header 'X-API-SECRET: <your_api_secret>' \
--data '{
"webhook_config_id": "<webhook_config_id>",
"event_type": "updated",
"source": "packet_response",
"source_id": "<packet_response_id>"
}'
The webhook configuration must be inactive (is_active: false) to use
this, set it back to true once you're done testing. Reference:
Test a webhook configuration.
3. Verify the signature on every incoming request
Every delivery includes an X-Zentake-Signature header. Recompute it from
the raw request body and your signature_secret, and reject anything that
doesn't match, see Signature verification
for exact Node and Python snippets.
4. Interpret the event
The payload shape is documented in
Webhook payloads. For a packet_response
event specifically: treat is_submitted: false with form_index: null as
setup noise (fired when the packet send is created), and
is_submitted: true as the completion signal you're waiting for.
5. Check delivery history
curl --request GET \
--url 'https://api.app.zentake.com/v2/webhooks/events?source=packet_response&status=failed' \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <your_api_key>' \
--header 'X-API-SECRET: <your_api_secret>'
Each event record shows status (pending / sent / failed),
status_code, and response_body from your endpoint, useful for
debugging a webhook your server rejected. Reference:
Retrieve a list of webhook events.
What success looks like
- Your endpoint receives a
POSTwith a validX-Zentake-Signatureyou can verify. - You respond with a
2xxstatus code (see Best practices). - The corresponding entry in
GET /v2/webhooks/eventsshowsstatus: "sent"with a2xxstatus_code.