Skip to content

Create new survey

POST
/surveys
curl --request POST \
--url https://app.surveyrock.com/api/v1/surveys \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "name": "example", "description": "example", "language": "en", "type": 1, "settings": {}, "questions": [ { "type": "text_input", "text": "example", "subject": "example", "helpText": "example", "required": false, "choices": [ "example" ], "multipleAnswers": false, "rows": [ "example" ], "columns": [ "example" ], "pageTitle": "example" } ] }'

Create new survey using shared SurveyService. Uses the same service as web SurveyController to ensure zero duplication. settings is checked exactly as in updateSurvey (nested, every value checked, 422 with field errors, 403 feature_locked for a setting the plan lacks), and a survey whose settings are refused is not created. With questions, the survey is created with those questions in one step, all or nothing, and the response lists each question’s new element id. The response carries the new resource’s ETag, as the ETag header and as meta.etag.

Idempotency-Key
string
>= 1 characters <= 128 characters

1 to 128 characters, chosen by the caller. Optional on this operation: a retry with the same key and body replays the first response instead of applying the write twice; the same key with a different body is a 409

Survey creation data

Media typeapplication/json
object
name
required

Survey name

string
description

Survey description

string
nullable
language

Survey language code

string
default: en
type

Survey type

integer
default: 1
settings

Nested settings to start with, e.g. {“display”: {“progressStyle”: “bar”}}. See updateSurvey.

object
questions

Optional. The survey’s questions, in order, written with the survey in one step: each is the question the survey editor would make for its type, with that type’s defaults. A question with pageTitle starts a new page with that title; the questions before the first one go on the first page. The list is checked whole first: any problem is a 422 naming each question at fault, and a list longer than the plan’s questions-per-survey limit is a 403 quota_exceeded. Either way no survey is created.

Array<object>
<= 100 items
object
type
required

Question type. text_input is a free-text answer, rating_scale a rating scale, ranking puts choices in order, matrix asks rows against columns.

string
Allowed values: text_input multiple_choice rating_scale matrix slider nps yes_no email date ranking file_upload
text
required

The question as respondents read it. Except for nps: an NPS question always asks the standard sentence, “How likely is it that you would recommend [subject] to a friend or colleague?”, so its text is not shown; set subject instead. The response gives each question’s text as respondents will see it.

string
<= 5000 characters
subject

For nps only: who or what is recommended, e.g. “us” or “our support team”. Leave it out for “this company”. Refused on other types.

string
nullable <= 50 characters
helpText

Optional guidance shown under the question.

string
nullable <= 5000 characters
required

Whether a respondent must answer it.

boolean
choices

The answer options, for multiple_choice and ranking. Ignored for other types.

Array<string>
<= 50 items
multipleAnswers

For multiple_choice: let respondents pick more than one. Ignored for other types.

boolean
rows

For matrix and slider: the statements rated. None gives the editor’s three placeholder rows. Ignored for other types.

Array<string>
<= 50 items
columns

For matrix: the answer columns. None keeps the editor’s standard scale. Ignored for other types.

Array<string>
<= 10 items
pageTitle

Start a new page at this question, with this title.

string
nullable <= 255 characters

Survey created successfully

Media typeapplication/json
object
success
boolean
data
object
surveyId
string
name
string
createdAt
string format: date-time
questions

Present when the request had questions: each one written, in the request’s order, with the id its element now has.

Array<object>
object
elementId
string
type
string
text
string
meta

Standard response metadata

object
timestamp

Response timestamp in ISO 8601 format

string format: date-time
version

API version

string
requestId

Unique request identifier

string
etag

The resource’s ETag, on a read, create or update of a survey, element, rating or NPS question, distributor or contact. The same value as the ETag response header. Treat it as opaque and send it back as If-Match on the next update.

string
Example
{
"success": true,
"meta": {
"version": "3.0"
}
}
ETag
string
Example
"element:abc123:1790690123456789"

The resource’s current version, as a strong validator. Opaque: send it back unchanged as If-Match. Also returned as meta.etag in the body, for a client that only sees the body.

Bad request - invalid data

Media typeapplication/json

Standard error response format

object
success
boolean
error
object
code

Stable, snake_case domain code – see ApiErrorHandler::EXCEPTION_MAP and DomainException

string
message

Human-readable error message

string
suggestion

Imperative recovery hint for this domain code – see ApiErrorHandler::DOMAIN_CODE_SUGGESTIONS

string
retryable

Whether retrying the identical request might succeed without any change on the caller’s end

boolean
details

Additional, code-specific error details

object
meta

Standard response metadata

object
timestamp

Response timestamp in ISO 8601 format

string format: date-time
version

API version

string
requestId

Unique request identifier

string
etag

The resource’s ETag, on a read, create or update of a survey, element, rating or NPS question, distributor or contact. The same value as the ETag response header. Treat it as opaque and send it back as If-Match on the next update.

string
Example
{
"success": false,
"error": {
"code": "survey_not_found"
},
"meta": {
"version": "3.0"
}
}

Forbidden - the account is over its limit; or (error code feature_locked; details name the plan that includes it) settings names a setting the account’s plan does not include; or (error code quota_exceeded; details give limit, requested and required_plan) questions has more questions than the plan allows on one survey. Nothing is created.

Media typeapplication/json

Standard error response format

object
success
boolean
error
object
code

Stable, snake_case domain code – see ApiErrorHandler::EXCEPTION_MAP and DomainException

string
message

Human-readable error message

string
suggestion

Imperative recovery hint for this domain code – see ApiErrorHandler::DOMAIN_CODE_SUGGESTIONS

string
retryable

Whether retrying the identical request might succeed without any change on the caller’s end

boolean
details

Additional, code-specific error details

object
meta

Standard response metadata

object
timestamp

Response timestamp in ISO 8601 format

string format: date-time
version

API version

string
requestId

Unique request identifier

string
etag

The resource’s ETag, on a read, create or update of a survey, element, rating or NPS question, distributor or contact. The same value as the ETag response header. Treat it as opaque and send it back as If-Match on the next update.

string
Example
{
"success": false,
"error": {
"code": "survey_not_found"
},
"meta": {
"version": "3.0"
}
}

Validation failed; details are keyed by location, e.g. “settings.display.progressStyle”

Media typeapplication/json

Validation error response with field-specific errors

object
success
boolean
error
object
code
string
message
string
suggestion
string
retryable
boolean
details

Field-specific validation errors

object
key
additional properties
Array<string>
meta

Standard response metadata

object
timestamp

Response timestamp in ISO 8601 format

string format: date-time
version

API version

string
requestId

Unique request identifier

string
etag

The resource’s ETag, on a read, create or update of a survey, element, rating or NPS question, distributor or contact. The same value as the ETag response header. Treat it as opaque and send it back as If-Match on the next update.

string
Example
{
"success": false,
"error": {
"code": "validation_failed",
"message": "Validation failed",
"suggestion": "Fix the fields listed in details and re-submit.",
"retryable": false
},
"meta": {
"version": "3.0"
}
}