{
"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"
}
],
"showLanguageSwitch": true,
"autoSelectLanguage": true,
"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>",
"imageAltText": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"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>",
"imageAltText": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"videoUrl": "<string>",
"hideDefaultIcon": true
}
],
"hiddenFields": {
"enabled": true,
"fieldIds": [
"<string>"
]
},
"variables": [
{
"id": "<string>",
"name": "<string>",
"type": "number",
"value": 123
}
],
"customCss": {
"light": "<string>",
"dark": "<string>"
},
"visibility": "restricted",
"owner": {
"name": "<string>"
},
"access": {
"via": "workspace",
"canManageVisibility": true
},
"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>"
}
}
]
}
},
"warnings": [
{
"code": "import_removed",
"scope": "workspace",
"appearance": "light",
"line": 2,
"column": 2,
"reason": "<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": "Unprocessable Content",
"status": 422,
"detail": "This workspace has reached its survey limit",
"code": "workspace_survey_limit_reached",
"requestId": "req_01j9zq7w3k2m4n5p6r7s8t9v0w",
"details": {
"count": 10000,
"limit": 10000
}
}{
"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.
{
"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"
}
],
"showLanguageSwitch": true,
"autoSelectLanguage": true,
"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>",
"imageAltText": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"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>",
"imageAltText": {
"en-US": "What should we improve?",
"de-DE": "Was sollten wir verbessern?"
},
"videoUrl": "<string>",
"hideDefaultIcon": true
}
],
"hiddenFields": {
"enabled": true,
"fieldIds": [
"<string>"
]
},
"variables": [
{
"id": "<string>",
"name": "<string>",
"type": "number",
"value": 123
}
],
"customCss": {
"light": "<string>",
"dark": "<string>"
},
"visibility": "restricted",
"owner": {
"name": "<string>"
},
"access": {
"via": "workspace",
"canManageVisibility": true
},
"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>"
}
}
]
}
},
"warnings": [
{
"code": "import_removed",
"scope": "workspace",
"appearance": "light",
"line": 2,
"column": 2,
"reason": "<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": "Unprocessable Content",
"status": 422,
"detail": "This workspace has reached its survey limit",
"code": "workspace_survey_limit_reached",
"requestId": "req_01j9zq7w3k2m4n5p6r7s8t9v0w",
"details": {
"count": 10000,
"limit": 10000
}
}{
"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 and language settings, 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.
11 - 1000 elementsShow 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.
50Show child attributes
Show child attributes
Show respondents a language switch on multi-language surveys. null and false both mean off.
Open link and app surveys in the respondent's browser language when it matches an enabled survey language; otherwise the default language is used. null and false both mean off.
Optional card shown before the first survey block.
Show child attributes
Show child attributes
100Ending 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
100Survey 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
Optional survey custom CSS source. Processed by the server; constructs it removes come back as top-level warnings on the 201. Adding CSS needs the Scale plan on Formbricks Cloud (403 custom_css_plan_required); CSS that cannot be processed is a 422 with details.errors. Processing counts against the custom CSS budget of 60 per minute per user or API key, shared with custom CSS validation; beyond it the create is a 429 and nothing is written.
Show child attributes
Show child attributes
Response
Survey created successfully
The three fields every SurveyListItem and SurveyResource carries, merged into both via allOf. All required, always present.
Show child attributes
Show child attributes
Processing warnings for this write: constructs the processor removed. Additive, returned beside data (never inside it, so data can be sent back unchanged); present only when the write processed custom CSS.
50Show child attributes
Show child attributes
Was this page helpful?