curl --request POST \
--url https://app.formbricks.com/api/v3/surveys \
--header 'Content-Type: application/json' \
--cookie next-auth.session-token= \
--data '
{
"workspaceId": "clxx1234567890123456789012",
"name": "Product Feedback Survey",
"status": "draft",
"defaultLanguage": "en-US",
"metadata": {
"cx_operation": "enterprise_onboarding",
"title": {
"en-US": "Product Feedback",
"de-DE": "Produktfeedback"
}
},
"languages": [
{
"code": "de-DE",
"enabled": true
}
],
"welcomeCard": {
"enabled": true,
"headline": {
"en-US": "Welcome",
"de-DE": "Willkommen"
}
},
"blocks": [
{
"name": "Main Block",
"elements": [
{
"id": "satisfaction",
"type": "openText",
"headline": {
"en-US": "What should we improve?",
"de-DE": "Was sollen wir verbessern?"
},
"required": true
}
]
}
],
"endings": [],
"hiddenFields": {
"enabled": false
},
"variables": []
}
'{
"data": {
"id": "<string>",
"workspaceId": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"archivedAt": "2023-11-07T05:31:56Z",
"name": "<string>",
"type": "link",
"status": "draft",
"metadata": {
"title": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"description": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
}
},
"defaultLanguage": "<string>",
"languages": [
{
"code": "en-US",
"default": true,
"enabled": true,
"alias": "english"
}
],
"welcomeCard": {
"enabled": true,
"headline": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"subheader": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"buttonLabel": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"fileUrl": "<string>",
"videoUrl": "<string>",
"timeToFinish": true,
"showResponseCount": true
},
"blocks": [
{
"id": "<string>",
"name": "<string>",
"elements": [
{
"id": "<string>",
"type": "openText",
"headline": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"required": true,
"subheader": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"imageUrl": "<string>",
"videoUrl": "<string>",
"isDraft": true,
"placeholder": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"longAnswer": true,
"inputType": "text",
"insightsEnabled": false,
"charLimit": {
"enabled": false,
"min": 123,
"max": 123
},
"validation": {
"rules": [
{
"id": "<string>",
"type": "minLength",
"params": {},
"field": "addressLine1"
}
],
"logic": "and"
}
}
],
"logic": [
{
"id": "<string>",
"conditions": {
"id": "<string>",
"connector": "and",
"conditions": [
{
"id": "<string>",
"leftOperand": {
"type": "element",
"value": "<string>",
"meta": {}
},
"operator": "equals",
"rightOperand": {
"type": "static",
"value": "<string>"
}
}
]
},
"actions": [
{
"id": "<string>",
"objective": "calculate",
"variableId": "<string>",
"operator": "assign",
"value": {
"type": "static",
"value": "<string>"
}
}
]
}
],
"logicFallback": "<string>",
"buttonLabel": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"backButtonLabel": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
}
}
],
"endings": [
{
"id": "<string>",
"type": "endScreen",
"headline": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"subheader": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"buttonLabel": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"buttonLink": "<string>",
"imageUrl": "<string>",
"videoUrl": "<string>",
"hideDefaultIcon": true
}
],
"hiddenFields": {
"enabled": true,
"fieldIds": [
"<string>"
]
},
"variables": [
{
"id": "<string>",
"name": "<string>",
"type": "number",
"value": 123
}
],
"distribution": {
"displayOption": "displaySome",
"displayLimit": 3,
"displayPercentage": null,
"recontactDays": 7,
"autoClose": null,
"autoComplete": null,
"delay": 0,
"triggers": [
{
"actionClassId": "clyy1234567890123456789012"
}
]
},
"targeting": {
"filters": [
{
"id": "<string>",
"connector": "and",
"resource": {
"id": "<string>",
"root": {
"type": "attribute",
"contactAttributeKey": "<string>"
},
"qualifier": {
"operator": "lessThan"
},
"value": "<string>"
}
}
]
}
}
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"type": "<string>",
"instance": "<string>",
"code": "ai_features_not_enabled",
"details": {},
"invalid_params": [
{
"name": "<string>",
"reason": "<string>",
"code": "dangling_reference",
"identifier": "<string>",
"referenceType": "block",
"missingId": "<string>",
"firstUsedAt": "<string>",
"conflictsWith": "<string>"
}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"type": "<string>",
"instance": "<string>",
"code": "ai_features_not_enabled",
"details": {},
"invalid_params": [
{
"name": "<string>",
"reason": "<string>",
"code": "dangling_reference",
"identifier": "<string>",
"referenceType": "block",
"missingId": "<string>",
"firstUsedAt": "<string>",
"conflictsWith": "<string>"
}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"type": "<string>",
"instance": "<string>",
"code": "ai_features_not_enabled",
"details": {},
"invalid_params": [
{
"name": "<string>",
"reason": "<string>",
"code": "dangling_reference",
"identifier": "<string>",
"referenceType": "block",
"missingId": "<string>",
"firstUsedAt": "<string>",
"conflictsWith": "<string>"
}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"type": "<string>",
"instance": "<string>",
"code": "ai_features_not_enabled",
"details": {},
"invalid_params": [
{
"name": "<string>",
"reason": "<string>",
"code": "dangling_reference",
"identifier": "<string>",
"referenceType": "block",
"missingId": "<string>",
"firstUsedAt": "<string>",
"conflictsWith": "<string>"
}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"type": "<string>",
"instance": "<string>",
"code": "ai_features_not_enabled",
"details": {},
"invalid_params": [
{
"name": "<string>",
"reason": "<string>",
"code": "dangling_reference",
"identifier": "<string>",
"referenceType": "block",
"missingId": "<string>",
"firstUsedAt": "<string>",
"conflictsWith": "<string>"
}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"type": "<string>",
"instance": "<string>",
"code": "ai_features_not_enabled",
"details": {},
"invalid_params": [
{
"name": "<string>",
"reason": "<string>",
"code": "dangling_reference",
"identifier": "<string>",
"referenceType": "block",
"missingId": "<string>",
"firstUsedAt": "<string>",
"conflictsWith": "<string>"
}
]
}Create a survey
Creates a block-based survey template from one strict survey document. The endpoint accepts
multilingual authoring maps keyed by real locale codes and converts them to Formbricks’
internal default-language representation. Non-default locale keys in translated content
must be declared in languages; undeclared locale keys return unsupported_locale in
invalid_params instead of silently mutating workspace languages.
blocks[].id and variables[].id are stable public identifiers. They may be omitted on
create, in which case the server generates cuid2 ids. If the same create request needs to
reference a block or variable from logic, provide explicit valid ids and use those references
consistently.
For normal sequential surveys, omit logic and logicFallback. logicFallback is only valid
when the same block has at least one logic rule; otherwise the API returns
invalid_reference.
type may be omitted or set to link or app. App surveys additionally accept the distribution (display options + triggers) and targeting (contact segment filters) objects; both are rejected for link surveys. Trigger ids must reference existing workspace action classes (discover them via GET /api/v3/action-classes), and targeting.filters references (contact-attribute keys and segments) must exist in the workspace. Unsupported fields are rejected instead of ignored.
curl --request POST \
--url https://app.formbricks.com/api/v3/surveys \
--header 'Content-Type: application/json' \
--cookie next-auth.session-token= \
--data '
{
"workspaceId": "clxx1234567890123456789012",
"name": "Product Feedback Survey",
"status": "draft",
"defaultLanguage": "en-US",
"metadata": {
"cx_operation": "enterprise_onboarding",
"title": {
"en-US": "Product Feedback",
"de-DE": "Produktfeedback"
}
},
"languages": [
{
"code": "de-DE",
"enabled": true
}
],
"welcomeCard": {
"enabled": true,
"headline": {
"en-US": "Welcome",
"de-DE": "Willkommen"
}
},
"blocks": [
{
"name": "Main Block",
"elements": [
{
"id": "satisfaction",
"type": "openText",
"headline": {
"en-US": "What should we improve?",
"de-DE": "Was sollen wir verbessern?"
},
"required": true
}
]
}
],
"endings": [],
"hiddenFields": {
"enabled": false
},
"variables": []
}
'{
"data": {
"id": "<string>",
"workspaceId": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"archivedAt": "2023-11-07T05:31:56Z",
"name": "<string>",
"type": "link",
"status": "draft",
"metadata": {
"title": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"description": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
}
},
"defaultLanguage": "<string>",
"languages": [
{
"code": "en-US",
"default": true,
"enabled": true,
"alias": "english"
}
],
"welcomeCard": {
"enabled": true,
"headline": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"subheader": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"buttonLabel": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"fileUrl": "<string>",
"videoUrl": "<string>",
"timeToFinish": true,
"showResponseCount": true
},
"blocks": [
{
"id": "<string>",
"name": "<string>",
"elements": [
{
"id": "<string>",
"type": "openText",
"headline": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"required": true,
"subheader": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"imageUrl": "<string>",
"videoUrl": "<string>",
"isDraft": true,
"placeholder": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"longAnswer": true,
"inputType": "text",
"insightsEnabled": false,
"charLimit": {
"enabled": false,
"min": 123,
"max": 123
},
"validation": {
"rules": [
{
"id": "<string>",
"type": "minLength",
"params": {},
"field": "addressLine1"
}
],
"logic": "and"
}
}
],
"logic": [
{
"id": "<string>",
"conditions": {
"id": "<string>",
"connector": "and",
"conditions": [
{
"id": "<string>",
"leftOperand": {
"type": "element",
"value": "<string>",
"meta": {}
},
"operator": "equals",
"rightOperand": {
"type": "static",
"value": "<string>"
}
}
]
},
"actions": [
{
"id": "<string>",
"objective": "calculate",
"variableId": "<string>",
"operator": "assign",
"value": {
"type": "static",
"value": "<string>"
}
}
]
}
],
"logicFallback": "<string>",
"buttonLabel": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"backButtonLabel": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
}
}
],
"endings": [
{
"id": "<string>",
"type": "endScreen",
"headline": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"subheader": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"buttonLabel": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"buttonLink": "<string>",
"imageUrl": "<string>",
"videoUrl": "<string>",
"hideDefaultIcon": true
}
],
"hiddenFields": {
"enabled": true,
"fieldIds": [
"<string>"
]
},
"variables": [
{
"id": "<string>",
"name": "<string>",
"type": "number",
"value": 123
}
],
"distribution": {
"displayOption": "displaySome",
"displayLimit": 3,
"displayPercentage": null,
"recontactDays": 7,
"autoClose": null,
"autoComplete": null,
"delay": 0,
"triggers": [
{
"actionClassId": "clyy1234567890123456789012"
}
]
},
"targeting": {
"filters": [
{
"id": "<string>",
"connector": "and",
"resource": {
"id": "<string>",
"root": {
"type": "attribute",
"contactAttributeKey": "<string>"
},
"qualifier": {
"operator": "lessThan"
},
"value": "<string>"
}
}
]
}
}
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"type": "<string>",
"instance": "<string>",
"code": "ai_features_not_enabled",
"details": {},
"invalid_params": [
{
"name": "<string>",
"reason": "<string>",
"code": "dangling_reference",
"identifier": "<string>",
"referenceType": "block",
"missingId": "<string>",
"firstUsedAt": "<string>",
"conflictsWith": "<string>"
}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"type": "<string>",
"instance": "<string>",
"code": "ai_features_not_enabled",
"details": {},
"invalid_params": [
{
"name": "<string>",
"reason": "<string>",
"code": "dangling_reference",
"identifier": "<string>",
"referenceType": "block",
"missingId": "<string>",
"firstUsedAt": "<string>",
"conflictsWith": "<string>"
}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"type": "<string>",
"instance": "<string>",
"code": "ai_features_not_enabled",
"details": {},
"invalid_params": [
{
"name": "<string>",
"reason": "<string>",
"code": "dangling_reference",
"identifier": "<string>",
"referenceType": "block",
"missingId": "<string>",
"firstUsedAt": "<string>",
"conflictsWith": "<string>"
}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"type": "<string>",
"instance": "<string>",
"code": "ai_features_not_enabled",
"details": {},
"invalid_params": [
{
"name": "<string>",
"reason": "<string>",
"code": "dangling_reference",
"identifier": "<string>",
"referenceType": "block",
"missingId": "<string>",
"firstUsedAt": "<string>",
"conflictsWith": "<string>"
}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"type": "<string>",
"instance": "<string>",
"code": "ai_features_not_enabled",
"details": {},
"invalid_params": [
{
"name": "<string>",
"reason": "<string>",
"code": "dangling_reference",
"identifier": "<string>",
"referenceType": "block",
"missingId": "<string>",
"firstUsedAt": "<string>",
"conflictsWith": "<string>"
}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"requestId": "<string>",
"type": "<string>",
"instance": "<string>",
"code": "ai_features_not_enabled",
"details": {},
"invalid_params": [
{
"name": "<string>",
"reason": "<string>",
"code": "dangling_reference",
"identifier": "<string>",
"referenceType": "block",
"missingId": "<string>",
"firstUsedAt": "<string>",
"conflictsWith": "<string>"
}
]
}Authorizations
NextAuth session JWT cookie. Development: often next-auth.session-token.
Production (HTTPS): often __Secure-next-auth.session-token. Send the cookie your browser receives after sign-in.
Body
Strict v3 survey creation document. This endpoint accepts survey structure only: name,
metadata, languages, welcome card, blocks/elements/logic, endings, hidden fields, and variables.
App surveys (type: app) additionally accept the distribution (display options + triggers) and targeting (contact segment filters) objects; these are rejected for link surveys.
It rejects legacy questions and out-of-scope settings such as styling, follow-ups, recaptcha, single-use/email verification, slug, custom scripts, analytics fields, timestamps, and createdBy.
Translatable fields use real locale-code maps. The map must include the canonical
defaultLanguage key, such as en-US, so the server can persist the internal default
translation. Locale keys must be canonical BCP 47 codes such as de-DE, pt-PT, or
zh-Hans-CN. Non-default locale keys must be declared in languages; undeclared locale
keys in metadata, welcome cards, blocks, or endings are rejected with unsupported_locale.
blocks[].id and variables[].id may be omitted on create and will be generated by the
server. Provide explicit cuid2 ids when other fields in the same request reference them.
For normal sequential flow, omit logicFallback. It is only valid together with a non-empty
logic array on the same block.
Workspace where the survey will be created. Requires read/write access.
11Show child attributes
Show child attributes
Survey type. link surveys are distributed by URL; app surveys are shown in-app and configure their runtime behavior via the distribution and targeting objects. type is immutable after creation (it cannot be changed via PATCH).
link, app draft, inProgress, paused, completed Arbitrary JSON survey context for customer- or operation-specific metadata. v3 preserves
arbitrary metadata values as-is. If present, title and description are treated as
translatable text maps and returned with real locale-code keys.
Show child attributes
Show child attributes
Default authoring locale. Translatable maps must include this locale key.
^[a-z]{2}(?:-[A-Z][a-z]{3})?-[A-Z]{2}$"en-US"
Optional survey language configuration. Every non-default locale used by translatable maps must be declared here; omitted languages are not inferred from map keys.
Show child attributes
Show child attributes
Optional card shown before the first survey block.
Show child attributes
Show child attributes
Ending reached after the last block or a jump action. type selects the allowed shape;
unsupported fields are rejected instead of ignored.
- Option 1
- Option 2
Show child attributes
Show child attributes
Hidden fields, sometimes called embedded data in other survey products. Field ids are stable public identifiers and may be referenced by logic, recall, quotas, integrations, and response data.
Naming rule for new field ids — the same rule the survey editor applies (ENG-2539): a new id must start with a lowercase letter and then contain only lowercase letters, numbers and underscores (^[a-z][a-z0-9_]*$), and must not take a reserved name. Reserved are the link-survey system params and internal ids — userId, source, suid, end, start, welcomeCard, hidden, verifiedEmail, multiLanguage, embed, verify, suToken, lang, preview, startAt, skipPrefilled, offlineSupport (matched case-insensitively) — and the names of auto-captured system fields, which every survey can already read without declaring them: source, url, country, action, browser, os, deviceType, ipAddress, finished, language, locale, responseId, surveyId, durationSeconds, startedAt, finishedAt, pagePath, pageReferrer, utmSource, utmMedium, utmCampaign, utmTerm, utmContent, screenWidth, screenHeight, viewportWidth, viewportHeight, timezone.
Ids a survey already declares are grandfathered: they always load, and re-sending the survey unchanged never fails validation — only adding such a name as a new field is refused. Deleting a grandfathered field spends the reprieve: once it is gone from the saved survey, the name can no longer be re-added. Note this means re-creating a survey from an exported document can fail with a 400 when the export declares a name the rule refuses; rename the field in the payload before importing. The pattern below describes what stored surveys may hold (the pre-existing lenient charset), not what a new id may look like.
Show child attributes
Show child attributes
Survey variable accepted by POST /api/v3/surveys. id may be omitted and will be
generated by the server. Provide an explicit cuid2 id when logic in the same request needs
to reference this variable.
- Option 1
- Option 2
Show child attributes
Show child attributes
App-survey runtime/display settings. Only valid when type is app.
Show child attributes
Show child attributes
{
"displayOption": "displaySome",
"displayLimit": 3,
"displayPercentage": null,
"recontactDays": 7,
"autoClose": null,
"autoComplete": null,
"delay": 0,
"triggers": [
{
"actionClassId": "clyy1234567890123456789012"
}
]
}
App-survey contact targeting. Only valid when type is app.
Show child attributes
Show child attributes
Response
Survey created successfully
Show child attributes
Show child attributes
Was this page helpful?