Skip to main content

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 POST requests.

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
}'
  • source is one of patient, document, form, packet, response, packet_response, pick response for single-form sends, or packet_response for packet sends.
  • event_types is any subset of created, 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.

Save signature_secret now

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 POST with a valid X-Zentake-Signature you can verify.
  • You respond with a 2xx status code (see Best practices).
  • The corresponding entry in GET /v2/webhooks/events shows status: "sent" with a 2xx status_code.

Next