Skip to content
Knowledge ERP Docs

API Reference ↗
Surveys

Survey Responses

One respondent's completed submission to a survey — the set of answers they gave to each question, tied back to the survey and, when there is one, the invitation that brought them in.

A survey response is a single, completed submission to a survey. When a customer fills out your post-purchase survey and hits submit, that's one response — a record that ties together who answered (when known), which survey they answered, and every answer they gave. Responses are where the raw sentiment lives before it rolls up into an NPS score or a low-score alert.

Survey vs. response, in one line: a survey is the set of questions you design; a response is one person's filled-out copy of it. You build and send surveys; you read and report on responses.

What a response holds #

Each response is deliberately thin — it's mostly a container that points at other things:

  • Survey — the survey the response belongs to. Required; every response is anchored to exactly one survey.
  • Invitation — the invitation that solicited it, when there is one. This is how a response gets a respondent email and a source (the record the invitation was sent about). Responses collected through an anonymous open link have no invitation, so they show no email.
  • Answers — one entry per question the respondent addressed, each linking to the question and carrying the value they gave (see below).
  • Submitted at — when the response came in, taken from when the record was created.

How answers are stored #

A response's answers are kept as individual records, one per question. Each answer can carry its value in one of three shapes, depending on the question type:

  • a choice — the selected option's label, for multiple-choice questions,
  • a numeric value — for scale or rating questions (scale, star rating, NPS), or
  • text — for free-form questions.

A matrix and a ranking write one answer row per option: for a matrix the choice is the grid row and the text is the column picked for it, and for a ranking the choice is the option and the number is the place it was given. So an answer with a choice standing on its own is the answer, and an answer with a choice and a value beside it is a label for that value — which is why a matrix reads back as "Explaining what was wrong: Excellent".

When a response is displayed or returned, the system shows whichever of these is set, falling back to a dash when a question was left blank.

A rating is checked against its question's scale before it is stored. A score that is not on the scale — an 11 on a 0–10 pain rating, a 6 on a five-star question — is refused and nothing is written, whatever wrote it: the form, the autosave, the anonymous link, the CSV import, or a script talking to the database directly. Before that, only the rendered radio buttons stood in the way.

Answers come back in the survey's own order. The order the survey asks its questions in, then, within a matrix or a ranking, the order its rows or options are offered in. That holds everywhere a response is read — the response page, the invitation page, the CSV export, the respondent's receipt and the API.

Collecting responses #

Responses aren't created by hand inside the app — they arrive when respondents submit a survey. Two paths lead to a response:

  • From an invitation — a survey invitation is sent to a customer (often about a specific record, its source), the customer follows the link and submits, and a response is recorded against both the survey and that invitation.
  • From an anonymous open link — the survey's public link lets anyone submit without an invitation. These responses are still tied to the survey but have no respondent email or source.

Either way, the response and its answers are saved together, and the survey's NPS and response-rate reporting update accordingly.

Reporting on answers #

Beyond the survey results page, survey answers are a Report Builder data source — one row per answer, carrying the survey, the question, the question type, the chosen option, the score, the written answer, the respondent and the submission date. Group by question and average the score to get an outcome table you can save, share and schedule, instead of exporting a CSV and pivoting it by hand. Submitted responses only.

Viewing responses #

Open Surveys → Responses for the list. Each row shows the survey, the respondent email (from the invitation, blank for anonymous submissions), the source of the invitation (e.g. an order or customer record, shown by type), and when it was answered. The list is sorted newest-first, and you can search by survey name or email.

Click any row to open the response. Its page shows the survey, respondent email, and submission time up top, then an Answers section listing every question alongside the answer that was given. Responses are read-only here — there's nothing to edit, because a response is a historical record of what someone submitted.

Responses are soft-deleted: removing one hides it from the list but keeps it in the database, so reporting history and audit trails stay intact.

How responses relate to surveys #

Responses are the payload of the Surveys module. A survey defines the questions and the delivery options; its responses are the answers that come back. The survey's NPS score and response-rate funnel are computed from its responses, and low-score alerts fire off the values inside them. To understand a number on a survey's report, drill into its responses.

Doing it from the API #

The survey-responses endpoint is read-only — you can list responses and fetch a single one, but you can't create, edit, or delete them over the API (responses come in through survey submission). Over the API, identifiers use _id field names (e.g. survey_id).

# List survey responses (optionally filter to one survey)
curl "https://your-domain.com/api/v1/survey-responses?survey_id=$SURVEY_ID" \
  -H "Authorization: Bearer $TOKEN"

# Get a single response with its answers
curl "https://your-domain.com/api/v1/survey-responses/{surveyResponse}" \
  -H "Authorization: Bearer $TOKEN"

Listing is paginated at 50 per page and accepts a survey_id query parameter to scope results to one survey. Each response returns its answers, with each answer carrying question_id and whichever of choice_id, answer_numeric, or answer_text applies.

survey_invitation_id is null for a response that came in off the anonymous public link — nobody was invited, so there is no invitation to point at. respondent_email is the address either way: the invited person's, or whatever an anonymous respondent volunteered, and null when they left none.

Most question types leave one answer per question, but a matrix, a ranking and a multi-select each leave one answer per option, so group a response's answers by question_id before reading them. In those rows choice_id is not the answer — it names the option, and the answer sits beside it: the rating a matrix row was given is in answer_text, and the position a ranking option was put in is in answer_numeric.