---
title: "Create a survey draft idempotently; identical retries return the original draft."
method: POST
path: "/v1/surveys"
---

# Create a survey draft idempotently; identical retries return the original draft.

`POST /v1/surveys`

## Request

- Base URL: `http://127.0.0.1:8080`
- URL: `http://127.0.0.1:8080/v1/surveys`
- Auth: HTTP bearer

## Headers

- `X-Likerts-Workspace` string

## Request body

- SurveyCreateInput
  - `idempotencyKey` string, required: Required by survey creation; omitted from draft update payloads.
  - `title` string, required
  - `questions` Question[], required
    - union: Question IDs must be unique within a survey; option IDs unique within each question; min must not exceed max. Backend validates these cross-field constraints. Expanded fields are permitted only on their respective types. preset, labels, minSelections or maxSelections require schemaVersion 2. visibleWhen, Other/exclusive choices or presentation require schemaVersion 3. Hidden answers are discarded before validation and persistence; hidden required questions are not required. ranking, matrix or constant_sum requires schemaVersion 5.
      - SingleChoiceQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'single_choice', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `options` Choice[], required
          - `id` string, required
          - `label` string, required
          - `other` object
            - `maxLength` integer, required
          - `exclusive` unknown
        - `preset` 'yes_no'
        - `presentation` 'dropdown'
      - MultipleChoiceQuestion: Selection bounds must satisfy effective minimum <= maximum <= option count. Effective minimum is max(minSelections or 0, required ? 1 : 0). Default maximum is option count. Optional answers may be omitted, but a supplied array must respect the bounds. Backend enforces these related-field constraints.
        - `id` string, required
        - `label` string, required
        - `type` 'multiple_choice', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `options` Choice[], required
          - `id` string, required
          - `label` string, required
          - `other` object
            - `maxLength` integer, required
          - `exclusive` unknown
        - `minSelections` integer
        - `maxSelections` integer
      - ScaleQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'scale', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `min` integer, required
        - `max` integer, required
        - `preset` 'nps'
        - `labels` object: Keys must be canonical integer strings within min/max; the backend enforces range membership.
        - `presentation` 'stars'
      - TextQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'text', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `maxLength` integer, required
      - NumberQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'number', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `min` number
        - `max` number
      - DateQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'date', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
      - RankingQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'ranking', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `options` Choice[], required
          - `id` string, required
          - `label` string, required
          - `other` object
            - `maxLength` integer, required
          - `exclusive` unknown
      - MatrixQuestion: rows × columns is limited to 200; semantic validation enforces unique IDs and plain columns without Other/exclusive.
        - `id` string, required
        - `label` string, required
        - `type` 'matrix', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `matrixMode` 'single' | 'multiple', required
        - `rows` PromptItem[], required
          - `id` string, required
          - `label` string, required
        - `columns` Choice[], required
          - `id` string, required
          - `label` string, required
          - `other` object
            - `maxLength` integer, required
          - `exclusive` unknown
      - ConstantSumQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'constant_sum', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `total` integer, required
        - `items` PromptItem[], required
          - `id` string, required
          - `label` string, required
  - `pages` SurveyPage[]
    - `id` string, required
    - `title` string
    - `questionIds` string[], required
    - `branches` PageBranch[]
      - `when` VisibilityCondition, required: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
        - `questionId` string, required
        - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
        - `value` union
          - string
          - number
      - `goToPageId` string, required

## Response `201`

Success

- Survey
  - `id` string, uuid, required
  - `revision` integer, required
  - `title` string, required
  - `questions` Question[], required
    - union: Question IDs must be unique within a survey; option IDs unique within each question; min must not exceed max. Backend validates these cross-field constraints. Expanded fields are permitted only on their respective types. preset, labels, minSelections or maxSelections require schemaVersion 2. visibleWhen, Other/exclusive choices or presentation require schemaVersion 3. Hidden answers are discarded before validation and persistence; hidden required questions are not required. ranking, matrix or constant_sum requires schemaVersion 5.
      - SingleChoiceQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'single_choice', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `options` Choice[], required
          - `id` string, required
          - `label` string, required
          - `other` object
            - `maxLength` integer, required
          - `exclusive` unknown
        - `preset` 'yes_no'
        - `presentation` 'dropdown'
      - MultipleChoiceQuestion: Selection bounds must satisfy effective minimum <= maximum <= option count. Effective minimum is max(minSelections or 0, required ? 1 : 0). Default maximum is option count. Optional answers may be omitted, but a supplied array must respect the bounds. Backend enforces these related-field constraints.
        - `id` string, required
        - `label` string, required
        - `type` 'multiple_choice', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `options` Choice[], required
          - `id` string, required
          - `label` string, required
          - `other` object
            - `maxLength` integer, required
          - `exclusive` unknown
        - `minSelections` integer
        - `maxSelections` integer
      - ScaleQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'scale', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `min` integer, required
        - `max` integer, required
        - `preset` 'nps'
        - `labels` object: Keys must be canonical integer strings within min/max; the backend enforces range membership.
        - `presentation` 'stars'
      - TextQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'text', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `maxLength` integer, required
      - NumberQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'number', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `min` number
        - `max` number
      - DateQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'date', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
      - RankingQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'ranking', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `options` Choice[], required
          - `id` string, required
          - `label` string, required
          - `other` object
            - `maxLength` integer, required
          - `exclusive` unknown
      - MatrixQuestion: rows × columns is limited to 200; semantic validation enforces unique IDs and plain columns without Other/exclusive.
        - `id` string, required
        - `label` string, required
        - `type` 'matrix', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `matrixMode` 'single' | 'multiple', required
        - `rows` PromptItem[], required
          - `id` string, required
          - `label` string, required
        - `columns` Choice[], required
          - `id` string, required
          - `label` string, required
          - `other` object
            - `maxLength` integer, required
          - `exclusive` unknown
      - ConstantSumQuestion
        - `id` string, required
        - `label` string, required
        - `type` 'constant_sum', required
        - `required` boolean
        - `visibleWhen` VisibilityCondition: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
          - `questionId` string, required
          - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
          - `value` union
            - string
            - number
        - `total` integer, required
        - `items` PromptItem[], required
          - `id` string, required
          - `label` string, required
  - `pages` SurveyPage[]
    - `id` string, required
    - `title` string
    - `questionIds` string[], required
    - `branches` PageBranch[]
      - `when` VisibilityCondition, required: One bounded predicate. answered/not_answered forbid value; other operators require it. equals/not_equals apply to scalar answers; includes/not_includes apply to multiple-choice selections. The backend validates reference existence, source compatibility, choice/range membership and an acyclic dependency graph. Comparison operators are false when the effective source answer is absent; answered trims strings.
        - `questionId` string, required
        - `operator` 'equals' | 'not_equals' | 'includes' | 'not_includes' | 'answered' | 'not_answered', required
        - `value` union
          - string
          - number
      - `goToPageId` string, required

## Other responses

- `400`: Invalid JSON, unknown fields or domain validation failure.
- `401`: Missing/invalid bearer credential, including wrong collection credential.
- `403`: The credential scope, membership or role does not permit this operation.
- `409`: The idempotency key was already used with a different payload.
- `413`: Request body exceeds 65536 bytes.
- `415`: Content-Type must be application/json.
- `429`: Admission or collection rate limit reached. Honor Retry-After in seconds; admission usually returns1, the collection minute window returns60.
- `500`: Internal failure; do not assume a write failed. Retry only with its original idempotency key and payload.
- `503`: Distributed request admission is temporarily unavailable. No protected handler ran; honor Retry-After.

---

[API](https://skmtc.dev/likerts/apis/likerts-development-api.md) · [All operations](https://skmtc.dev/likerts/apis/likerts-development-api/llms.txt) · [OpenAPI document](https://skmtc.dev/likerts/apis/likerts-development-api/revisions/c583fa096c07?raw)
