csat survey agent spamming follow-ups: dedupe guard
A guide to stopping CSAT survey agents from spamming follow-ups, in the business-apis-integrations category: send dedupe, cooldowns, and one-survey-per-ticket rules. Use when customers receive duplicate or repeated CSAT surveys, or when building survey automation guardrails. Not for writing survey questions, survey timing strategy, or analyzing CSAT results.
TL;DR
Survey spam happens when the send logic has no memory: ticket updates re-trigger the survey, retries double-send, and reopened tickets survey twice. Dedupe on ticket plus survey type, enforce a per-customer cooldown, and make the send idempotent so retries never duplicate. One ticket, one survey, ever.
The query
csat survey agent spamming follow-ups: dedupe guardUse this when
- Customers get duplicate CSAT surveys
- Reopened tickets trigger second surveys
- You are building survey automation
- Survey complaints spike
Not for
- Writing the survey questions
- Deciding when to send surveys
- Analyzing CSAT scores
- NPS program design
Steps
1. Dedupe on ticket plus survey type
Record every survey sent keyed by ticket id and survey type. Before sending, check the key. A ticket that already got its CSAT survey never gets another, no matter how many updates or reopens follow.
Expected output: sent-survey registry checked before every send.
2. Enforce a per-customer cooldown
Even across tickets, cap survey frequency: no customer surveyed more than once per 30 days. Frequent ticket openers should not become frequent survey takers. The cooldown is per customer, not per ticket.
Expected output: a 30-day per-customer survey cap enforced.
3. Make the send idempotent
Retries, double-triggers, and race conditions should never produce two surveys. Use idempotency keys on the send call or check-then-send atomically. Idempotent sends make the dedupe bulletproof.
Expected output: duplicate triggers collapse to one send.
4. Suppress on reopen within the window
If a ticket reopens within a few days of close, suppress the survey from the first close and send one survey at the final resolution. The customer experiences one ticket; they should get one survey.
Expected output: reopen suppression with a single final survey.
5. Monitor sends per customer
Track survey sends per customer per month and alert on outliers. The metric catches logic bugs before customers complain: a customer with five surveys in a week is a bug, not a super-user.
Expected output: per-customer send monitoring with alerts.
Template: the checklist
CSAT survey dedupe:
[ ] Sent registry keyed by ticket plus survey type
[ ] Per-customer cooldown enforced (30 days)
[ ] Idempotent sends: retries never duplicate
[ ] Reopen suppression within the window
[ ] Per-customer send counts monitoredVariant phrasings
duplicate csat surveys same ticket
Steps 1 and 3. Registry plus idempotency.
customer surveyed too often
Step 2. The per-customer cooldown.
survey sent twice on reopen
Step 4. Suppress, then survey once at final close.
Why it happens
Survey triggers attach to ticket events (close, resolve), and tickets generate many such events: updates after close, reopens, merges. Each event looks like a fresh survey opportunity to trigger logic with no memory. The spam is not a bug in any single trigger; it is the absence of a shared send memory.
Edge cases
- Merged tickets: two tickets with two surveys merge into one. Dedupe across the merge or suppress the loser's survey.
- Multiple survey types: CSAT plus a follow-up survey need separate dedupe keys but a shared cooldown.
- Test tickets: internal test closes should never send surveys. Exclude test requesters.
- The customer replies to the survey with a new issue: route it as a ticket, and do not count it as survey engagement for cooldown purposes.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_EgpOnY8Ib2eW-1ApWCecjw