API Reference
API Reference

/surveys/:id/outcomes

Returns aggregated results of a survey cycle: response overview and per-question statistics. Required scope: r_surveys.

Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…
🚧

This endpoint uses the r_surveys scope, which must be enabled through the Integrations section found within the Settings menu.

Requires a user token whose member has permission to view survey cycles, or an account token together with the member_id query parameter of such a member (the request is then evaluated with that member's permissions). An account token without member_id gets 403 Account tokens need a member_id for this operation. The account must have the Surveys feature enabled.

Statistics are calculated only over participants the member is allowed to view (members with a scoped role only see aggregates of employees within their scope), and only submitted responses count towards answers and choice distributions. Deleted survey cycles return 404.

Anonymity threshold

For anonymous surveys with min_responses_required greater than 0:

  • If fewer submitted responses than min_responses_required exist, overview.minimum_responses_requirement_met is false, every ratings[].count / percentage is 0 and every average_score is null. Overview counts and total_answers are still returned.
  • Once the threshold is met, the choice breakdown is returned only for questions that have themselves received at least min_responses_required answers.

For non-anonymous surveys the threshold is ignored and minimum_responses_requirement_met is always true.

Pagination

Pagination applies to questions. limit and offset are optional; when omitted, outcomes for every question are returned. total is the number of questions matching question_ids[] (or all questions of the survey), regardless of limit / offset.

Use question_ids[] to restrict the outcomes to specific questions, e.g. ?question_ids[]=2501ee00-0004-51cc-8e1c-6b29548a3d01. Ids that do not belong to the survey's questionnaire are ignored.

Results

{
  "overview": {
    "total_surveys": 3,
    "responses_count": 2,
    "average_response_time": 200,
    "minimum_responses_requirement_met": true
  },
  "outcomes": [
    {
      "question_id": "2501ee00-0003-51cc-8e1c-6b29548a3d01",
      "question_type": "paragraph",
      "question_title": "<p>What part of your role gives you the most energy right now?</p>",
      "section_id": "2501ee00-0002-51cc-8e1c-6b29548a3d01",
      "section_title": "<p>Your experience</p>",
      "mandatory": false,
      "total_answers": 2,
      "average_score": null,
      "ratings": []
    },
    {
      "question_id": "2501ee00-0004-51cc-8e1c-6b29548a3d01",
      "question_type": "multiple_choice",
      "question_title": "<p>Which best describes your usual work arrangement?</p>",
      "section_id": "2501ee00-0002-51cc-8e1c-6b29548a3d01",
      "section_title": "<p>Your experience</p>",
      "mandatory": true,
      "total_answers": 2,
      "average_score": null,
      "ratings": [
        {
          "value": "1",
          "label": "Mostly remote",
          "count": 1,
          "percentage": 50
        },
        {
          "value": "2",
          "label": "Hybrid",
          "count": 1,
          "percentage": 50
        },
        {
          "value": "3",
          "label": "Mostly in-office",
          "count": 0,
          "percentage": 0
        }
      ],
      "options": {
        "choices": {
          "1": "Mostly remote",
          "2": "Hybrid",
          "3": "Mostly in-office"
        }
      }
    },
    {
      "question_id": "2501ee00-0008-51cc-8e1c-6b29548a3d01",
      "question_type": "star_rated",
      "question_title": "<p>How would you rate your work-life balance?</p>",
      "section_id": "2501ee00-0005-51cc-8e1c-6b29548a3d01",
      "section_title": "<p>Wellbeing</p>",
      "mandatory": true,
      "total_answers": 2,
      "average_score": 2.5,
      "ratings": [
        {
          "value": "1",
          "label": "Poor",
          "count": 0,
          "percentage": 0
        },
        {
          "value": "2",
          "label": "Good",
          "count": 1,
          "percentage": 50
        },
        {
          "value": "3",
          "label": "Excellent",
          "count": 1,
          "percentage": 50
        }
      ],
      "options": {
        "1": "Poor",
        "2": "Good",
        "3": "Excellent"
      }
    }
  ],
  "total": 3
}
keytypedescription
overviewobjectResponse overview of the survey
overview.total_surveysintegerNumber of participants (employee surveys) visible to the member
overview.responses_countintegerNumber of submitted responses
overview.average_response_timenumber | nullAverage time, in seconds, participants took to complete the survey. null when there are no submitted responses
overview.minimum_responses_requirement_metbooleanWhether the anonymity threshold (min_responses_required) is met. Always true for non-anonymous surveys
outcomesarrayPer-question statistics, in questionnaire order
outcomes[].question_idstringQuestion id
outcomes[].question_typestringQuestion type in snake_case. One of: paragraph, paragraph_star_rated, paragraph_numeric_rated, paragraph_custom_rated, single_choice, multiple_choice, star_rated, numeric_rated, custom_rated
outcomes[].question_titlestringQuestion text (HTML)
outcomes[].section_idstringId of the section the question belongs to
outcomes[].section_titlestringSection title (HTML)
outcomes[].mandatorybooleanWhether an answer is required
outcomes[].semantic_typestringSemantic role of the question, when set. One of: section_rating, overall_rating
outcomes[].total_answersintegerNumber of submitted responses that answered the question
outcomes[].average_scorenumber | nullAverage of the selected numeric values, rounded to 2 decimals. Only for rated question types; null otherwise or when results are withheld
outcomes[].ratingsarrayDistribution of answers per option. Empty for questions without options or choices
outcomes[].ratings[].valuestringOption / choice key
outcomes[].ratings[].labelstringOption / choice label (omitted when the question defines no labels)
outcomes[].ratings[].countintegerNumber of responses that selected the option
outcomes[].ratings[].percentagenumbercount as a percentage of total_answers, rounded to 2 decimals
outcomes[].optionsobjectOptions defined on the question (omitted when there are none). For rated questions a map of rating value to label; for choice questions an object with a choices map of choice key to label
totalintegerNumber of questions matching the filters (before limit / offset)

Error responses

StatusCondition
400id is not a valid survey cycle key, or invalid query parameters (limit < 1, offset < 0, a question_ids[] value that is not a UUID)
401Missing or invalid token
403Missing r_surveys scope, account token without member_id, the Surveys feature is not enabled for the account, or the user lacks permission to view survey cycles
404No survey cycle with the supplied id exists in the account, it is deleted, or its questionnaire template cannot be found

Error bodies: 401 / 403 responses are plain text holding the reason (e.g. Required scopes missing: ["r_surveys"]). 404 responses are JSON of the form {"message": "..."}. 400 validation errors are JSON keyed by the offending field, e.g. {"limit": {"code": "number.min", "message": "\"limit\" must be greater than or equal to 1"}}.

Path Params
string
required

Survey cycle key (as returned by GET /surveys)

Query Params
integer
≥ 1

Maximum number of questions to return. When omitted, all questions are returned.

integer
≥ 0

Number of questions to skip (for pagination).

question_ids[]
array of uuids
length ≥ 1

Restrict the outcomes to these question ids. Ids not in the survey's questionnaire are ignored.

question_ids[]
string

Required when using an account token: the member (SPI key, from GET /members) to act as. The request is evaluated with that member's permissions; without it the request gets 403. Ignored for user tokens.

Headers
string
enum
Defaults to application/json

Generated from available response content types

Allowed:
Responses

Language
Credentials
Header
URL
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json
text/plain