Surveys
Manage surveys, work with hidden variables and settings
Overview
The Surveys/Quizzes API lets you programmatically create surveys, manage questions, configure settings, handle hidden variables, control the survey lifecycle (duplicate, rename, archive, delete), and manage default label texts.
Download the markdown version of the "Surveys" section for use in ChatGPT / other LLMs:
Create & edit
This section covers creating a new survey and saving its questions.
Create survey
Creates a new survey in the specified folder and returns the survey object.
Request body (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
| folder_id | integer | Yes | ID of the folder to create the survey in |
curl -X POST "https://api.surveyninja.io/api/v3/service/quiz" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{"folder_id": 5}' Successful response (201)
{ "id": 124, "workspace_id": 1, "name": "Survey #12", "virtual_id": "abc12xyz", "url_preview": "https://example.com/quiz/124/preview", "url_shared": "https://example.com/q/abc12xyz", "is_published": false } Possible errors
| HTTP | Code | Description |
|---|---|---|
| 400 | workspace_not_found, folder_not_found | Workspace or folder not found |
| 401 | user_not_authenticated | Invalid or missing authorization token |
| 403 | quiz_limit_today | Daily survey creation limit reached for this account |
| 422 | validation_error | Request body validation error |
Survey questions
Save the full set of questions for a survey using the /quiz/{id}/save endpoint.
Saves the full question structure for the survey. Replaces the existing set of questions.
Request body (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
| ids | array | Yes | Ordered array of question identifiers (UUIDs, "welcome", "submit") |
| entities | object | Yes | Object mapping each question ID to its full data object |
ids values
The ids array contains question identifiers in display order. Special values:
| Value | Description |
|---|---|
| welcome | Welcome screen (intro page) |
| submit | Completion screen (thank-you page) |
| UUID | UUID — a regular question |
Common fields for all question types
| Field | Type | Description |
|---|---|---|
| type | string | Required. Question type identifier (see types table below) |
| title | string | Question title / label text |
| withTitle | boolean | Show the title field |
| description | string | Question description / subtitle text |
| withDescription | boolean | Show the description field |
| isRequired | boolean | Make the question required |
| isBlocked | boolean | Block the question (hide from respondents) |
| multimedia | object \| null | Multimedia object (image, video, audio) or null |
| filling_time_enabled | boolean | Enable per-question time limit |
| filling_time_seconds | integer | Time limit for the question in seconds |
Question types
| type | Name | Description |
|---|---|---|
| welcome | Welcome screen | Intro / welcome screen |
| yesno | Yes / No | Yes / No question |
| choice | Choice | Single or multiple choice from a list of options |
| dropdown | Dropdown | Dropdown list selection |
| ranking | Ranking | Drag-and-drop ranking of options |
| slider | Slider | Slider with configurable min/max/step |
| rating | Rating | Star/heart/emoji rating scale |
| scale | Scale | Numeric scale (e.g. 1–10) |
| input | Text input | Short or long text input |
| Email address input field | ||
| phone | Phone | Phone number input field |
| datetime | Date & Time | Date and/or time picker |
| matrix | Matrix | Matrix grid (rows × columns) |
| message | Message | Static message or info block |
| file | File upload | File upload |
| html | HTML block | Custom HTML content block |
| submit | Submit screen | Completion / thank-you screen |
Multimedia object structure
| Field | Description |
|---|---|
| type | img, video, audio |
| imgUrl | URL of the image |
| videoUrl | URL of the video |
| imgLocation | Image position: top, left, right, background |
| videoSettings | Video player settings object |
Additional fields by question type
Validation rules
- All values in ids must be unique
- Every value in ids must have a corresponding entry in entities
- Every key in entities must be present in ids
- Each entity object must have a type field
curl -X POST "https://api.surveyninja.io/api/v3/service/quiz/123/save" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "ids": ["welcome", "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "submit"], "entities": { "welcome": { "type": "welcome", "title": "Welcome", "welcomeLabel": "Start" }, "a1b2c3d4-e5f6-7890-abcd-ef1234567890": { "type": "rating", "title": "Rate the service", "ratingCount": 5, "ratingFigure": "star" }, "submit": { "type": "submit", "submitLabel": "Submit" } } }' Errors
| HTTP | Description |
|---|---|
| 400 | Survey not found |
| 401 | Authorization required |
| 403 | Access to the survey is denied |
| 422 | Validation error: ids and entities are inconsistent |
| 500 | Internal server error while saving the survey structure |
Get survey list
Returns a paginated list of all active (non-archived) surveys.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| sort | string | No | Field to sort by (e.g. name, created_at) |
| order | string | No | Sort direction: asc or desc |
| limit | integer | No | Maximum number of surveys to return |
| offset | integer | No | Number of surveys to skip (pagination offset) |
curl -X GET "https://api.surveyninja.io/api/v3/service/quiz?sort=name&order=asc&limit=10&offset=0" \ -H "Authorization: Bearer YOUR_TOKEN" [ { "id": "survey ID", "name": "name", "url_shared": "survey URL", "is_published": true, "folder": { "id": 384, "workspace_id": 384, "user_id": 12, "name": "My Surveys", "pos": 1, "is_default": true, "created_at": "2022-04-01T08:37:14.000000Z", "updated_at": "2022-04-27T15:46:27.000000Z", "deleted_at": null } } ] Get survey data
Returns the full data object for a specific survey, including all questions and settings.
curl -X GET https://api.surveyninja.io/api/v3/service/quiz/123 \ -H "Authorization: Bearer YOUR_TOKEN" { "id": "survey ID", "answer_count": "number of responses", "name": "name", "url_shared": "survey URL", "widgets": "question structure (ids, entities)", "hidden_options": "hidden variable", "folder": { "id": 384, "workspace_id": 384, "user_id": 12, "name": "My Surveys", "pos": 1, "is_default": true, "created_at": "2022-04-01T08:37:14.000000Z", "updated_at": "2022-04-27T15:46:27.000000Z", "deleted_at": null } } Survey settings
Updates one or more setting groups for a survey. All parameters are optional — only the fields you send will be updated.
Basic
| Parameter | Type | Description |
|---|---|---|
| name | string | Survey name / title |
| lang | string | Survey interface language code (e.g. en, ru) |
| info_title | string | Internal survey title (shown in the dashboard) |
| description | string | SEO meta description for the survey page |
Display
| Parameter | Type | Description |
|---|---|---|
| show_progressbar | boolean | Show progress bar |
| show_navigate | boolean | Show navigation buttons (Back / Next) |
| numeration | boolean | Show question numbers |
| auto_move_by_enter | boolean | Auto-advance to the next question when Enter is pressed |
| show_by_one | boolean | Show one question at a time |
| allow_multiple_answer | boolean | Allow multiple submissions from the same respondent |
| show_copyright | boolean | Show the SurveyNinja copyright footer |
Access & restrictions
| Parameter | Type | Description |
|---|---|---|
| close_quiz_enabled | boolean | Close the survey (stop accepting responses) |
| limit_time_enabled | boolean | Enable response deadline |
| limit_time_value | string | Response deadline (datetime string) |
| limit_time_timezone | string | Timezone for the response deadline (e.g. Europe/London) |
| limit_answer_count_enabled | boolean | Limit the total number of responses |
| limit_answer_count_value | integer | Maximum number of responses |
| use_password | boolean | Password-protect the survey |
| multiple_ip | boolean | Allow multiple responses from the same IP address |
| show_captcha | boolean | Show CAPTCHA before submission |
| ip_list_enabled | boolean | Enable IP address filtering |
| ip_whitelist | string | Comma-separated list of allowed IP addresses |
| ip_blacklist | string | Comma-separated list of blocked IP addresses |
| available_devices[] | array | Allowed devices: desktop, mobile, tablet |
Behavior
| Parameter | Type | Description |
|---|---|---|
| scoring_switcher | boolean | Enable scoring mode |
| question_required_mode | string | individual / all_required / all_optional |
| question_random_order | boolean | Randomize the order of questions |
| disable_auto_redirect | boolean | Disable automatic redirect after submission |
| block_jump_to_prev_widget | boolean | Prevent respondents from going back to previous questions |
| filling_time_enabled | boolean | Enable overall survey time limit |
| filling_time_seconds | integer | Survey time limit in seconds |
Analytics & QR code
| Parameter | Type | Description |
|---|---|---|
| scripts_in_head | string | Custom scripts inserted in |
| scripts_in_body | string | Custom scripts inserted before |
| scripts_in_head_enabled | boolean | Enable head scripts |
| scripts_in_body_enabled | boolean | Enable body scripts |
| sso_active | boolean | Enable Single Sign-On (SSO) |
| qr_code_size | integer | QR code size in pixels |
| qr_code_color | string | QR code foreground color (HEX) |
| qr_code_background_color | string | QR code background color (HEX) |
| qr_code_margin | integer | QR code margin in pixels |
curl -X POST "https://api.surveyninja.io/api/v3/service/quiz/123/settings/info" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "New survey name", "lang": "en", "show_progressbar": true, "limit_answer_count_enabled": true, "limit_answer_count_value": 500, "question_required_mode": "all_required" }' Survey management
The following endpoints let you manage the lifecycle of surveys: add notes, duplicate, rename, make a template, archive, move, and delete.
Survey lifecycle
Saves the full question structure of the survey (replaces existing questions).
curl -X POST "https://api.surveyninja.io/api/v3/service/quiz/123/save" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "ids": ["welcome", "question-1", "submit"], "entities": { "welcome": { "type": "welcome", "...": "..." }, "question-1": { "type": "choice", "title": "...", "...": "..." }, "submit": { "type": "submit", "...": "..." } } }' Applies a design theme to the survey.
curl -X POST "https://api.surveyninja.io/api/v3/service/quiz/123/applyTheme/925" \ -H "Authorization: Bearer YOUR_API_TOKEN" Publishes the current draft of the survey so respondents can access it.
curl -X POST "https://api.surveyninja.io/api/v3/service/quiz/123/publish" \ -H "Authorization: Bearer YOUR_API_TOKEN" Saves the branching logic (skip/jump conditions) for the survey.
curl -X POST "https://api.surveyninja.io/api/v3/service/quiz/123/conditions" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "conditions": { "...": "logic structure, same as in the builder" } }' Add note
Adds or updates a note (internal comment) attached to the survey.
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| notes | string | Yes | Note text (maximum 1000 characters) |
curl -X POST https://api.surveyninja.io/api/v3/service/quiz/123/note \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "notes": "Note text (maximum 1000 characters)" }' { "status": true, "notes": "Note text" } Duplicate survey
Creates a full copy of the survey including all questions and settings.
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | No | Name for the duplicated survey (optional; defaults to a copy of the original name) |
curl -X POST https://api.surveyninja.io/api/v3/service/quiz/123/duplicate \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Copy name (optional)" }' { "status": true, "quiz": { "id": 123, "name": "Copy: Survey Name", "url_shared": "https://example.com/abc123", "is_published": false, "created_at": "2024-01-01T12:00:00Z", "updated_at": "2024-01-01T12:00:00Z", "folder": { "id": 1, "name": "My Folder" } } } Rename survey
Renames the survey.
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | New survey name |
curl -X POST https://api.surveyninja.io/api/v3/service/quiz/123/rename \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "New survey name" }' { "status": true, "name": "New survey name" } Make template
Marks the survey as a reusable template available in the template gallery.
curl -X POST https://api.surveyninja.io/api/v3/service/quiz/123/template \ -H "Authorization: Bearer YOUR_TOKEN" { "status": true } Archive survey
Archives or unarchives a survey. Archived surveys do not accept new responses.
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| archive | boolean | Yes | true — archive the survey, false — unarchive |
curl -X POST https://api.surveyninja.io/api/v3/service/quiz/123/archive \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "archive": true }' { "status": true, "archive_at": "2024-01-01T12:00:00Z", "is_archived": true } Move survey
Moves the survey to a different folder within the same workspace.
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| folder_id | integer | Yes | ID of the target folder |
curl -X POST https://api.surveyninja.io/api/v3/service/quiz/123/move \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "folder_id": 5 }' { "status": true, "folder_id": 5, "folder": { "id": 5, "name": "New Folder" } } Delete survey
Permanently deletes a survey along with all its responses. This action cannot be undone.
curl -X DELETE https://api.surveyninja.io/api/v3/service/quiz/123 \ -H "Authorization: Bearer YOUR_TOKEN" { "status": true } Archived surveys
Returns the list of archived surveys.
curl -X GET https://api.surveyninja.io/api/v3/service/quiz/archived \ -H "Authorization: Bearer YOUR_TOKEN" [ { "id": 123, "name": "Archived survey", "url_shared": "https://example.com/abc123", "is_published": false, "created_at": "2024-01-01T12:00:00Z", "updated_at": "2024-01-01T12:00:00Z", "archive_at": "2024-01-02T12:00:00Z", "folder": { "id": 1, "name": "My Folder" } } ] Default texts
Default labels are button and UI texts shown to respondents (e.g. Next, Back, Submit). Retrieve current values and override them per survey.
Get default texts GET /api/v3/service/quiz/{id}/default-texts
| Parameter | Type | Default | Description |
|---|---|---|---|
| lang | string | ru | Language code for which to retrieve labels (e.g. ru, en) |
Returns an array of label objects, each with code, standard_text, and user_text (custom override, or null).
curl -X GET "https://api.surveyninja.io/api/v3/service/quiz/123/default-texts?lang=ru" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Accept: application/json" Response example
[ { "code": "btn_next", "standard_text": "Next", "user_text": null }, { "code": "btn_back", "standard_text": "Back", "user_text": "Go Back" }, { "code": "btn_submit", "standard_text": "Submit", "user_text": null } ] Update default texts POST /api/v3/service/quiz/{id}/default-texts
Updates custom label texts for the survey. Pass text: null to reset to the standard text.
| Parameter | Type | Description |
|---|---|---|
| texts[] | array | Array of objects with fields code and text |
| texts[].code | string | Label code from the GET response |
| texts[].text | string|null | New text; null resets to the standard value |
400 blocked_by_tariff — the feature is not available on the current plan. curl -X POST "https://api.surveyninja.io/api/v3/service/quiz/123/default-texts" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "texts": [ { "code": "btn_next", "text": "Forward" }, { "code": "btn_back", "text": null } ] }'