Skip to main content

Zapier and webhooks

Every organization gets one URL that accepts feedback over HTTP. Zapier is how most people will reach it, but nothing about it is Zapier-specific — Make, a cron job, or a one-line curl work identically.

:::info Beta The URL works today, with Zapier's built-in Webhooks by Zapier step or with anything else that can POST JSON.

A dedicated Actify app in Zapier — where you pick Actify from a list instead of pasting a URL — is on the way. Zapier only lists an app publicly once it has a number of active users, so it will be invite-only first. That is what "Beta" means here: the capability is real, the discovery path is not built yet. :::

One URL, not one per tool

The tool names itself in the payload, using source_provider. That means you connect once rather than once per Zap, and there is nothing to configure before the first event — the list of tools that have sent feedback is derived from what actually arrives.

The token in the URL is the credential. It is 192 random bits, and the organization is read from it and never from the request body. Treat it like a password: anyone holding it can file feedback into your organization.

You can regenerate it from the settings screen. Doing so immediately breaks every Zap using the old URL.

Sending feedback

In Zapier: add a Webhooks by Zapier action, choose POST, paste your URL, set the payload type to JSON, and map your tool's fields onto these.

FieldRequiredWhat it is
contentYesWhat the customer said.
source_providerWhich tool it came from — typeform, g2. Groups the feedback.
titleA subject line, if the source has one.
contact_nameWho said it.
contact_emailTheir address, so it can be tied to an account later.
external_idThe record's id in its own system — see deduplication below.
source_created_atWhen it was written, if not now.
urlA link back to the thing in its own system.

content is the only requirement. This endpoint gets pasted into tools nobody has seen, and a schema that rejects a message for missing a field the sender never had is a support ticket, not a safeguard.

Extra fields are kept, not rejected. Anything beyond the list above is stored with the original payload, so a generous caller is never punished for it and the original shape survives for anyone debugging later.

From anything that speaks HTTP

Copy your exact URL from Settings → Integrations → Zapier — the screen has a ready-made version of this command with your token already in it.

curl -X POST <YOUR_ENDPOINT_URL> \
-H "Content-Type: application/json" \
-d '{
"content": "The export takes so long I gave up and did it by hand.",
"source_provider": "typeform",
"contact_email": "[email protected]",
"external_id": "response_8813"
}'

Deduplication

Send an external_id and a repeated delivery of the same record is ignored rather than duplicated. Omit it and every call creates a new row.

This matters more than it looks. Without it, a retrying Zap produces the same feedback twice, and by the time anyone notices it has been embedded (a paid model call), classified (another), and counted twice on the dashboard.

What you get back

A successful post answers 202 Accepted, not 201. The feedback exists, but the embedding and classification it triggers have not run — so nothing is finished yet in the sense the caller cares about.

{ "ok": true, "deduplicated": false, "source": "typeform" }

deduplicated: true means that external_id had already arrived. It is reported rather than hidden, because a Zap re-sending the same id is usually a Zap somebody has misconfigured, and this response is the only place they would find out.

Errors say what was wrong in words you can act on. Zapier shows the response in the Zap's run history, and that is the only debugging surface the person wiring it up has — so nothing is accepted and then quietly dropped.

Connecting

Settings → Integrations → Zapier. The URL exists as soon as you open the screen. Viewing and regenerating it is restricted to an organization's owner or admin.

Disconnecting

Regenerate the token to invalidate the old URL, or disconnect the endpoint to stop accepting posts entirely. Feedback already collected stays.

Data stored

  • The endpoint token, and a running count per source_provider
  • For each accepted post: every field above, plus the complete original payload

Questions about this integration: [email protected]