The same recipe on a platform you can self-host. Free either way.
Every answer can post itself to n8n the moment it arrives, and go anywhere from there — Slack, a spreadsheet, your CRM.
What arrives, exactly as the app sends it:
{
"event": "response.created",
"survey": {
"id": "C9kIGpyl",
"name": "After a support chat",
"question": "NPS",
"channel": "link"
},
"response": {
"id": "va5cZvLGf7g",
"score": 9,
"comment": "Quick and friendly, thanks.",
"answered_at": "2026-09-01T20:47:02Z"
},
"contact": {
"email": "customer@example.com",
"name": "Sam Taylor"
},
"account": { "name": "Acme Coffee Roasters" },
"sent_at": "2026-09-01T20:47:02Z"
}
On an anonymous answer contact is missing entirely rather
than present and empty, so your automation can tell a link answer from a
contact with no name. Two events exist —
response.created and response.updated, when
somebody adds a comment to a score they already gave. Same shape.
This one condition is most of the value of the whole setup. Add an IF node after the webhook, with a single rule:
response.score <= 6
Only the answers that need a person get past it — into the Slack channel the shift is watching, a ticket with the comment already in the body, a message naming who to call back today. Everything else is counted and left alone. The score bands are the standard NPS ones: 0–6 detractor, 7–8 neutral, 9–10 promoter.
The half that matters most: something happens in your world and the survey goes out on its own. Add an HTTP Request node pointed at one of your surveys — the id is on your surveys page.
POST https://www.usedownright.com/api/v1/surveys/SURVEY_ID/invitations
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"contact_email": "customer@example.com",
"contact_name": "Sam Taylor",
"locale": "it"
}
locale is optional and sticks to that person from then on.
Downright speaks 13 languages, so the survey arrives in
the customer's own without branching in n8n.
Asking how the delivery went while the parcel is still in the van gets you
an answer about the wait. Add deliver_at and Downright holds
the survey until the moment is right:
{
"contact_email": "customer@example.com",
"deliver_at": "2026-09-04T09:00:00Z"
}
Send an offset or a Z; without one it is read as UTC.
Unsubscribes, throttling and your quota are re-checked at the moment of
sending, so somebody who unsubscribes on Tuesday will not get Wednesday
what you queued on Monday.
Every delivery is signed, so an automation that acts on the data can verify before it acts:
X-Downright-Event: response.created X-Downright-Event-Id: unique per event, safe to use for idempotency X-Downright-Timestamp: unix seconds X-Downright-Signature: hex HMAC-SHA256 of "<timestamp>.<body>"
Skip it while trying the recipe out; add it before the automation matters.
n8n can run on your own server, so survey answers go from Downright to your machine and stop there — no third platform on the list of processors you keep for GDPR. If your answers name customers, that is a real argument, not a preference.
Built with the Webhook and HTTP Request nodes that ship with n8n — there is no Downright node in n8n yet, and this recipe does not need one. Your n8n must be reachable from the internet for the webhook half; the sending half works from anywhere.