Prepare your receiving address
Use a public HTTPS endpoint that you control. It receives Worth Asking events, verifies their signatures and saves a receipt before replying.
Already have a receiver? Make sure it accepts POST, verifies the original request bytes and deduplicates event IDs in persistent storage. Use the final URL, including its path; redirects are not followed.
https://your-receiver.example/hookNo receiver yet? Deploy the starter
The downloadable Cloudflare Worker includes the receiver, verifier, database schema and a README. You need Node.js 22 or later, npm and a Cloudflare account with Workers and D1 available. Your account’s usage and charges apply.
Download receiver starter (.zip)
In the folder containing the downloaded file, run these commands. Sign in to the Cloudflare account where you want to host the receiver.
unzip worthasking-webhook-receiver.zip
cd worthasking-webhook-receiver
npm install
npx wrangler login
npx wrangler d1 create worthasking-webhook-receiverCopy the database_id returned by the last command into database_id in wrangler.jsonc. Keep the RECEIVER_DB binding. Then create the receipt table and deploy:
npx wrangler d1 execute worthasking-webhook-receiver --remote --file schema.sql
npm run deployAppend /hook to the HTTPS Worker URL printed by deployment. The receiver will refuse unsigned requests and will not pass the connection test until you configure the signing credentials in step 2.
This starter verifies and records receipts only. To send a chat message or run an automation, add the forwarding described below.
Ready when: you have your receiver’s final public HTTPS URL.
Save the destination and signing key
Open Webhook settings, enter the address and choose which events and questions to include. Each account has one destination, on every plan.
- Choose Meaningful changes, First complete view ready, or both. Include followed public questions, or explicitly select eligible private questions.
- Start with metadata and sign-in links only. Titles and short summaries are optional. Private event metadata and private content each require explicit consent.
- Click Save draft. Securely copy the signing secret shown once and the key ID shown beside Signing key. Keep this page open until both are stored at your receiver.
For the starter, run these commands inside its project folder. Paste the signing secret into the first prompt and the key ID into the second. The commands store them as Cloudflare secrets; never put them in your source files or logs.
npx wrangler secret put WEBHOOK_SIGNING_SECRET
npx wrangler secret put WEBHOOK_KEY_IDSaving leaves notifications off. If you lose the secret, rotate it in Signing and destination controls, save any private permissions again and configure the new secret and key ID.
Ready when: the same signing secret and key ID are stored at your receiver.
Test the connection
Click Test saved address and confirm. Worth Asking sends one synthetic webhook.test event with no real research content.
The starter returns HTTP 204 only after it verifies the event and saves its receipt. Confirm the passed test in Worth Asking, then check the saved receipt in your receiver’s project:
npx wrangler d1 execute worthasking-webhook-receiver --remote --command "SELECT event_id, event_type, received_at FROM webhook_receipts ORDER BY received_at DESC LIMIT 10"Look for event_type webhook.test and a recent received_at. A test should record a receipt without sending a business message or changing your research. Any 2xx response counts as accepted by Worth Asking; it does not prove that an automation finished.
Tests and deliveries share a limit of one attempt per minute per destination. If asked to wait, retry after the indicated time.
Ready when: the current configuration passes and your receiver contains a webhook.test receipt.
Enable future notifications
Click Enable notifications and confirm the saved scope. Testing alone never turns notifications on.
Keep at least one eligible question in your selected scope. After a new first view or meaningful change is published, open Delivery history → Details → Event and match that event ID with the receiver’s receipt. No matching event means there may simply be nothing new to send.
Saving changes to the address, events, scope or content pauses delivery and cancels old pending attempts. Unsaved drafts do not change current delivery. Test and enable the saved new version. Pausing stops future attempts; resuming starts with future events and does not replay the paused backlog.
Ready when: settings show Enabled. New eligible events can now reach your receiver.
Build on the connection
For your own receiver, a channel integration, or a connection that needs a closer look.
Event fields and signature verification
Research events use schema_version 1 and type first_view_ready or meaningful_change. The default links-only shape looks like this illustrative event. Test events instead use type webhook.test and contain no question.
{
"schema_version": "1",
"id": "event_example",
"type": "meaningful_change",
"occurred_at": "2026-09-08T08:00:00.000Z",
"question": {
"id": "question_example",
"visibility": "public",
"url": "https://worthasking.ai/account/notifications/event_example"
},
"change": {
"id": "change_example"
}
}meaningful_change includes change.id; first_view_ready includes view.id. Optional question.title and summary are each limited to 500 characters. Requests are at most 32 KiB; validate the full versioned schema rather than assuming every event has the same fields.
Keep all five headers. The timestamp is Unix seconds; the signature is lowercase hexadecimal HMAC-SHA256.
X-WorthAsking-Signature-Version: 1
X-WorthAsking-Key-Id: <your key ID>
X-WorthAsking-Timestamp: <Unix seconds>
X-WorthAsking-Event-Id: <root JSON id>
X-WorthAsking-Signature: <lowercase hex HMAC-SHA256>Use verifier.ts from the starter: decode the signing secret from base64url, then verify timestamp + "." + the exact raw body bytes. Do not parse and reserialize first. Reject timestamps outside five minutes, unknown keys or versions, invalid schemas and mismatched header/body IDs. Synchronize your receiver clock.
Retries keep the same id and body while refreshing the signature timestamp. Persist a unique event ID together with any queued work before replying. Signature validation alone does not prevent repeated business actions.
Forward to n8n, Slack or another channel
Use this path: Worth Asking → verified receiver → durable job → your automation or channel. Ordinary Slack, Teams, Discord, Feishu or WeCom bot URLs expect their own message format and are not directly compatible with this event JSON.
- In the receiver, atomically save the unique event ID and forwarding job. Return 2xx after this succeeds; perform the network forwarding separately.
- For n8n, publish a POST Webhook workflow and use its Production URL. Protect this second hop with a separate credential. Route webhook.test to a connection check only.
- Map id to your deduplication key and question.url to the details link. question.title and summary may be absent. Keep retries bounded and record the downstream result separately.
The starter does not include a forwarding worker, a channel account or a ready-made n8n workflow. Your integration owns those credentials, message templates and downstream retries.
Content, permissions and link access
The default payload contains event information, opaque IDs and an authenticated link. If you enable summaries, the receiver can retain and forward question titles and short summaries. Choose a destination audience that should see them and avoid recording private payloads in automation logs.
Private questions are selected individually; future private questions are not added automatically. Current access is rechecked before sending. Webhooks do not grant access, accept a view, spend a question place, publish research or change billing.
Notification links require sign-in and current question access. They depend on delivery history retained for 30 days from preparation and may expire sooner after account deletion or access loss. Removing the destination does not immediately revoke every link already sent.
When a test or delivery needs attention
- 401 / 403: check the current key ID, secret, raw bytes and receiver clock. Repair the receiver, test the saved version again and explicitly enable.
- Redirect or address rejected: enter the final public HTTPS URL. It must not redirect to a sign-in page, a private network or Worth Asking itself.
- 429 / 5xx / network failure: check receiver availability and Delivery history. Research events allow at most five attempts, including manual retries, within 24 hours of publication. Rate limits can delay attempts.
- Timeout or unknown result: an attempt waits up to 10 seconds and may already have reached the receiver. Check its receipt by event ID before investigating downstream work. Duplicates and out-of-order delivery are possible.
- Cannot enable: save any edits, test the current version and restore required private consents. Sensitive changes may ask you to sign in again; the settings page keeps your draft.
For support, share the event ID, status and approximate time. Never include your signing secret or private research content.
Your receiver is ready. Make the connection.
Save, test and enable in Webhook settings. You can pause delivery whenever you need.