---
title: "Set survey block order"
method: PUT
path: "/api/v3/surveys/{surveyId}/blocks/order"
tags: ["V3 Surveys"]
---

# Set survey block order

`PUT /api/v3/surveys/{surveyId}/blocks/order`

## Request

- Base URL: `https://app.formbricks.com`
- URL: `https://app.formbricks.com/api/v3/surveys/{surveyId}/blocks/order`
- Auth: one of:
  - API key in cookie `next-auth.session-token`
  - API key in header `x-api-key`
  - HTTP bearer

Replaces the order of a survey's blocks. The body lists every current block id exactly once, in the order you want; block content is untouched.

Idempotent: the same `order` always yields the same survey, and an order that already matches performs no write at all, so `updatedAt` does not move and other callers' preconditions stay valid. A stale `expectedUpdatedAt` is still rejected with **409** on that path — the precondition is evaluated before the method, so a no-op outcome never reports success to a stale caller. Because the list must be a permutation, a dropped or duplicated block is rejected rather than silently applied — the failure mode that resending the whole `blocks` array cannot catch.

Pass `expectedUpdatedAt` (the `updatedAt` from your last read) to make the write conditional; see the **409** response. Session cookie or x-api-key.

## Path parameters

- `surveyId` string, cuid2, required

## Request body

- SetSurveyBlockOrderRequest
  - `order` string[], required: Every current block id, exactly once, in the desired order. Ids are trimmed before use, so an id that is empty or whitespace-only is a **400**, as is a list of more than 1000 ids. A missing, unknown or repeated id is a **422** — repeats are reported as `duplicate_identifier` rather than rejected by the schema, so the response names the offending entry, and a dropped block cannot pass unnoticed, which is what makes this safer than resending the blocks.
  - `expectedUpdatedAt` string, date-time: Optimistic-concurrency precondition: the survey's `updatedAt` from your last read. If the survey changed since, the write is rejected with **409**.

## Response `200`

Order applied (or already matching); returns the full survey resource.

- object
  - `data` SurveyResource, required: The three fields every `SurveyListItem` and `SurveyResource` carries, merged into both via `allOf`. All required, always present.
    - `id` string, required
    - `workspaceId` string, required
    - `createdAt` string, date-time, required
    - `updatedAt` string, date-time, required
    - `archivedAt` string, date-time, nullable, required: Soft-delete/archive marker (ISO 8601); `null` when the survey is active.
    - `name` string, required
    - `type` 'link' | 'app', required
    - `status` 'draft' | 'inProgress' | 'paused' | 'completed', required
    - `metadata` SurveyMetadata, required: 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.
      - `title` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
      - `description` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
    - `defaultLanguage` string, required: Emitted language code/tag for the survey default language. The internal `default` translation key is never exposed.
    - `languages` SurveyLanguage[], required
      - `code` string, required: Server-emitted survey language code/tag used as the translatable map key.
      - `alias` string, nullable: Optional configured alias accepted by `?lang` for compatibility and agent discovery.
      - `default` boolean, required: Whether this is the default authoring language.
      - `enabled` boolean, required: Whether this language is enabled for respondent-facing delivery.
    - `showLanguageSwitch` boolean, nullable, required: Show respondents a language switch on multi-language surveys. `null` and `false` both mean off.
    - `autoSelectLanguage` boolean, nullable, required: 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.
    - `welcomeCard` SurveyWelcomeCard, required: Optional card shown before the first survey block.
      - `enabled` boolean, required
      - `headline` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
      - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
      - `buttonLabel` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
      - `fileUrl` string
      - `videoUrl` string
      - `timeToFinish` boolean
      - `showResponseCount` boolean
    - `blocks` SurveyBlock[], required
      - `id` string, cuid2, required: Stable block id.
      - `name` string, required
      - `elements` SurveyElement[], required
        - union: Survey element/question inside a block. Element ids are stable public identifiers used by logic, recall strings, response data, quotas, integrations, and analysis. `type` selects the allowed shape; unsupported fields are rejected instead of ignored.
          - SurveyOpenTextElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'openText', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `placeholder` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `longAnswer` boolean
            - `inputType` 'text' | 'email' | 'url' | 'number' | 'phone'
            - `insightsEnabled` boolean
            - `charLimit` SurveyCharLimit: Optional `openText` character limit configuration.
              - …
            - `validation` SurveyValidation: Optional element-level validation rules.
              - …
          - SurveyConsentElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'consent', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `label` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `validation` SurveyValidation: Optional element-level validation rules.
              - …
          - SurveyMultipleChoiceSingleElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'multipleChoiceSingle', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `choices` SurveyChoice[], required
              - …
            - `shuffleOption` 'none' | 'all' | 'exceptLast' | 'reverseOrderOccasionally' | 'reverseOrderExceptLast'
            - `otherOptionPlaceholder` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `displayType` 'list' | 'row' | 'dropdown'
          - SurveyMultipleChoiceMultiElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'multipleChoiceMulti', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `choices` SurveyChoice[], required
              - …
            - `shuffleOption` 'none' | 'all' | 'exceptLast' | 'reverseOrderOccasionally' | 'reverseOrderExceptLast'
            - `otherOptionPlaceholder` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `validation` SurveyValidation: Optional element-level validation rules.
              - …
            - `displayType` 'list' | 'row' | 'dropdown'
          - SurveyNpsElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'nps', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `lowerLabel` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `upperLabel` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `isColorCodingEnabled` boolean
          - SurveyCtaElement: If `buttonExternal` is true, `buttonUrl` and `ctaButtonLabel` are required.
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'cta', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `buttonExternal` boolean
            - `buttonUrl` string
            - `ctaButtonLabel` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
          - SurveyRatingElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'rating', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `scale` 'number' | 'smiley' | 'star', required
            - `range` 3 | 4 | 5 | 6 | 7 | 10, required
            - `lowerLabel` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `upperLabel` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `isColorCodingEnabled` boolean
          - SurveyPictureSelectionElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'pictureSelection', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `allowMulti` boolean
            - `choices` SurveyPictureChoice[], required
              - …
            - `validation` SurveyValidation: Optional element-level validation rules.
              - …
          - SurveyDateElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'date', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `html` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `format` 'M-d-y' | 'd-M-y' | 'y-M-d', required
            - `validation` SurveyValidation: Optional element-level validation rules.
              - …
          - SurveyFileUploadElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'fileUpload', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `allowMultipleFiles` boolean, required
            - `maxSizeInMB` number
            - `allowedFileExtensions` string[]
            - `validation` SurveyValidation: Optional element-level validation rules.
              - …
          - SurveyCalElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'cal', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `calUserName` string, required
            - `calHost` string
          - SurveyMatrixElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'matrix', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `rows` SurveyChoice[], required
              - …
            - `columns` SurveyChoice[], required
              - …
            - `shuffleOption` 'none' | 'all' | 'exceptLast' | 'reverseOrderOccasionally' | 'reverseOrderExceptLast'
            - `validation` SurveyValidation: Optional element-level validation rules.
              - …
          - SurveyAddressElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'address', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `addressLine1` SurveyToggleInputConfig, required: Field config for address and contact info elements.
              - …
            - `addressLine2` SurveyToggleInputConfig, required: Field config for address and contact info elements.
              - …
            - `city` SurveyToggleInputConfig, required: Field config for address and contact info elements.
              - …
            - `state` SurveyToggleInputConfig, required: Field config for address and contact info elements.
              - …
            - `zip` SurveyToggleInputConfig, required: Field config for address and contact info elements.
              - …
            - `country` SurveyToggleInputConfig, required: Field config for address and contact info elements.
              - …
            - `validation` SurveyValidation: Optional element-level validation rules.
              - …
          - SurveyRankingElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'ranking', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `choices` SurveyChoice[], required
              - …
            - `otherOptionPlaceholder` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `shuffleOption` 'none' | 'all' | 'exceptLast' | 'reverseOrderOccasionally' | 'reverseOrderExceptLast'
            - `validation` SurveyValidation: Optional element-level validation rules.
              - …
          - SurveyContactInfoElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'contactInfo', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `firstName` SurveyToggleInputConfig, required: Field config for address and contact info elements.
              - …
            - `lastName` SurveyToggleInputConfig, required: Field config for address and contact info elements.
              - …
            - `email` SurveyToggleInputConfig, required: Field config for address and contact info elements.
              - …
            - `phone` SurveyToggleInputConfig, required: Field config for address and contact info elements.
              - …
            - `company` SurveyToggleInputConfig, required: Field config for address and contact info elements.
              - …
            - `validation` SurveyValidation: Optional element-level validation rules.
              - …
          - SurveyCsatElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'csat', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `scale` 'number' | 'smiley' | 'star', required
            - `range` 5, required
            - `lowerLabel` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `upperLabel` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `isColorCodingEnabled` boolean
          - SurveyCesElement
            - `id` string, required: Stable element id. Avoid spaces and reserved ids.
            - `type` 'ces', required
            - `headline` TranslatableText, required: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `required` boolean, required
            - `imageUrl` string
            - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `videoUrl` string
            - `isDraft` boolean: Draft marker used by the editor and future update rules.
            - `scale` 'number' | 'smiley' | 'star', required
            - `range` 5 | 7, required
            - `lowerLabel` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `upperLabel` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
            - `isColorCodingEnabled` boolean
      - `logic` SurveyBlockLogic[]
        - `id` string, cuid2, required
        - `conditions` SurveyConditionGroup, required
          - `id` string, cuid2, required
          - `connector` 'and' | 'or', required
          - `conditions` union[], required
            - union
              - …
        - `actions` SurveyLogicAction[], required
          - union: Logic action. Keep referenced ids stable: `calculate.variableId` points to a variable id, `requireAnswer.target` points to an element id, and `jumpToBlock.target` points to a block id or ending id.
            - SurveyCalculateAction: Updates a survey variable when the logic rule matches.
              - …
            - SurveyRequireAnswerAction: Requires an element/question to be answered before continuing.
              - …
            - SurveyJumpToBlockAction: Jumps to another block or ending when the logic rule matches.
              - …
      - `logicFallback` string, cuid2: Block or ending id used when no logic condition matches. Only valid when this same block has at least one `logic` rule; omit it for normal sequential flow.
      - `buttonLabel` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
      - `backButtonLabel` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
    - `endings` SurveyEnding[], required
      - union: Ending reached after the last block or a jump action. `type` selects the allowed shape; unsupported fields are rejected instead of ignored.
        - SurveyEndScreenEnding: Visual end screen displayed after survey completion.
          - `id` string, cuid2, required: Stable ending id. `jumpToBlock.target` may point to this id.
          - `type` 'endScreen', required
          - `headline` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
          - `subheader` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
          - `buttonLabel` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
          - `buttonLink` string
          - `imageUrl` string
          - `imageAltText` TranslatableText: Multilingual text map keyed by the emitted `languages[].code` values for this survey.
          - `videoUrl` string
          - `hideDefaultIcon` boolean: Hides the default checkmark icon rendered above the headline when the ending carries no image or video. Omit to keep the icon.
        - SurveyRedirectEnding: Redirects the respondent to a URL after survey completion. External redirects require the organization's external URL permission; otherwise write endpoints return `403 Forbidden`.
          - `id` string, cuid2, required: Stable ending id. `jumpToBlock.target` may point to this id.
          - `type` 'redirectToUrl', required
          - `url` string, uri, required: External redirect URL. Requires the organization's external URL permission.
          - `label` string: Optional internal label for redirect endings.
    - `hiddenFields` SurveyHiddenFields, required: 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`, `visitPagesViewed`, `visitUniquePagesViewed`, `visitTimeOnSite`, `visitEntryReferrer`, `visitUrls`, `openedByCreativeId`, `openedByCreativeName`. **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.
      - `enabled` boolean, required: Derived, not stored: `true` whenever the survey declares at least one hidden field. A value sent on create or update is ignored; to turn hidden fields off, remove them from `fieldIds`.
      - `fieldIds` string[]
    - `variables` SurveyVariable[], required
      - union: Survey variable. Variable ids are stable references used by logic and calculation actions. Variable names are human-readable labels and must be unique within the survey.
        - SurveyNumberVariable: Number variable. Used by `calculate` logic actions with numeric operators such as `add`, `subtract`, `multiply`, `divide`, or `assign`.
          - `id` string, cuid2, required: Stable variable id referenced from logic.
          - `name` string, required: Unique variable name. `pattern` is the charset of a *stored* name; a newly declared one is held to more than that, and the extra rules split into two groups that behave differently. **400 `forbidden_identifier`, grandfathered.** A new name must match `^[a-z][a-z0-9_]*$` (no leading digit or underscore) and must not take a reserved name — 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`) or an auto-captured system field name (`country`, `browser`, `deviceType`, …; `SurveyHiddenFields` carries the full list, and the two sets are the same there). Names the survey already declares are grandfathered against these, so re-sending an existing document never trips them. **400 `duplicate_identifier`, not grandfathered.** A variable name that collides case-insensitively with a hidden field id on the same survey. This is checked by reference validation over the whole merged document rather than against the incoming names, so a survey that already holds such a clash is refused on **every** patch — including one that touches neither collection — until one side is renamed.
          - `type` 'number', required
          - `value` number, required: Default numeric value.
        - SurveyTextVariable: Text variable. Used by `calculate` logic actions with text operators such as `assign` or `concat`.
          - `id` string, cuid2, required: Stable variable id referenced from logic.
          - `name` string, required: Unique variable name. `pattern` is the charset of a *stored* name; a newly declared one is held to more than that, and the extra rules split into two groups that behave differently. **400 `forbidden_identifier`, grandfathered.** A new name must match `^[a-z][a-z0-9_]*$` (no leading digit or underscore) and must not take a reserved name — 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`) or an auto-captured system field name (`country`, `browser`, `deviceType`, …; `SurveyHiddenFields` carries the full list, and the two sets are the same there). Names the survey already declares are grandfathered against these, so re-sending an existing document never trips them. **400 `duplicate_identifier`, not grandfathered.** A variable name that collides case-insensitively with a hidden field id on the same survey. This is checked by reference validation over the whole merged document rather than against the incoming names, so a survey that already holds such a clash is refused on **every** patch — including one that touches neither collection — until one side is renamed.
          - `type` 'text', required
          - `value` string, required: Default text value.
    - `distribution` SurveyDistribution: App-survey runtime/display settings. Only valid for `type: app`; rejected for link surveys. **Replacement semantics (destructive):** when `distribution` is provided on PATCH it fully replaces the stored object — any sub-field you omit is reset to its default, NOT preserved. In particular, omitting `triggers` removes ALL existing triggers, and omitting `displayOption` resets it to `displayOnce`. To change one setting, send the complete desired distribution. To leave distribution untouched, omit the whole `distribution` key.
      - `displayOption` 'displayOnce' | 'displayMultiple' | 'respondMultiple' | 'displaySome': How often the survey may be shown to a contact. `displaySome` shows it up to `displayLimit` times (or until the contact responds, whichever comes first).
      - `displayPercentage` number, nullable: Independent throttle: show the survey to only this percentage of triggered contacts. Optional and valid with any `displayOption`; null/omitted means no throttle (shown to everyone).
      - `displayLimit` integer, nullable: Maximum number of times the survey is shown to a single contact. Required (must be >= 1) when `displayOption` is `displaySome`; otherwise optional.
      - `recontactDays` integer, nullable: Days to wait before showing this survey again to the same contact. Null uses the workspace default.
      - `autoClose` integer, nullable: Seconds of inactivity after which the survey widget auto-closes. Null disables auto-close.
      - `keepEndingCardOpen` boolean: Keep the ending card on screen until the respondent closes the survey. When false, the survey widget closes 3 seconds after the ending card appears. Has no effect on a survey with no ending card (it closes immediately) or whose first ending redirects to a URL. Independent of `autoClose`.
      - `autoComplete` integer, nullable: Automatically stop collecting responses after this many completed responses. Null disables it.
      - `delay` integer: Seconds to wait after a trigger fires before showing the survey.
      - `showConditions` SurveyShowConditionGroup: A group of show conditions. `and` means every condition must hold; `or` means one is enough. A group can hold one more group, no deeper. An empty group is stored as `null`.
        - `id` string, required: Client-generated id (cuid2), unique within the survey's conditions.
        - `connector` 'and' | 'or', required
        - `conditions` union[], required
          - union
            - SurveyShowCondition: One check, read like a sentence: what to look at (`leftOperand`), how to compare (`operator`) and what to compare with (`rightOperand`). Text comparisons ignore upper and lower case. | `leftOperand.type` | `leftOperand.value` | Operators | | --- | --- | --- | | `page` | `currentUrl` (full URL, query included) | `pathIsAnyOf`, `pathIsNoneOf`, `containsAnyOf`, `containsNoneOf`, `equals`, `doesNotEqual`, `contains`, `doesNotContain`, `startsWith`, `endsWith` | | `page` | `pageReferrer`, `entryReferrer` (first page of the visit) | `equals`, `doesNotEqual`, `contains`, `doesNotContain`, `startsWith`, `endsWith`, `containsAnyOf`, `containsNoneOf` | | `page` | `queryParam` (name in `meta.key`) | `equals`, `doesNotEqual`, `contains`, `doesNotContain`, `startsWith`, `endsWith`, `isSet`, `isNotSet` | | `visit` | `pagesViewed`, `uniquePagesViewed`, `timeOnSite` (seconds) | `equals`, `isGreaterThan`, `isLessThan`, `isGreaterThanOrEqual`, `isLessThanOrEqual` | | `visit` | `visitedUrls` (pages seen in this visit, the current one included) | `includes`, `doesNotInclude` | | `device` | `deviceType` (`phone`, `tablet`, `desktop`), `browser` (`chrome`, `safari`, `firefox`, `edge`, `opera`, `samsung`, `other`) | `equals`, `doesNotEqual` | | `device` | `screenWidth` (browser window width, CSS px) | `equals`, `isGreaterThan`, `isLessThan`, `isGreaterThanOrEqual`, `isLessThanOrEqual` | `pathIsAnyOf` / `pathIsNoneOf` take a list of page paths, each compared exactly with the URL's path: case, a trailing slash, the query string and the `#hash` are ignored, and a full URL is reduced to its path. `/plans` matches `/plans?ref=email` but not `/plans/compare`. `containsAnyOf` / `containsNoneOf` take a list of fragments; a line passes when the URL contains it anywhere, so `/plans` also matches `/plans/compare`. `visitedUrls` takes one page path, compared exactly like a `pathIsAnyOf` line. `uniquePagesViewed` takes at most 200, the number of different pages a visit remembers. `isSet` / `isNotSet` take no `rightOperand`. A visit is one browser tab; if the browser blocks storage, visit conditions fail.
              - …
            - SurveyShowConditionGroup (recursive)
      - `triggers` SurveyTrigger[]: Action classes that trigger the survey. Every id must reference an existing workspace action class. On PATCH this list fully replaces the survey's triggers — omitting it (or sending `[]`) removes all existing triggers.
        - `actionClassId` string, cuid2, required: Id of an action class in the same workspace.
    - `targeting` SurveyTargeting: App-survey contact targeting. Only valid for `type: app`. `filters: []` targets everyone. Setting or changing non-empty filters requires the Contacts entitlement; otherwise create/patch returns 403. `attribute` filters reference workspace contact-attribute keys (discover them via `GET /api/v3/contact-attribute-keys`) and `segment` filters reference other segment ids — both are workspace-scoped resources you must obtain before constructing filters (an invalid key/id targets no one rather than erroring). See `SegmentFilter` for the per-`root.type` operator sets.
      - `filters` object[], required: Contact targeting filter tree. An empty array targets everyone. Each node joins the previous one via its `connector` (`and`/`or`; the first node's connector is null). A node's `resource` is either a single filter condition or a nested filter group (enabling parenthesized `and`/`or` logic).
        - `id` string, cuid2, required
        - `connector` 'and' | 'or' | 'null', nullable, required: Logical connector joining this node to the previous one. Null for the first node.
        - `resource` union, required: A single filter condition, or a nested filter group for grouped logic.
          - union: A single targeting condition. `root.type` selects the subject and determines the valid `qualifier.operator` set: `attribute` (a workspace contact-attribute key), `person` (a built-in person identifier such as `userId`/`email`), `segment` (membership in another segment), `device`, or `surveyInteraction` (how the contact interacted with surveys). Each variant is one member of this union; the matching member is chosen by `root.type`.
            - object: Matches on a workspace contact-attribute value.
              - …
            - object: Matches on a built-in person identifier.
              - …
            - object: Matches on membership in another segment.
              - …
            - object: Matches on the contact's device type.
              - …
            - object: Matches on how the contact interacted with surveys within a time window. `surveyIds` only names surveys the caller may see; ids of other surveys the segment targets are left out.
              - …
          - SegmentFilters (recursive)
    - `customCss` CustomCssInput, required: Custom CSS **source** as a caller writes it (ENG-3641). Both keys are required. `light` is base CSS that applies in both appearances; `dark` adds overrides on top of it when the survey renders dark. `null`, an empty string or whitespace means "no CSS" for that field. Source only: compiled output and the processor version are computed by the server on every write, and a request that supplies either is rejected. The combined source is limited to 100 000 UTF-8 bytes for a workspace and 20 000 for a survey; larger CSS is a **422** with error code `source_too_large`.
      - `light` string, nullable, required: Base CSS, applied in light and dark appearance.
      - `dark` string, nullable, required: Additional CSS applied only in dark appearance.
    - `visibility` 'restricted' | 'workspace', required: `restricted`: readable by the owner and the organisation's owners and managers only. The owner's access is conditional on their workspace access, level for level: they read the survey only while they can read the workspace, and edit it only while they can write to it — being the owner grants nothing the workspace does not. `workspace`: readable by everyone with access to the workspace — today's behaviour.
    - `owner` SurveyOwner, required: The authorization owner — the person whose restricted surveys these are. Distinct from `creator`, which is attribution only and is never rewritten. Display only, like `creator`: no user id is exposed, because `access.via === "owner"` already answers "is this mine" and `filter[owner][in]=me` filters server-side. Ownership transfer can add an identifier later, additively. Durable source: `Survey.ownerId` in PostgreSQL, projected to `survey#owner@user`; the graph never holds ownership alone, so a rebuild from an empty graph restores it.
      - `name` string, required
    - `access` SurveyAccess, required: Why **this caller** can see the survey, and whether they may change its visibility. Derived by the server per request; a rendering hint only — every mutation is re-authorised on the server.
      - `via` string, required: Why this caller can see the survey. Known values today: `workspace` (the survey is workspace-visible and the caller has workspace read — always the value for API keys), `owner` (restricted, the caller owns it), `organizationRole` (restricted, the caller reaches it only as an organisation owner or manager — the case that shows the admin banner). **Open set, deliberately not an enum**: named person and team sharing will add values, so clients treat an unknown string as "some other access path" and never branch exhaustively. Explanatory metadata, not authorization truth — the server re-authorises every call.
      - `canManageVisibility` boolean, required: Permission only: `true` when this caller holds `survey.change_visibility` — owner or organisation owner/manager, feature enabled for the organisation and deployment. It can be `true` while `allowedTargets` is empty (blockers, or no owner): it answers "may this person manage visibility at all", which is what shows or hides the controls; `allowedTargets` on `GET …/visibility` answers which transitions would succeed now. Stays `true` for an organisation manager on an ownerless restricted survey.

## Other responses

- `400`: Bad Request — malformed JSON, invalid query/body/params, duplicate name, or unsupported field.
- `401`: Not authenticated (no valid session or API key).
- `403`: Forbidden — no workspace access, or resource does not exist (404 not used; avoids existence leak).
- `409`: The survey changed since the `expectedUpdatedAt` you supplied. Nothing was written; `details` carries `expectedUpdatedAt` and the live `currentUpdatedAt`.
- `422`: The request is well-formed but could not be applied. Three distinct cases share this status; switch on the Problem-level `code`. `unprocessable_content` — the order is not a permutation of the survey's blocks. Unknown ids (`dangling_reference`), repeated ids (`duplicate_identifier`) and omitted blocks (`missing_required_field`, reported at `order`) are returned together, capped at 50 with a final entry saying how many were left out. Also used when the new order would *introduce* a forward reference — a recall of an answer not yet given, or a logic condition reading a later block — reported as `misordered_reference` at the stored-document path. An order that already contains such a reference stays reorderable; only newly created ones are refused. Likewise when the new order would *introduce* a loop in the conditional logic — a jump that now points back at a block whose next step leads to it again, so a respondent could never reach an ending — reported at the `logic` of each block a new looping step leaves. Moving a block in front of an existing loop is fine; reordering blocks inside one changes the loop and is refused. `stored_survey_invalid` — the stored survey cannot be reordered by id: it is a legacy question-based survey, exposes no v3 block list, or a block id occurs more than once. The request was not evaluated; `invalid_params[].name` points into the stored survey. `archivedAt` in `invalid_params` (no `code`) — the survey is archived; restore it first.
- `429`: Rate limit exceeded.
- `500`: Internal Server Error.

## Changes

- **2026-11-02** `25335c959a13`: 2 warning
  - added the new `row` enum value to the `data/allOf[subschema #1]/blocks/items/elements/items/oneOf[#/components/schemas/SurveyMultipleChoiceMultiElement]/allOf[subschema #2]/displayType` response property for the response status `200`
  - added the new `row` enum value to the `data/allOf[subschema #1]/blocks/items/elements/items/oneOf[#/components/schemas/SurveyMultipleChoiceSingleElement]/allOf[subschema #2]/displayType` response property for the response status `200`
- **2026-10-29** `82c0afd2df39`: 1 breaking
  - added `subschema #5: SurveyInteractionFilter` to the `data/allOf[subschema #1]/targeting/allOf[#/components/schemas/SurveyTargeting]/filters/items/resource/oneOf[#/components/schemas/SegmentFilter]/` response property `oneOf` list for the response status `200`
- **2026-10-28** `84820a01e550`: 21 warning
  - added the new `chart_in_use` enum value to the `code` response property for the response status `400`
  - added the new `chart_in_use` enum value to the `code` response property for the response status `401`
  - added the new `chart_in_use` enum value to the `code` response property for the response status `403`
  - added the new `chart_in_use` enum value to the `code` response property for the response status `409`
  - …17 more
- …earlier changes not shown

[Operation history](https://skmtc.dev/formbricks/apis/formbricks-api-v3/changes/api/v3/surveys/:surveyId/blocks/order/put.md)

---

[API](https://skmtc.dev/formbricks/apis/formbricks-api-v3.md) - [All operations](https://skmtc.dev/formbricks/apis/formbricks-api-v3/llms.txt) - [OpenAPI document](https://skmtc.dev/formbricks/apis/formbricks-api-v3/revisions/25335c959a13?raw)
