Skip to main content
Zudo can show an NPS survey inside your own product, on your terms: who gets asked, how often, and in your words. Every answer lands on the account and the contact it came from, so a score is never a number without a customer attached.
The survey is shown by zudo.js, so install that first. Everything on this page is configured at Settings › NPS survey.

What your users see

A small panel, three steps:
  1. The question — “How likely are you to recommend Acme to a friend or colleague?”, with a 0–10 scale.
  2. The follow-up — a box for what made them choose that. Optional; most of the value is here.
  3. Thanks — closes itself after a few seconds.
They can dismiss it at any step. The panel renders in a shadow root, so your product’s styling and the survey’s cannot interfere with each other — and you can restyle the whole thing with your own CSS, against stable class names. See Styling the survey.

Who gets asked

All of these have to be true. Zudo checks them on its own side, so they hold however the person reaches your product — a new browser or a private window does not reset them.
Settings › NPS survey: the allowed origins for the zudo.js key, the Show the survey switch, and the rules for who gets asked
On top of all of it, nobody is asked twice in one day. That one is not negotiable, and no playbook can override it.
The age rule is the one that catches people out. It is measured from the account’s createdAt trait when zudo.js sends one, and otherwise from the day Zudo first saw the account. On a fresh install that is today — so with the default of 30 days, nobody is eligible for a month. Send createdAt on your Zudo.account() call and it measures from the real date instead.

What it says

Every piece of wording is yours to change, and leaving a field empty uses the default shown in it. The settings page previews it as you type. {{productName}} is replaced with the product name you set, or with whatever your page passes to Zudo.nps("survey", { productName: "…" }). If it resolves to nothing, it is removed cleanly along with its space — the sentence still reads. You also control the button colour, where the panel appears, and how long after Zudo.nps() is called before it shows. For anything beyond that there is a Custom CSS box, with a live preview of the real panel — the class names are listed here.

Driving the survey from a playbook

The rules above describe one audience for everybody. A playbook lets you build a different one — and, more usefully, lets you ask somebody the ordinary cadence would not. Add a Show an NPS survey step to a playbook. When an account reaches that step it is invited: the next time somebody on it opens your product, the survey appears if they clear the rules you have set. The step shows nothing itself, because a playbook runs on a schedule and a survey has to be shown to a person who is actually there. Things people build with it:
  • ask only accounts that are paying, not trialling
  • ask two weeks before a renewal, whether or not they answered three months ago
  • ask only accounts in your Enterprise segment
  • ask after a big onboarding milestone, while it is fresh

Making an invitation required

By default an invitation only ever adds: everybody clearing the rules is still asked. Turn on Require a playbook invitation and that flips — nobody is asked unless a playbook has invited their account, with the rules still applying on top.
This is the one setting that can silence the survey entirely. Turned on with no playbook inviting anybody, nobody is ever asked and nothing tells you except an empty response list. The settings screen shows how many accounts currently hold an invitation, and says so plainly when that is none.

What the step can skip

The reason to invite from a playbook is usually that the ordinary cadence is in the way. Each rule is skipped independently, so a step can waive the wait without also asking somebody who has opened your product once: Nobody is asked twice in one day whatever you tick. The step also takes:
  • Invitation lasts — days before it lapses. Empty means it stands until somebody answers.
  • Ask a different question — replaces the question for people invited by this step, so a renewal playbook can ask a renewal-shaped question. The rest of the wording stays yours.
An invitation is used up when somebody on the account answers. If the playbook is set to undo its steps on exit, the invitation is taken back when the account stops matching, so an account does not stay inviteable long after it left.

Checking the wording

Call Zudo.nps("test") in your product. It ignores every rule above and records nothing, so you can read the real panel without waiting a month or spending one of your own responses.

Where answers show up

  • The account page, under Indicators & segments › NPS: the three numbers, and the last 90 answers with their comments. The three numbers are computed over every answer the account has ever given, whatever the list is showing; when there are more than 90, the panel says which it is showing.
  • The account timeline, under the NPS filter, and in the All view alongside meetings, emails and notes — so an answer sits next to whatever happened around it. Each row shows the score in its band’s colour, who gave it and what they wrote.
  • Settings › NPS survey: the most recent answers across every account.
Recent responses on Settings › NPS survey: each answer's score, comment, person and account, newest first
Each answer carries the score, the comment, who wrote it and when. An answer with no comment says so rather than showing a blank line — somebody scoring you 4 and saying nothing is itself worth seeing. Parent accounts show their members’ answers as well as their own, each row naming the account it came from.

Using NPS in rules

Every figure on the panel is a condition field, so NPS reads like anything else in Zudo: They work everywhere account conditions do:
  • Segments — a saved group like “detractors on more than $1k MRR”.
  • Playbook triggers — so an answer can start work. A detractor answering is the case this is really for: trigger on NPS Band is Detractor, and have the playbook create a task for the CSM, post to Slack, or raise a flag.
  • Flag rules — a flag rule is a segment plus a kind, so a segment of NPS Band is Detractor with a Risk flag rule puts a flag on every account whose latest answer is a detractor, and takes it off again when they next answer higher. Nothing to configure beyond the segment you already wrote.
  • The accounts table — open Filters and they are in the list, with presets for the common ones: Detractors, Promoters, Has answered, Never answered, Last 30 days.
  • This survey’s own audience filter — you can ask only accounts that have never answered, or only ones whose last answer was a detractor.
The numbers are per account. A parent account’s conditions read the answers given to the parent itself, not its members’ pooled ones — the same split every other aggregate uses. The panel pools them, because that is the honest figure to read; a segment counts rows, so it counts each account’s own.
An account nobody has answered for has no value for any of these, rather than a zero. That is deliberate: zero is a real and middling score and −100 is the worst possible NPS, so an unanswered account reaching NPS Score less than 0 as either would put every silent account in with your actual detractors. Use is not set to find the accounts you have never heard from.
Conditions read the account’s last 90 answers. The three numbers on the account panel are computed over every answer it has ever given. For almost every account these are the same set — 90 answers is years of a quarterly survey — but on an account that has answered more than that, a condition on NPS Average Answer or NPS Score can differ from the figure the panel shows. The panel is the complete one.

In the accounts table

An NPS column sits beside Health, Pulse and MRR, showing the standard calculation. Hover it for the latest answer, the average and how many answers it is built from — a figure of −100 means something different from two answers than from two hundred. Sort by it, or hide it from the column menu like any other.

In a smart trait formula

NPS is a variable namespace, alongside traits.* and indicators.*: So a formula can weigh what the customer said against what they are worth:
That is revenue sitting behind a detractor — a number neither NPS nor MRR gives you on its own.
For an account nobody has answered for, every variable except nps.count is undefined, and a comparison against undefined is false. That is deliberate, and it is why nps.count exists: write nps.count > 0 && nps.latest < 7 when a formula needs to tell “they are unhappy” from “we have never asked”.

In the health score

NPS can be a weighted factor in the health score, scored from the most recent answer inside the last 365 days. It defaults to 0% — switching on the survey does not move any score by itself — and you opt in under Health Score Settings. An account with no answer has the weight redistributed across the other factors rather than being scored zero.

In the AI features

Account Summary, AI Pulse, Meeting Prep and the Weekly Summary all read NPS answers, comments included. AI Pulse weighs them heaviest: it scores how the customer feels about you, and everything else it reads is inferred from behavior. Each of them is told the same three things about an answer — weigh it, say who gave it, and check the date. One person’s 4 on a fifty-seat account is one person’s 4, and a summary that reports it as “the customer is unhappy” is a sentence a CSM would act on wrongly.

Per person, not just per account

An account’s figure and one person’s answer are different facts, and the account one hides the person. A champion going from 9 to 4 moves a fifty-seat account’s average by almost nothing. So each contact on an account’s Contacts tab carries their own latest score, in its band’s colour, with their answer count on hover. Somebody who has not answered shows a dash. The other direction is the one a risk-shaped tool never shows you: Settings → NPS survey filters the response list by band, and Promoters is your referral, case-study and reference-call list — named people who have just said they would recommend you.
An answer that arrived without a contact resolved — an anonymous or imported one — counts toward the account and toward nobody’s personal figure. It is not folded into some other contact’s score.

Turning an answer into work

A comment is the most specific piece of product feedback a CS team gets, and on its own it sits in a panel. Under every answer — on the account’s NPS panel and on the timeline row — there are two actions: Both carry the full comment, the score, who answered and when — so a product team reading the request does not have to come back to Zudo for the rest of the sentence. The title is the comment itself rather than “NPS feedback from Acme”, because the sentence is the thing being tracked. An answer can have one of each: something to build, and somebody to call back are different pieces of work. Once it has one, the action becomes a link to it, so scrolling a long list shows which comments you have already dealt with and a second click cannot make a second copy.
The request is linked to the account, which is what makes it count toward that account’s open requests, its request list and its health score. An answer that arrived with no account resolved still creates the work — there is just nothing to link it to.
An answer with no comment can still become work; the title names the score and the band instead, which at least says why the request exists. A request made this way is ranked against your other requests straight away, as one made on the Requests page is. You can also ask the Assistant to do this, such as “make tasks for this week’s detractors who left a comment.” Its review card shows each answer and what it would create, and it skips an answer that already has that kind of work. Through the API, list_nps_responses now includes each answer’s requestId and taskId, so an integration can tell which answers have been handled too.

In the daily follow-up

A detractor answering in the last 14 days puts its account on the daily follow-up list on its own, with the comment quoted. A promoter lands in the “bring news” lane — the referral or case-study opening, while it is still fresh. Neither needs configuring.

In custom reporting

NPS Score, NPS Latest Answer, NPS Average Answer, NPS Answers and NPS Band are all available as fields in custom reporting, so you can chart NPS by CSM, by plan, or against anything else you group accounts on. Accounts with no answers carry no value rather than a zero, so they drop out of an average instead of dragging it down.

Who an answer is attributed to

Every answer belongs to an account and a person, and both have to resolve before anybody is asked. The account is matched on the accountId you send, against an account’s External ID and then its Vitally ID. The person is matched on the userId you send, and then on their email — which is the one that matters in practice, because most of your contacts are already in Zudo under an id your product has never heard of. Neither is created for you unless you have turned on auto-create. If the account and the person are already there, nothing needs creating and nothing needs switching on.

The three numbers

“NPS” means three different things, and Zudo keeps them apart rather than picking one for you: Scores are banded the standard way, so Zudo’s figure is comparable with whatever you reported before:
  • Detractors 0–6
  • Passives 7–8
  • Promoters 9–10
An account nobody has answered for shows no number rather than a zero. For the standard NPS that matters: zero is a real and middling score, and an account you have never heard from is not the same thing.
Parent accounts pool their members’ answers rather than averaging their members’ scores, so a customer made up of several accounts gets one honest figure rather than an average of averages. If your product has an organization layer, Zudo.organization builds those parent accounts for you.

Turning it on

The survey is off until you switch it on, so installing zudo.js never starts surveying people as a side effect. When you are ready:
1

Set the rules

Go to Settings › NPS survey and set who gets asked. The defaults are a reasonable starting point for most products.
2

Read the wording

Change what you want, and preview it as you go.
3

Check it with test mode

Call Zudo.nps("test") in your product and read the real panel.
4

Switch it on

Turn on Show the survey. The next eligible person sees it.

What is not here yet

Being straight about the current shape:
  • One survey per organization. Named surveys with their own questions and audiences are planned, not built.
  • In-app only. Emailing the survey is not available yet.
  • Nothing turns a comment into work on its own. The request or task is one click, not automatic — a playbook can create a task when a detractor answers, but it cannot write the request’s title from the comment.
  • The AI reads answers but does not go looking. A summary or a pulse generated before somebody answered does not regenerate itself; the next run picks the answer up.
  • Nothing happens the instant somebody answers. An answer marks its account for recomputation straight away, so a playbook picks it up on its next run (a few minutes) and a flag rule on its next sweep (hourly) — not the moment somebody presses Send.
  • Conditions are account-level. A contact’s own score is shown but cannot be written into a segment, a playbook trigger or a flag rule — those read the account’s figures. Finding named promoters is the band filter on the settings page, not a saved view.
  • Playbooks target accounts, not people. A Show an NPS survey step invites an account, and the per-person rules decide which of its people get asked. Conditions about an individual — their role, their own usage — are not available yet.