When and Why to Use
Use this to capture Net Promoter Score (NPS), which measures the likelihood of a respondent to recommend a product, service, or brand. Ideal for:
-
Customer satisfaction benchmarking
-
Brand tracking
-
Loyalty measurement
This is a special case of a rating scale with specific scoring thresholds for Promoters, Passives, and Detractors.
Chat Experience
-
Slider or button input centered with numeric scale
-
Optional labels help anchor the ends and midpoint
-
Optional "Don't know" option appears below scale
See rating question for examples of the UX.
Traditional Experience
-
Layout shows more of the scale horizontally
-
Works with keyboard/remote navigation
-
Star and button styles are supported for more visual UIs
See rating question for examples of the UX.
Configuration Options
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
| question | string | yes | - | The question shown to the respondent |
| number_of_points | int | no | 11 | Number of scale points (at least 2; typically 0-10) |
| first_point | int | no | 0 or first label | First value on the scale |
| style | string | no | slider | "slider", "button", or "star" |
| labels | Dict[int, str] | no | endpoint labels | Labels for points on the scale; by default the first and last actual points read "Not at all likely" and "Extremely likely" |
| image | MediaItem | no | - | Optional image above the question |
| image_size | Tuple[int, int] | no | (600, 600) | Bounding box size for a displayed image |
| default | int | List[int] | no | random | Raw scale point used in test mode, or a list of candidate points — each simulated respondent picks one at random; the pick is classified to -100, 0, or 100 like a live response |
| dont_know_option | str | no | - | Text label for "Don't know" button |
| recodes | Dict[str, str] | no | - | Maps the classified keys "-100", "0", and "100" (plus the "Don't know" label, if configured) to reported values |
| custom_validator | Callable[[int | str], str | None] | no | - | Called with the classified response (-100, 0, or 100; "Don't know" arrives as its text); return an error message to reject |
| min_promoter_score | int | no | 9 on the 0-10 scale | Inclusive minimum score classified as a Promoter; supply together with max_detractor_score |
| max_detractor_score | int | no | 6 on the 0-10 scale | Inclusive maximum score classified as a Detractor; supply together with min_promoter_score |
| number_seconds | int | no | 0 | Seconds to wait before allowing the respondent to continue |
tags | s.tag() | no | - | Used for dynamic substitution and reporting |
| id | str | None | no | None | Optional stable identifier for this question |
Classified Responses
The selected point is classified before it is returned, stored, or reported — the exact point a respondent picks is not retained:
-
Detractor (score at or below
max_detractor_score) returnsIntResponse(-100) -
Passive (between the two thresholds) returns
IntResponse(0) -
Promoter (score at or above
min_promoter_score) returnsIntResponse(100)
Both thresholds are inclusive and must be supplied together, and the promoter threshold must be strictly greater than the detractor threshold. The defaults keep the standard relative positions and shift with first_point: on the standard 0-10 scale, Detractors are 0-6, Passives are 7-8, and Promoters are 9-10.
Example Code
Basic NPS question:
s.net_promoter_score_question( "How likely are you to recommend this product to a friend?", number_of_points=11, labels={ 0: "Not at all likely", 10: "Extremely likely" } )
With recodes:
s.net_promoter_score_question( "How likely are you to recommend this product to a friend?", number_of_points=11, recodes={ "-100": "Detractor", "0": "Passive", "100": "Promoter" } )
With "Don't know" option:
s.net_promoter_score_question( "How likely are you to recommend {brand}?", number_of_points=11, dont_know_option="Not sure", tags=s.tag(brand="Tesla") )
Notes
-
The question returns an
IntResponseof -100 (Detractor), 0 (Passive), or 100 (Promoter) — never the raw 0-10 score -
NPS is calculated by subtracting the % of Detractors (score <= max_detractor_score) from the % of Promoters (score >= min_promoter_score)
-
dont_know_option responses are returned to survey code as -999 and reported using the configured label
-
Imported values of -100, 0, and 100 are treated as already classified; any other valid scale point is classified as raw input, so an imported 0 is the Passive segment, not a raw score of zero
-
When a simulated transcript replays a classified value, it substitutes a representative raw point (6, 7, and 9 on the standard scale); the conversion is deliberately lossy
-
Use recodes for segmentation and reporting — keys are the classified values "-100", "0", and "100", not raw scale points
-
custom_validator can block test inputs or enforce attention

