Skip to content

Send answers to your own endpoint with webhooks

Post every answer a campaign receives to an HTTPS address of yours, signed, or send any payload from a workflow step. How the Webhooks connector differs from Settings → API → Webhooks.

Polzy team7 min readUpdated 31 Oct 2026Business and up
On this page
  1. 1Which webhook do you need?
  2. 2Before you start
  3. 3Connect the Webhooks connector
  4. 4Give a campaign its endpoint
  5. 5What your endpoint receives
  6. 6Check the signature
  7. 7Send a webhook from a workflow
  8. 8Check that it works
  9. 9Troubleshooting
  10. 10Good to know

The Webhooks connector sends every answer a campaign receives to an address on your own server, as a signed POST, a few moments after it is given. A workflow can use it too, to send whatever the run knows. At the end of this guide you will have an endpoint receiving answers, and the means to check that each request really comes from Polzy.

The Webhooks connector is on Business. Only Admins can connect it and choose where a campaign's answers go.

Which webhook do you need?

Polzy can call your server in three ways:

Webhooks connector (this article)Settings → API → WebhooksOutbound webhook step
What is sentEach answer to one campaign, or a workflow step's payloadWorkspace events: a response created, a campaign finished, an action created or completedWhatever the workflow step says
Where it is setIntegrations, then a campaign's Integrations tab or a workflow stepSettings → API → WebhooksA workflow
PlanBusinessTeamTeam
SignedX-Polzy-Signature, over the bodyX-Polzy-Signature, over the timestamp and the bodyNo
When delivery failsTried three times in allTried six times over about half an hour, with a log of every attemptThe step's error rule decides

For events across the whole workspace, see Send and receive webhooks.

Before you start

You need:

  • A workspace on Business, and the Admin role in it.
  • Integrations switched on for the workspace, under Settings → General → What this workspace does.
  • An endpoint on the internet, over HTTPS, that accepts a POST with a JSON body and answers with a 2xx status within 10 seconds. Polzy refuses http:// addresses and addresses inside a private network.

Connect the Webhooks connector

Connecting holds what every request shares: the signing secret, and any headers.

  1. In the sidebar, under Automate, open Integrations and choose the Available tab.
  2. Find Webhooks and choose Connect.
  3. In Signing Secret, enter a long random value and keep a copy for your server.
  4. Under HTTP Headers, add any headers you want sent, such as Authorization. Their values are stored encrypted. See Good to know for where they go.
  5. Choose Connect. The test answers Connected. Each survey and step names the endpoint it posts to.
Connecting the Webhooks connector: the signing secret and any headers.

Left empty, the signing secret is made for you — but it is never shown, so you could not check signatures with it. Enter your own. To change it later, choose Configure and type the new one over the stored value.

Give a campaign its endpoint

  1. Open Campaigns, then the campaign, and its Integrations tab.
  2. Under Add a connection, find Webhooks and choose Connect. If the button reads Set up, the connector is not connected to the workspace yet.
  3. In Endpoint, enter the address this campaign's answers are posted to.
  4. Choose Save changes.
A campaign's destination: the endpoint its answers are posted to.

Webhooks then appears under Connected to this campaign, with Sends to and the address, its switch, Edit configuration, Disconnect, and how many answers were sent and failed. Each campaign can post to its own endpoint.

A campaign's Integrations tab: what each answer is sent to, and what could be added.

What your endpoint receives

Each answer is one POST with these headers:

HeaderWhat it holds
Content-Typeapplication/json
X-Polzy-Eventresponse.submitted for a campaign's answer; the step's Event name from a workflow.
X-Polzy-SignatureThe HMAC-SHA256 of the raw request body, made with the signing secret, in hexadecimal.
X-Polzy-TimestampThe timestamp from the body.
Idempotency-KeyFrom a workflow step only: the same on a repeat of the same step, so you can ignore it.

And this JSON body:

FieldWhat it holds
eventresponse.submitted.
timestampWhen the request was sent. For an anonymous answer, the day it was given.
survey.id, survey.titleThe survey's ID and title.
response.idThe answer's ID in Polzy. Empty for an anonymous answer.
response.submittedAtWhen the answer was finished. For an anonymous answer, the day alone.
response.answersOne item per question answered, each with questionId, questionText and value.
response.scoreThe overall score, if it was worked out by the time the request was sent.

An anonymous answer carries what it said, its score and its day, and nothing that could name or time its author. Polzy waits for each answer's safety reading, up to 10 minutes, before it sends it; an answer withheld for safety review arrives as its placeholder. The privacy floor does not hold single answers back.

Check the signature

  1. Read the request body exactly as it arrived, before parsing it.
  2. Compute its HMAC-SHA256 with your signing secret, written as hexadecimal.
  3. Compare it with X-Polzy-Signature, with a constant-time comparison. If they differ, refuse the request.

The timestamp is part of the body, so a changed timestamp breaks the signature too.

Send a webhook from a workflow

  1. Open Workflows and the workflow, or start a new one.
  2. Under Connectors in Installed steps, drag Send a webhook · Webhooks onto the canvas.
  3. In Endpoint, enter where this step posts.
  4. Under Event name, keep workflow.step or name the event your server expects. It is sent as X-Polzy-Event.
  5. Leave Payload empty to send everything the run knows, or write the JSON you want, with {{ to insert values from the run.
  6. Choose Send a test to post one request filled from a sample response.
The Send a webhook step: the endpoint, the event's name and the payload.

The step is signed with the connection's secret, and leaves your server's answer as {{connector.statusCode}} and {{connector.response}}.

Check that it works

On the campaign's Integrations tab, the activity line counts the answers sent and those that failed. The connector's own page lists each delivery under Activity, with Worked or Failed and the reason.

The connector's page: its status, the last seven days, and every delivery.

Troubleshooting

Under Activity, a failed delivery reads Webhook failed: and the reason; a workflow's run shows the same reason without it.

  • Webhook failed: only https endpoints are allowed. The endpoint must start with https://.
  • Webhook failed: private addresses are not allowed. The address points inside a private network, such as localhost or 10.0.0.5. Use an address reachable from the internet.
  • Webhook failed: that host could not be found. The name in the address does not exist. Check its spelling.
  • Webhook failed: and a status, such as 500, or timeout of 10000ms exceeded. Your endpoint answered with an error, or took longer than 10 seconds. Anything but a 2xx answer counts as failed, and the delivery is tried three times in all.
  • No endpoint for this survey. Set one on its Integrations tab. The campaign has no endpoint. Add one with Edit configuration on the campaign's Integrations tab.
  • The signature does not match. Compute it over the raw body, before any parsing, with the secret you entered. If the secret was made for you, enter one of your own.
  • Your header does not arrive. See below: headers go only to a host the connection itself posts to.

Answers given before the endpoint was saved, or while the switch was off, are not sent later. Export them from the survey's Responses instead.

Good to know

  • Where do the HTTP headers go? Only to a host the connection itself posts to. An endpoint a campaign or a step chooses on another host is called without them, so a stored Authorization value never reaches an address it was not meant for. Rely on the signature to tell Polzy's requests from anyone else's.
  • Are unfinished answers sent? No. Only finished answers are, once each.
  • Can my endpoint answer with data? For a workflow step, yes: the answer is kept as {{connector.response}} for later steps. For a campaign's answers, the answer is ignored beyond its status.
Was this helpful?
Still stuck?

Signed-in members can ask Polzy or message the team from Support. How fast we reply depends on your plan.