1
Add a Webhook node
Set HTTP Method to
POST and Respond to Immediately. Rallly waits at most 10 seconds for a 2xx, and responding first means a slow step later in the workflow never turns into a retry.Under Options, switch on Raw Body. This is the step people miss. The signature covers the request body byte for byte; without this option the node parses the JSON and hands you an object, and re-serialising that object produces different bytes and a digest that never matches. With Raw Body on, the exact bytes are kept as binary data on the item, in the property named data.Copy the node’s Production URL.2
Register the endpoint in Rallly
In Rallly, open Settings → Webhooks, choose Add webhook, paste the URL and pick the events you want. Copy the signing secret: it is shown once.In n8n, store the secret where the workflow can read it without it appearing in the workflow JSON. A workflow variable or an environment variable both work; the code below reads
$vars.RALLLY_WEBHOOK_SECRET.3
Verify the signature in a Code node
Add a Code node after the Webhook node, mode Run Once for All Items, and paste:A request that fails any check stops the workflow with an error, and the node outputs the verified event body as the item. Everything after this node can trust
$json.type and $json.data.On self-hosted n8n, require("crypto") needs the built-in module allowed: set NODE_FUNCTION_ALLOW_BUILTIN=crypto in n8n’s environment. n8n Cloud allows it already.4
Branch on the event type
Add a Switch node on
{{ $json.type }} with one output per event you subscribed to, for example poll.closed, poll.scheduled and poll.participant.created. Add a fallback output and leave it unconnected: Rallly may add event types without a version change, and an unknown type should be ignored, not treated as an error.5
Fetch the poll
The event carries the poll’s id and nothing else about it, so add an HTTP Request node:
- Method
GET - URL
https://api.rallly.co/v1/polls/{{ $json.data.poll.id }} - Authentication
Generic Credential Type→Bearer Auth, with a credential holding your Rallly API key from Settings → API keys
poll.participant.* event, fetch the participant the same way: https://api.rallly.co/v1/polls/{{ $json.data.poll.id }}/participants/{{ $json.data.participant.id }} returns their name, email and availability.From here the poll and the participant are ordinary items: post to Slack, write a row to a sheet, or update your own system.Testing it
Use the Webhook node’s Test URL while building, then register the Production URL in Rallly. A quick end-to-end check is to close and reopen a poll in Rallly and watchpoll.closed and poll.reopened arrive.
When something fails
- Signature does not match on every request: Raw Body is off, or the secret in n8n is not the one Rallly showed when the endpoint was created. Delete and re-add the endpoint if the secret is lost.
- Timestamp older than five minutes: the n8n host’s clock is wrong, or the request was a replay. Rallly’s retries are signed fresh, so a stale timestamp is never a retry.
- Endpoint disabled in Rallly: twenty deliveries in a row exhausted their retries. Fix the workflow, then re-enable the endpoint from the settings page; events from while it was disabled are not replayed.