Omniscope Custom Blocks › Analytics/Net-Promoter-Score

Net Promoter Score

Net Promoter Score per group and period from 0-10 answers, with margin of error, confidence interval, weights, significance vs the rest and vs the previous period.

Analytics › Marketing Python visokio-agents

Open the demo in Omniscope Download demo.ioz Sample data: nps-survey.csv Source on GitHub

Items tagged visokio-agents are community examples built by Visokio's agents, to extend Omniscope's core blocks and views with popular, specialist and more unusual use cases, and to show what anyone, people or agents, can build on Omniscope. They are tested by automated tests and were run on a real Omniscope server. They were not reviewed by Omniscope's core team, so they are not on a par with the core blocks and views, which have years of manual, functional and unit tests behind them. About

Omniscope custom block · Analytics

Net Promoter Score per group and period with the margin of error, so a change of a few points is not reported as news when it is noise.

Python · pandas, numpy · nothing extra to install

The problem it solves

NPS is simple to calculate and easy to over-read. A store, agent or month with 40 responses can move 20 points by chance, and dashboards that show only the score invite the wrong conversations: celebrating noise, or chasing a team whose score is within the margin of error.

This block calculates NPS the standard way and adds what an analyst would: the margin of error and confidence interval, survey weights, a test of each group against the rest and of each period against the previous one, plus the score distribution and per-response NPS points for any further slicing.

How it works

What goes in

NPS survey

3,200 synthetic responses over 2025 by region and channel, with a few blank and "Don't know" answers (illustrative).

Response ID Response Date Region Channel Likelihood To Recommend
R02809 2025-01-01 Midlands Store 9
R02285 2025-01-01 Midlands Online 10
R02779 2025-01-01 London Online 6
R00105 2025-01-01 North Online 9
R00713 2025-01-01 Midlands Online 5
R01347 2025-01-01 South West Online 9

3,200 rows in the sample file.

The options

Option Demo setting What it does
Score field (0-10) Likelihood To Recommend The answer to the likelihood-to-recommend question, from 0 to 10.
Group by (optional) Channel For example Region or Channel.
Date field (optional) Response Date Needed to report by period.
Report by period Quarter Adds a row per period, compared with the period before. Needs a date field.
Confidence level 0.95 For the margin of error and significance tests.
Small sample below 30 Rows with fewer responses are flagged.

What comes out

NPS by channel and quarter

Channel Period Responses % Promoters % Detractors NPS Margin Of Error CI Low CI High Vs Rest Change Vs Previous Change Significant
All 2025Q1 788 32.9 32 0.9 5.6 -4.7 6.5
All 2025Q2 791 32.2 30.6 1.6 5.5 -3.9 7.2 0.8 Not significant
All 2025Q3 795 35.6 28.8 6.8 5.6 1.2 12.4 5.1 Not significant
All 2025Q4 786 36.5 22.9 13.6 5.3 8.3 18.9 6.8 Not significant
Contact Centre 2025Q1 133 20.3 54.9 -34.6 13.5 -48.1 -21.1 Lower
Contact Centre 2025Q2 135 23 45.9 -23 13.5 -36.4 -9.5 Lower 11.6 Not significant
Contact Centre 2025Q3 132 9.8 59.8 -50 11.4 -61.4 -38.6 Lower -27 Lower
Contact Centre 2025Q4 137 21.9 33.6 -11.7 12.3 -24 0.6 Lower 38.3 Higher
Online 2025Q1 346 38.7 24.9 13.9 8.3 5.6 22.1 Higher
Online 2025Q2 348 37.1 25.3 11.8 8.2 3.6 20 Higher -2.1 Not significant
Online 2025Q3 335 46.6 19.4 27.2 8.2 19 35.4 Higher 15.4 Higher
Online 2025Q4 342 40.9 18.7 22.2 7.8 14.4 30.1 Higher -4.9 Not significant
Store 2025Q1 309 31.7 30.1 1.6 8.8 -7.1 10.4 Not significant
Store 2025Q2 308 30.8 29.9 1 8.7 -7.7 9.7 Not significant -0.6 Not significant
Store 2025Q3 328 34.8 25.9 8.8 8.4 0.5 17.2 Not significant 7.9 Not significant
Store 2025Q4 307 38.1 22.8 15.3 8.6 6.7 23.9 Not significant 6.5 Not significant

Score distribution (all channels)

Channel Score Category Responses Share
All 0 Detractor 2 0.001
All 1 Detractor 7 0.002
All 2 Detractor 17 0.005
All 3 Detractor 57 0.018
All 4 Detractor 130 0.041
All 5 Detractor 277 0.088
All 6 Detractor 413 0.131
All 7 Passive 554 0.175
All 8 Passive 619 0.196
All 9 Promoter 502 0.159
All 10 Promoter 582 0.184
The line is overall NPS; each bar shows how far a region's score could move by chance. London is lowest at -4 (synthetic data).
The line is overall NPS; each bar shows how far a region's score could move by chance. London is lowest at -4 (synthetic data).

The line is overall NPS; each bar shows how far a region's score could move by chance. London is lowest at -4 (synthetic data).

Nearly half of Contact Centre respondents are detractors (synthetic data).
Nearly half of Contact Centre respondents are detractors (synthetic data).

Nearly half of Contact Centre respondents are detractors (synthetic data).

Quarterly NPS: the Contact Centre dip in Q3 is flagged as significant; most other quarter-on-quarter moves are not (synthetic data).
Quarterly NPS: the Contact Centre dip in Q3 is flagged as significant; most other quarter-on-quarter moves are not (synthetic data).

Quarterly NPS: the Contact Centre dip in Q3 is flagged as significant; most other quarter-on-quarter moves are not (synthetic data).

Where it pays off

Retail and hospitality: Store and site league tables

NPS per store with margins of error, so area managers act on stores that are significantly below the rest, not on the ones with the fewest responses.

Telecoms and utilities: Journey and channel NPS

Transactional NPS by contact channel and reason, with month-on-month changes tested before they reach the board pack.

SaaS and B2B: Relationship NPS by segment

Account-weighted NPS (weights by revenue or seats) by plan, region and customer age.

Public sector and healthcare: Friends and family style surveys

Recommendation scores per ward, practice or service with small samples flagged.

Use cases describe typical scenarios and are illustrative.

Why do this in Omniscope

How it fits into an Omniscope workflow

Survey export (file, database or API) → Net Promoter Score → Report (league table, trend, distribution) → Email output (alerts)

Load survey responses on a schedule; Data Cleansing upstream can tidy free-text group names.

Show the NPS table and trend in a Report; filter rows where Change Significant is Lower to alert owners. The responses output with NPS Points lets any Report re-aggregate NPS by any field as an average.

In one step

Categories, NPS, margin of error and significance tests, with weights and period-on-period changes.

Try it

  1. Open the demo project (demo.iox on the demo server, or import demo.ioz from this folder): a year of synthetic survey responses by channel and region.
  2. The question: what is our NPS, which channel is dragging it down, and did anything really change this year?
  3. Open the block: choose the score field, group by Channel, date field and Quarter. Run it.
  4. Look at the table: overall +5.7 ±2.8; Contact Centre -30, flagged lower than the rest.
  5. Look at the trend: the Contact Centre Q3 dip (-27) is significant, while most other moves are flagged not significant, which is why the block reports the margin of error.

Running in Omniscope

Omniscope workflow
Omniscope workflow

The demo project's workflow: the sample data, the block, and a Validate data check on its output.

Language and libraries

Python. It uses pandas and numpy, plus the Python standard library (math).

pandas and numpy are part of Omniscope's Docker Python image, and the block was run in both host mode and Docker mode on an Omniscope server, with the same results. It needs nothing else installed.

Tested

Run on an Omniscope server, the demo workflow finished without errors (16 records in NPS, 44 in Score distribution and 3,200 in Responses). Automated tests also cover normal data, empty input, wrong types and large input.

Reference

Fields it reads

NameTypeWhat it does
Score field (0-10)FieldThe answer to the likelihood-to-recommend question, from 0 to 10.
Group by (optional)FieldsFor example Region or Channel.
Weight field (optional)FieldSurvey weights; leave empty for unweighted.
Date field (optional)FieldNeeded to report by period.

Options

NameTypeWhat it does
Report by periodChoiceAdds a row per period, compared with the period before. Needs a date field.
Confidence levelNumberFor the margin of error and significance tests.
Small sample belowWhole numberRows with fewer responses are flagged.

Outputs

OutputWhat it holds
NPSPer group (and period): counts, shares, NPS, standard error, margin of error, confidence interval, vs rest, change vs previous period.
DistributionPer group: responses and share for each score 0 to 10.
ResponsesThe input with NPS Category and NPS Points (+100 / 0 / -100).