Skip to main content
This page shows the exact request AskFunnel sends to your webhook, how to check that a request really came from AskFunnel, and how retries work. It is for the person who builds the receiving side of a webhook. If that is not you, share this page with your developer. In short: AskFunnel sends one signed request for each new lead. Answer with a 2xx status (a success code such as 200) and AskFunnel counts the lead as delivered. Before you start, you need:
  • A webhook added to a funnel. See Send your leads to a webhook.
  • The webhook’s signing secret, if your server checks signatures. You find it in “Edit webhook”, under Advanced.

The request

AskFunnel sends a POST request with a JSON body. Along with any headers you added, it always includes these:
  • webhook-id and idempotency-key are the lead’s event ID, the same value as id in the body. They stay the same on every retry, so use them to ignore repeats.
  • webhook-timestamp is the time of this attempt, in seconds since 1970 (Unix time). Each retry has a new timestamp and a new signature.
  • webhook-signature is the signature of this attempt. See Verify the signature.
  • user-agent is always AskFunnel-Webhooks/1.0 (+https://askfunnel.com) unless you add your own header with that name.

The JSON body

Here is a sample lead from a funnel called Buyer inquiry. JSON is a standard text format that software reads easily. The body is sent as compact JSON, shown here with line breaks to read it.
In a test, test is true, lead.id is null, score is 0, consent.marketing is false, and attribution.utm and attribution.referrer are null. The answers are sample text built from your funnel’s questions.
You can also copy a sample from AskFunnel. Before you add your first webhook, click the info icon next to What we send, then “Copy sample”.

Verify the signature

Each webhook has its own signing secret. AskFunnel signs every request with it, following the Standard Webhooks v1 format, so libraries that support that format can verify AskFunnel requests too. To check a request yourself:
  1. Read the body exactly as it arrived. Do not parse it and write it out again, because the signature covers the exact bytes.
  2. Build the signed text: the webhook-id header, a dot, the webhook-timestamp header, a dot, then the body.
  3. Take your signing secret, remove the whsec_ at the start and decode the rest from base64. That is the key.
  4. Compute an HMAC with SHA-256 over the signed text using that key, and encode the result as base64.
  5. The webhook-signature header is v1, followed by that value. Compare the two in constant time.
  6. Reject requests with an old timestamp. We suggest 5 minutes.
With Express, keep the raw body for the route that receives AskFunnel:
  • Send your answer within 15 seconds. A 2xx status means the lead was received. A 401 from your own check is treated as a failure and is not retried, so only use it for requests that are really not from AskFunnel.
  • If you rotate the signing secret, requests signed with the old one fail your check until you update it.
  • A test sent before the webhook is saved is signed with a temporary secret. To test your check, save the webhook first, copy its signing secret, then click “Send test”.

Retries and what counts as success

AskFunnel only looks at the status code of your answer. The body of your answer is ignored. A lead that can be retried is sent again after 1 minute, then 5 minutes, 30 minutes, 2 hours, 6 hours and 12 hours, each counted from the previous attempt. That is up to 7 attempts in about 21 hours. Each retry sends the same webhook-id and the same body, with a new timestamp and signature.
  • 429 Too Many Requests is treated as “slow down”, not as an outage. If your answer has a Retry-After header, in seconds or as an HTTP date, AskFunnel waits at least that long, up to 24 hours. It never retries sooner than the schedule above. It does not schedule a retry later than 72 hours after the first attempt.
  • After the last attempt fails, the lead shows Failed with the last error, the webhook shows Needs attention, and the organization owner gets an email.
  • Clicking “Retry” in the delivery log starts a new set of up to 7 attempts.
  • Failed leads stay in the delivery log for 30 days.

Troubleshooting

Check these, in order:
  • You are using the raw body, not a parsed and re-written one.
  • You are using the signing secret of this webhook. Each webhook has its own.
  • You remove whsec_ and decode the rest from base64 before using it as the key.
  • You did not rotate the secret without updating your server.
  • The clock on your server is close to the real time, if you check the timestamp.
  • You are not testing with an unsaved webhook. A test sent before you save is signed with a temporary secret.
Need help? Email support@askfunnel.com.