Discord
Receive notifications about new survey responses directly in a Discord channel.
Setup
Step 1 — Create a Webhook in Discord
- Open your server in Discord and go to the channel settings (⚙️ next to the channel name).
- Select Integrations → Webhooks → New Webhook.
- Give the webhook a name (e.g.
ftools) and click Copy Webhook URL. - The URL looks like this:
https://discord.com/api/webhooks/000000000000000000/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Step 2 — Connect the integration in ftools
- Open the survey and go to the Integrations tab.
- Click Add integration and select the type Webhook.
- In the Provider field select Discord.
- Paste the Webhook URL from step 1 into the Webhook URL field.
- Optionally set a name, e.g.
Discord — Product feedback. - Click Save.
The integration will send a notification to Discord on every new survey response.
Step 3 — Done
Each new response will appear in the channel as an embed message:
- Title: survey name
- Left border color: 🟢 green (promoter), 🟡 yellow (passive), 🔴 red (detractor) — NPS surveys only
- Fields: Score, Bucket, User (email, plan, country)
- Response text in the embed body
Optional — Signature verification
If you want to verify that requests come from ftools, set a secret in the Secret field when creating the integration, or leave it blank to auto-generate one.
The secret can be rotated at any time via the Rotate secret button in integration settings.
Each request will include an X-Webhook-Signature: sha256=<signature> header. See Webhook signature verification for verification instructions.
Reference
Integration configuration
| Field | Value |
|---|---|
integration_type | webhook |
provider | discord |
event_types | ["survey.response"] |
url | Discord Webhook URL |
secret | HMAC signing secret (auto-generated if not provided) |
Trigger
The survey.response event fires on every new survey response submitted through the public widget.
Subscription requirement: ACTIVE or CANCELED. Delivery does not occur on PAYMENT_OVERDUE.
Retries
On failure: 30 s → 120 s → 600 s.
HTTP request
POST <url>
Content-Type: application/json
X-Webhook-Event: survey.response
X-Webhook-Signature: sha256=<hmac>
User-Agent: feedback-tools-webhook/1.0Timeout: 10 seconds. A 2xx response is considered a success.
Payload format
Discord receives an Embeds payload:
{
"embeds": [
{
"title": "Post-onboarding NPS",
"color": 3066993,
"timestamp": "2026-05-07T10:15:00+00:00",
"description": "Love the new dashboard",
"fields": [
{ "name": "Score", "value": "9", "inline": true },
{ "name": "Bucket", "value": "promoter", "inline": true },
{ "name": "User", "value": "user@example.com (pro) · PL", "inline": false }
]
}
]
}Formatting rules
title: survey.title, maximum 256 characters.
color: integer (hex → decimal):
| Bucket | Hex | Decimal |
|---|---|---|
| promoter (9–10) | #2ECC71 | 3066993 |
| passive (7–8) | #F1C40F | 15844367 |
| detractor (0–6) | #E74C3C | 15158332 |
| non-NPS / no score | #95A5A6 | 9807270 |
Color is only calculated for nps_10 survey type.
timestamp: response.created_at taken as-is from the event payload.
description: response text (response.text), only included if non-empty. Maximum 4096 characters.
fields:
Score— included ifresponse.valueis not nullBucket— included only for NPS surveys (nps_10)User— built frommetadata.email,metadata.plan(in parentheses),response.country(prefixed with·). Field is omitted if all values are missing
Signature verification
See Webhook signature verification.
Delivery
| Field | Description |
|---|---|
status | pending / success / failed |
attempt_count | Attempt number (1–4) |
response_status | HTTP status returned by Discord |
response_body | Response body (up to 2048 characters) |
error | Error description on network failure |
Delivery history is available in the Integrations section on the survey page.