> ## Documentation Index
> Fetch the complete documentation index at: https://docs.repdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Auto Save

> # Description

Saves the project. The response will have the errors found on it.

* **Note**:
You must always send the entire project structure in the request payload.

# Payload

```json
{
    "lastResponsesRecreationDate": "string",
    "id": "string",
    "title": "string",
    "isLive": "boolean",
    "hasSignatureConfirmation": "boolean",
    "status": "string",
    "hasConditionalDisplay": "boolean",
    "showLocked": "boolean",
    "isPipingFromQuestionEnabled": "boolean",
    "isSkipLogicEnabled": "boolean",
    "isTranslationEnabled": "boolean",
    "languages": "array",
    "customization": "object",
    "logo": "object",
    "survey": "object",
    "conceptTestPerUser": "object",
    "conceptTestsToDisplay": "object"
}
```
where:

- `lastResponsesRecreationDate`: Date of the last time someone recreated the data of the project in the format `YYYY-MM-DDTHH:mm:ss.SSSZ`.
- `id`: Id of the project.
- `title`: Name of the project.
- `isLive`: Whether the project is live or not.
- `hasSignatureConfirmation`: Whether the project has the signature configuration enabled or not.
- `status`: Status of the project. Possible values are:
    - `draft`
    - `published`
- `hasConditionalDisplay`: Whether the project contains conditional display or not.
- `showLocked`: Whether the build section of the project should be shown locked or not. If the survey already has responses, `showLocked` will always be `true`.
- `isPipingFromQuestionEnabled`: Whether piping from questions is enabled or not.
- `isSkipLogicEnabled`: Whether skip logic is enabled or not.
- `isTranslationEnabled`: Whether translations are enabled or not.
- `languages`: An array of `string` with the country codes of the languages available in the project.

### Customization

The customization object defines the customization options of the project. It has the following structure:

```json
{
    "backgroundColor": "string",
    "foregroundColor": "string",
    "mobilePaging": "string",
    "paging": "string",
    "showNumbers": "boolean",
    "showTitle": "boolean",
    "disableBackButton": "boolean",
    "progressBar": {
        "enabled": "boolean",
        "type": "string",
    },
    "question": {
        "font": "string",
        "color": "string",
        "align": "string"
    },
    "answer": {
        "font": "string",
        "color": "string",
        "align": "string"
    },
    "nextPreviousButton": {
        "type": "string",
    }
}
```

- `backgroundColor`: Hex color code for the survey's background.
- `foregroundColor`: Hex color code of buttons shown in the survey.
- `paging`: The type of paging used for the desktop version of the survey. Possible values are:
    - `none`
    - `page`
    - `question`
- `mobilePaging`: The type of paging used for the mobile version of the survey. The values are the same of `paging`.
- `showNumbers`: Whether the survey should show question numbers or not.
- `showTitle`: Whether to show the name of the project in the survey or not.
- `disableBackButton`: Whether to disable the back button or not.
- `progressBar`
    - `enabled`: Whether the progress bar is shown or not in the survey.
    - `type`: The type of progress bar. Possible values are:
        - `percent`
        - `bar`
        - `simple`
- `question`
    - `font`: Font of the questions titles. Defaults to `Source Sans Pro`.
    - `color`: Color of the font of the questions titles.
    - `align`: Alignment of the questions titles.
- `answer`
    - `font`: Font of the questions' options. Defaults to `Source Sans Pro`.
    - `color`: Color of the font of the questions' options.
    - `align`: Alignment of the questions' options.
- `nextPreviousButton`
    - `type`: Type of the previous button. Possible values are:
        - `default`
        - `simple`
        - `bigger`

## Logo

The logo of the project is an object with the following structure:

```json
{
    "url": "string"
}
```

- `url`: Url of the logo of the project. Can be base64 or regular url.

#### Note

If base64 string is posted then the api saves the image and saves the url.

If a normal url is posted then the api just saves it.

## Survey

The structure of the survey object is the following:

```json
{
    "endOfSurveyText": "string",
    "pages": "array",
    "termsAndConditions": "string",
    "welcomeText": "string"
}
```

- `welcomeText`: Text of the welcome page of the survey.
- `termsAndConditions`: Text of the terms and conditions of the survey.
- `endOfSurveyText`: Text of the thank you page of the survey.

## Pages

Pages is an array of objects. Each page contains the following information:

```json
[
    {
        "frontendId": "number",
        "position": "number",
        "randomizeItems": "boolean",
        "title": "string",
        "type": "string",
        "items": "array",
    }
]
```

- `frontendId`: The id of the page.
- `position`: Position of the page in the survey. For example, if it is the first page, then `position` will be equal to `1`.
- `randomizeItems`: Whether the items inside the page should be randomized or not.
- `title`: The title of the page.
- `type`: The type of item. For pages, it will always be `page`.

## Items

The items are the questions inside the pages. Each item contains the following common structure:

```json
{
    "_id": "string",
    "config": {
        "isRequired": "boolean",
        "allowNA": "boolean",
    },
    "frontendId": "number",
    "pageFrontendId": "number",
    "position": "number",
    "title": "string",
    "type": "string",
    "subtype": "string",
    "options": "array",
    "rows": "array",
    "conditionalDisplay": "object"
}
```

- `_id`: A unique id of the item. Its purpose is to identify the item in the Analysis dashboard.
- `config`
    - `isRequired`: Whether the item is required or not.
    - `allowNA`: Whether the item accepts N/A as an answer or not.
- `frontendId`: An id set in the frontend to identify the item.
- `pageFrontendId`: The id of the page that containing the item.
- `position`: The position of the item in the survey.
- `title`: The title of the item. All items have this field except for the Text block.
- `type`: The type of the item. Possible values are:
    - `multipĺe`
    - `input`
    - `scale`
    - `scaleNumeric`
    - `grid`
    - `conjoint`
    - `rank`
    - `decorator`
    - `pageBreak`
    - `promoter`
    - `constant-sum`
    - `date`
    - `contact-info`
- `subtype`: The subtype of the item. Possible values are:
    - `text`
    - `number`
    - `slider`
    - `icon`
    - `ìmage`
    - `info`
    - `information`
    - `separator`
    - `link`
    - `concept-test`
    - `max-diff`
    - `max-diff-experiment`
    - `nps`
    - `max-diff-aggregated`

For each type of item, there can be more specific properties.

## Options

Options is an array of objects containing the options for these types of questions:

- Multiple choice
- Multiple choice image
- Grid / Rating scale
- Rank order
- Max diff basic
- Max diff experiment
- Conjoint

It has the following structure:

```json
[
    {
        "frontendId": "number",
        "isOther": "boolean",
        "itemId": "number",
        "label": "string",
        "position": "number",
        "isNoneOfAbove": "boolean",
        "autopopulated": "boolean",
        "sourceId": "number",
        "url": "string"
    }
]
```

- `frontendId`: An id set in the frontend to identify the option.
- `isOther`: Whether the option is the "other" option or not.
- `itemId`: Id of the item containing the option.
- `label`: The label of the option.
- `position`: The position of the option relative to the item.
- `isNoneOfAbove`: Whether the option is the "none of above" option or not.
- `autopopulated`: Whether the option comes from another source or not.
- `sourceId`: The frontendId from the option this was populated with if `autopopulated` is set to `true`.
- `url`: The URL of the image if the option contains one.

## Rows

Rows is an array of objects containing the options for these types of questions:

- Grid / Rating scale
- NPS
- Text entry
- Numeric entry
- Constant sum
- Max diff basic
- Max diff experiment
- Conjoint

It has the same structure as options.

## Conditional display

Conditional display is an object with the following structure:

```json
{
    "visibleByDefault": "boolean",
    "rules": "array",
}
```


where:

- `visibleByDefault`: Whether the question is visible by default or not.
- `rules`: Array with the following structure:

```json
[
    {
        "conditions": {
            "all": "array"
        },
        "event": {
            "type": "string",
            "params": {
                "frontendIds": "array"
            }
        }
    }
]
```

where:

- `event`
    - `type`: Type of event. Possible values are:
        - `question`
        - `option`
        - `concept`
        - `row`
        - `concept-test`
    - `params`
        - `frontendIds`: It is an array of ids. When `type` is `option`, it is an array of option ids. When `type` is `row`, it is an array of row ids. When `type` is `concept`, it is an array of concept ids. When `type` is either `question` or `concept-test`, this field is not present.
- `all`: Array of objects with the following structure:

```json
[
    {
        "fact": "string",
        "operator": "string",
        "path": "string",
        "value": "number|array|object"
    }
]
```

where:

- `fact`: It is the id of the question that appears in the condition block.
- `operator`: The operator that is going to be used in the rule. Possible values are:
    - `equal`
    - `notEqual`
    - `lessThan`
    - `lessThanInclusive`
    - `greaterThan`
    - `greaterThanInclusive`
    - `betweenExclusive`
    - `betweenInclusive`
    - `arrayContainsAll`
    - `arrayDoesNotContainstAll`
    - `arrayContainsAny`
- `path`: Whether the rule needs to check a single value or multiple values. Possible values are:
    - `.value`
    - `.values`
- `value`: When we are comparing a single value, `value` will be a number. When we are comparing multiple values, `value` will be an array of ids. When we are comparing a minimum and a maximum, it will be an object with the following structure:

    ```json
    {
        "min": "number",
        "max": "number"
    }
    ```

    When we are comparing rows and options, it will have the followin structure:

    ```json
    {
        "option": "number",
        "row": "number"
    }
    ```

## Multiple choice

For multiple choice questions, we have that:

- `type`: `multiple`
- `subtype`: `text`

And the specific configuration is:

```json
{
    "config": {
        "allowMultipleSelection": "boolean",
        "anchoredOption": "array",
        "columnCustomization": "string|number",
        "displayAs": "string",
        "exclusiveOptions": "array",
        "maxResponses": "number",
        "minResponses": "number",
        "randomize": "boolean",
        "image": "string",
        "allowOther": "boolean",
        "allowNoneOfAbove": "boolean",
        "noneOfAboveFrontendId": "number"
    }
}
```

where:

- `allowMultipleSelection`: Whether the question allows multiple selection or not.
- `maxResponses`: Maximum number of responses if `allowMultipleSelection` is set to `true`.
- `minResponses`: Minimum number of responses if `allowMultipleSelection` is set to `true`.
- `exclusiveOptions`: An array of the ids of the options that are exclusive. If a user selects an option from here, the question is considered to be answered and will ignore the `minResponses` configuration.
- `columnCustomization`: The number of columns shown for this question. If the value is `auto`, then the type of the value is `string`. Otherwise, it is a `number`. Possible values are:
    - `auto`
    - `1`
    - `2`
    - `3`
- `displayAs`: Whether the question should be displayed as a list or as a dropdown. Possible values are:
    - `list`
    - `dropdown`
- `randomize`: Whether the question should randomize its options or not.
- `anchoredOption`: An array of the ids of the options that are anchored when `randomize` is set to `true`. These options are always shown at the end of the list of options of the question and are not randomized.
- `image`: The URL of the title image (if any).
- `allowOther`: Whether the item accepts "Other" as an answer or not.
- `allowNoneOfAbove`: Whether the item accepts "None of above" as an answer or not.
- `noneOfAboveFrontendId`: Id of the "None of above" option if `allowNoneOfAbove` is set to `true`.

## Multiple choice image

For multiple choice questions, we have that:

- `type`: `multiple`
- `subtype`: `image`

The configuration object is the same as the Multiple choice questions' and, additionally, contains the following specific properties:

```json
{
    "config": {
        "imageSize": "string",
        "showTitles": "boolean",
        "fitCover": "boolean"
    }
}
```

- `imageSize`: The size of the image. Possible values are:
    - `small`
    - `medium`
    - `large`
- `showTitles`: Whether the titles of the images should be shown or not.
- `fitCover`: If set to `false`, the image is not going to keep its aspect ratio.

## Grid / Rating scale

For grid, we have that:

- `type`: `grid`

And the specific configuration object is:

```json
{
    "config": {
        "allowMultipleSelectionPerRow": "boolean",
        "maxResponsesPerRow": "number",
        "minResponsesPerRow": "number",
        "displayAs": "string",
        "autoPopulateData": "string",
        "displayNaColumn": "boolean",
        "randomize": "boolean",
        "randomizeColumns": "boolean",
        "requires": {
            "type": "string",
            "value": "number",
            "min": "number",
            "max": "number"
        },
        "rowPerPage": "boolean",
        "shouldForceRanking": "boolean"
    }
}
```

where:

- `allowMultipleSelectionPerRow`: Whether the user can select multiple choices for each row or not.
- `maxResponsesPerRow`: Maximum number of responses if `allowMultipleSelectionPerRow` is set to `true`.
- `minResponsesPerRow`: Minimum number of responses if `allowMultipleSelectionPerRow` is set to `true`.
- `displayAs`: Whether the question should be displayed as multiple rows or a single row. Possible values are:
    - `multipleRows`
    - `singleRow`
- `autoPopulateData`: Whether the rows come from another source or not.
- `displayNaColumn`: Whether an additional N/A column should be displayed or not.
- `randomize`: Whether rows should be randomized or not.
- `randomizeColumns`: Whether columns should be randomized or not.
- `requires`
    - `type`: Whether the question requires to answer all rows or not. Possible values are:
        - `all`
        - `exactly`
        - `atLeast`
        - `atMost`
        - `range`
    - `value`: If `type` is `exactly`, `atLeast` or `atMost`, then a value must be specified.
    - `min`: If `type` is `range`, then a minimum number of rows to answer must be set.
    - `max`: If `type` is `range`, then a maximum number of rows to answer  must be set.
- `rowPerPage`: Whether we should display the question by row or not.
- `shouldForceRanking`: Whether we should force ranking (one response per column) or not.

## NPS

For NPS, we have that:

- `type`: `grid`
- `subtype`: `nps`

The configuration object is the same as the Grids' and, additionally, contains the following specific properties:

```json
{
    "config": {
        "allowComments": "boolean",
        "leftLabel": "string",
        "rightLabel": "string",
    }
}
```

where:

- `allowComments`: Whether NPS allows comments or not.
- `leftLabel`: The label of left anchor.
- `rightLabel`: The label of the right anchor.

We also force the following properties inside `config`:

- `displayAs`: `promoter`
- `requires`
    - `type`: `all`

## Max diff basic

For Max diff basic, we have that:

- `type`: `grid`
- `subtype`: `max-diff`

The configuration object is the same as the Grids', with the particularity that we force the following values inside `config`:

- `allowMultipleSelectionPerRow`: `false`
- `displayAs`: `multipleRows`
- `requires`
    - `type`: `exactly`
    - `value`: `2`
- `shouldForceRanking`: `true`

## Max diff experiment

For Max diff experiment, we have that:

- `type`: `grid`
- `subtype`: `max-diff-experiment`

The configuration object is the same as the Grids' and, additionally, contains the following specific properties:

```json
{
    "config": {
        "numberOfSets": "number",
        "setSize": "number"
    }
}
```

where:

- `numberOfSets`: The number of sets to be shown in the survey.
- `setSize`: The size of each set.

We also force the following properties inside `config`:

- `allowMultipleSelectionPerRow`: `false`
- `displayAs`: `multipleRows`
- `requires`
    - `type`: `exactly`
    - `value`: `2`
- `shouldForceRanking`: `true`

## Rank order

For Rank order, we have that:

- `type`: `rank`

And the specific configuration object:

```json
{
    "config": {
        "randomize": "boolean",
    }
}
```

where:

- `randomize`: Whether the options are randomized or not.

## Scale

When the scale is shown as slider, we have that:

- `type`: `scale`
- `subtype`: `slider`

And when the scale is shown as rating, we have that:

- `type`: `scale`
- `subtype`: `icon`

And the specific configuration object is:

```json
{
    "config": {
        "granularity": "number",
        "leftLabel": "string",
        "rightLabel": "string",
        "minValue": "number",
        "maxValue": "number"
    }
}
```

where:

- `granularity`: The granularity of the scale. If `subtype` is `icon`, possible values are:
    - 1
    - 0.5
- `leftLabel`: The far left side of scale answer. Only available when `subtype` is `slider`.
- `rightLabel`: The far right side of scale answer. Only available when `subtype` is `slider`.
- `minValue`: The minimum value of the scale.
- `maxValue`: The maximum value of the scale.

## Text entry

For text entry, we have that:

- `type`: `input`
- `subtype`: `text`

And the specific configuration object is:

```json
{
    "config": {
        "maxLength": "number",
        "multipleInputs": "boolean"
    }
}
```

where:

- `maxLength`: If the short response option is enabled, then `maxLength` is equal to `250`. Otherwise, its value is `0`.
- `multipleInputs`: Whether we should allow multiple inputs or not.

> Note: when `multipleInputs` is set to `true`, oher items of `type` equal to `input` and `subtype` equal to `text` are going to be created.

## Numeric entry

For text entry, we have that:

- `type`: `input`
- `subtype`: `number`

And the specific configuration object is:

```json
{
    "config": {
        "minValue": "number",
        "maxValue": "number",
        "allowDecimals": "boolean",
        "multipleInputs": "boolean",
        "maxLength": "number"
    }
}
```

where:

- `minValue`: The minimum number allowed.
- `maxValue`: The maximum number allowed.
- `allowDecimals`: Whether decimals are allowed or not.
- `multipleInputs`: Whether multiple inputs should be allowed or not.

> Note: contrary to text entry questions, other items **are not** created when `multipleInputs` is set to `true`.

## Constant sum

For Constant sum, we have that:

- `type`: `constant-sum`

And the specific configuration object is:

```json
{
    "config": {
        "validationType": "string",
        "mustTotalValue": "number",
        "minSumValue": "number",
        "maxSumValue": "number",
        "randomize": "boolean"
    }
}
```

where:

- `validationType`: Validation type of the total sum. Possible values are:
    - `mustTotal`
    - `range`
- `mustTotalValue`: Total sum value when `validationType` is `mustTotal`.
- `minSumValue`: Minimum total sum when `validationType` is `range`.
- `maxSumValue`: Maximum total sum when `validationType` is `range`.
- `randomize`: Whether the rows are randomized or not.

## Text block

For Text block, we have that:

- `type`: `decorator`
- `subtype`: `info`

For this question, we have other things that change besides the configuration object:

```json
{
    "text": "string"
}
```

- `text`: The text to be shown in the survey.

## Date

For Date, we have that:

- `type`: `date`

And the specific configuration object is:

```json
{
    "config": {
        "maxYear": "number",
        "minYear": "number"
    }
}
```

where:

- `maxYear`: The maximum year to be shown in the survey.
- `minYear`: The minimum year to be shown in the survey.

## Contact info

For Contact info, we have that:

- `type`: `contact-info`

And the specific configuration object is:

```json
{
    "config": {
        "showAddressLine1": "boolean",
        "showAddressLine2": "boolean",
        "showCountry": "boolean",
        "showEmail": "boolean",
        "showFirstName": "boolean",
        "showLastName": "boolean",
        "showPhone": "boolean",
        "showUsState": "boolean",
        "showZipCode": "boolean",
        "countryMultipleChoiceId": "number",
        "stateMultipleChoiceId": "number"
    }
}
```

where:

- `showAddressLine1`: Whether the address line 1 should be asked in the survey or not.
- `showAddressLine2`: Whether the address line 2 should be asked in the survey or not.
- `showCountry`: Whether the country should be asked in the survey or not.
- `showEmail`: Whether the email should be asked in the survey or not.
- `showFirstName`: Whether the first name should be asked in the survey or not.
- `showLastName`: Whether the last name should be asked in the survey or not.
- `showUsState`: Whether the US State should be asked in the survey or not.
- `showZipCode`: Whether the zip code should be asked in the survey or not.
- `countryMultipleChoiceId`: If `showCountry` is set to `true`, another item (more specifically, a multiple choice question where the options are the countries) is created automatically. This field represents the id of that new item.
- `stateMultipleChoiceId`: If `showUsState` is set to `true`, another item (more specifically, a multiple choice question where the options are the US states) is created automatically. This field represents the id of that new item.

## Conjoint

For conjoint, we have that:

- `type`: `conjoint`

And the specific properties of this item will be:

```json
{
    "config": {
        "numberOfCardsPerSet": "number",
        "numberOfSets": "number",
        "allowNone": "boolean",
    },
    "description": "string",
    "rows": "array",
    "options": "array",
}
```

where:

- `config`
    - `numberOfCardsPerSet`: The number of cards per set to be shown in the survey.
    - `numberOfSets`: The number of sets to be shown in the survey.
    - `allowNone`: Whether we should allow the "None" card or not.
- `description`: The description text of the conjoint experiment.

## Conjoint rows

Conjoint rows correspond to the attributes of the conjoint experiment. They have the same structure as the common `rows` array of objects, with the following additional properties:

```json
[
    {
        "allowLevelImages": "boolean",
        "enableRangeLevels": "boolean",
        "levels": "array"
    }
]
```

where:

- `allowLevelImages`: Whether images are allowed in the levels of the attribute or not.
- `enableRangeLevels`: Whether we should add a range of levels instead or not.
- `levels`: An array containing the ids of the levels. If `enableRangeLevels` is set to `true`, then `levels` will be an empty array.

## Conjoint options

Conjoint options correspond to the levels of the conjoint experiment. They have the same structure as the common `options` array of objects, with the following additional property:

```json
[
    {
        "attributeId": "number"
    }
]
```

where:

- `attributeId`: Id of the corresponding attribute for the level.

## Concept test

The concept test works very differently to other type of questions. For each concept inside the concept test, a new `page` object is created. As usual, this page will have `items`, which is again an array of objects. However, the first item will contain the information of the concept itself. It will have the same structure as a normal item, but with additional properties. First of all, we will have that:

- `type`: `decorator`
- `subtype`: `concept-test`

And the specific properties of this item will be:

```json
{
    "config": {
        "type": "string",
        "url": "string",
        "title": "string",
        "hideLinkAfterShow": "boolean",
        "timeToDisplay": "number",
        "videoId": "string",
        "thumbnailUrl": "string"
    },
    "children": "number",
    "conceptTestId": "number",
    "conceptTitle": "string",
    "randomizeConcept": "boolean",
    "showConceptsNotDisplayed": "boolean"
}
```

where:

- `config`
    - `type`: Type of concept to be shown. Possible values are:
        - `imageUpload`
        - `youtubeVideo`
        - `externalLink`
        - `audio`
    - `url`: URL of the image, video or external link.
    - `title`: Name of the concept (if any).
    - `hideLinkAfterShow`: Whether the link of the resource should be hidden or not after it was shown in the survey.
    - `timeToDisplay`: The number of seconds the image, video or external link should be displayed in the survey.
    - `videoId`: Id of the YouTube video. Only present if `type` is `youtubeVideo`.
    - `thumbnailUrl`: URL of the external link. Only present if `type` is `externalLink`.
- `children`: Number of questions inside the concept test.
- `conceptTestId`: Id of the concept.
- `conceptTitle`: Name of the concept test question that contains the current concept.
- `randomizeConcept`: Whether the concepts should be randomized or not.
- `showConceptsNotDisplayed`: Whether we should show concepts that are not displayed or not.

## conceptTestPerUser

The `conceptTestPerUser` object, which is not inside the `survey` object, contains information about how many concepts are going to be shown to the user. It will be an object where the keys are the `conceptTestId` of each concept test present in the survey and the value is the number of concept tests per user.

```json
{
    "[conceptTestId]": "number"
}
```

### Page jumps

For page jumps (Always skip), we have the following structure:

```json
{
    "[pageFrontendId]": {
        "pageJump": {
            "jumpType": "string",
            "skipTo": "string"
        }
    }
}
```

where:

- `pageFrontendId`: Id of the page that contains the skip logic rule. If we are applying skip logic rules to a whole page, then this will be the id of the first question of that page.
- `jumpType`: The type of jump. Possible values are:
    - `DISQUALIFY`
    - `END_OF_SURVEY`
    - `PAGE`
- `skipTo`: Id of the page we want to jump to. This field is present only if `jumpType` is `PAGE`.

### Conditional and unconditional skips

For conditional skips, we have the following structure:

```json
{
    "[pageFrontendId]": {
        "logic": {
            "[questionFrontendId]": {
                "type": "string",
                "jumps": "array"
            }
        }
    }
}
```

where:

- `pageFrontendId`: Id of the page that contains questions with skip logic rules.
- `questionFrontendId`: Id of the question with skip logic rules.
- `type`: The type of the skip. Possible values are:
    - `UNCONDITIONAL`
    - `BY_OPTION`
    - `BY_EXPRESSION`
    - `BY_GRID_SELECTION`

Now, `jumps` is an array of objects containing the logic of the skip.

```json
[
    {
        "jumpType": "string",
        "skipTo": "string",
        "areOptionsSelected": "boolean",
        "logicOperator": "string",
        "options": "array",
        "selections": "array",
        "expressions": "array",
    }
]
```

where:

- `jumpType`: It is the type of of jump. The possible values are the same for the page jumps.
- `skipTo`: The id of the page we want to skip to if `jumpType` is `PAGE`.
- `areOptionsSelected`: Whether the options specified in the `options` array are selected or not.
- `logicOperator`: The operator to be used. Possible values are:
    - `OR`
    - `AND`
- `options`: An array of ids of options where the logic rule is being applied to. Only available if `type` is `BY_OPTION`.
- `selections`: An array of objects containing the ids of the options and rows where the logic rule is being applied to. Only available if `type` is `BY_GRID_SELECTION`.
- `expressions`: An array of expressions for when the `type` of skip is `BY_EXPRESSION`.

# Response

## 200 OK

```json
{
    "customization": {
        "backgroundColor": "string",
        "foregroundColor": "string",
        "paging": "none|page|question",
        "mobilePaging": "none|page|question",
        "showNumbers": "boolean",
        "showTitle": "boolean",
        "disableBackButton": "boolean",
        "progressBar": {
            "enabled": "boolean",
            "type": "percent|simple|numeric"
        },
        "question": {
            "font": "string",
            "color": "string",
            "align": "string"
        },
        "answer": {
            "font": "string",
            "color": "string",
            "align": "string"
        },
        "nextPreviousButton": {
            "type": "default|simple|bigger"
        }
    },
    "logo": {
        "url": "string"
    },
    "survey": {
        "endOfSurveyText": "string",
        "pages": "array",
        "termsAndConditions": "string",
        "welcomeText": "string"
    },
    "id": "string",
    "title": "string",
    "isSkipLogicEnabled": "boolean",
    "isTranslationEnabled": "boolean",
    "isPipingFromQuestionEnabled": "boolean",
    "isLive": "boolean",
    "hasSignatureConfirmation": "boolean",
    "hasConditionalDisplay": "boolean",
    "lastResponsesRecreationDate": "YYYY-MM-DDTHH:mm:ss.SSSZ",
    "showLocked": "boolean",
    "languages": ["string"],
    "conceptTestsPerUser": object,
    "audienceId": null,
    "conceptTestsToDisplay": object,
    "criteria": object,
    "projectVariables": object,
    "catalog": object
}
```

where:

See payload description.

## 401 Unauthorized

> The user doesn't have permissions.

## 500 Internal Server Error

> Error occurred while processing the request.

# Description

Saves the project. The response will have the errors found on it.

* **Note**:
  You must always send the entire project structure in the request payload.

# Payload

```json theme={null}
{
    "lastResponsesRecreationDate": "string",
    "id": "string",
    "title": "string",
    "isLive": "boolean",
    "hasSignatureConfirmation": "boolean",
    "status": "string",
    "hasConditionalDisplay": "boolean",
    "showLocked": "boolean",
    "isPipingFromQuestionEnabled": "boolean",
    "isSkipLogicEnabled": "boolean",
    "isTranslationEnabled": "boolean",
    "languages": "array",
    "customization": "object",
    "logo": "object",
    "survey": "object",
    "conceptTestPerUser": "object",
    "conceptTestsToDisplay": "object"
}
```

where:

* `lastResponsesRecreationDate`: Date of the last time someone recreated the data of the project in the format `YYYY-MM-DDTHH:mm:ss.SSSZ`.
* `id`: Id of the project.
* `title`: Name of the project.
* `isLive`: Whether the project is live or not.
* `hasSignatureConfirmation`: Whether the project has the signature configuration enabled or not.
* `status`: Status of the project. Possible values are:
  * `draft`
  * `published`
* `hasConditionalDisplay`: Whether the project contains conditional display or not.
* `showLocked`: Whether the build section of the project should be shown locked or not. If the survey already has responses, `showLocked` will always be `true`.
* `isPipingFromQuestionEnabled`: Whether piping from questions is enabled or not.
* `isSkipLogicEnabled`: Whether skip logic is enabled or not.
* `isTranslationEnabled`: Whether translations are enabled or not.
* `languages`: An array of `string` with the country codes of the languages available in the project.

### Customization

The customization object defines the customization options of the project. It has the following structure:

```json theme={null}
{
    "backgroundColor": "string",
    "foregroundColor": "string",
    "mobilePaging": "string",
    "paging": "string",
    "showNumbers": "boolean",
    "showTitle": "boolean",
    "disableBackButton": "boolean",
    "progressBar": {
        "enabled": "boolean",
        "type": "string",
    },
    "question": {
        "font": "string",
        "color": "string",
        "align": "string"
    },
    "answer": {
        "font": "string",
        "color": "string",
        "align": "string"
    },
    "nextPreviousButton": {
        "type": "string",
    }
}
```

* `backgroundColor`: Hex color code for the survey's background.
* `foregroundColor`: Hex color code of buttons shown in the survey.
* `paging`: The type of paging used for the desktop version of the survey. Possible values are:
  * `none`
  * `page`
  * `question`
* `mobilePaging`: The type of paging used for the mobile version of the survey. The values are the same of `paging`.
* `showNumbers`: Whether the survey should show question numbers or not.
* `showTitle`: Whether to show the name of the project in the survey or not.
* `disableBackButton`: Whether to disable the back button or not.
* `progressBar`
  * `enabled`: Whether the progress bar is shown or not in the survey.
  * `type`: The type of progress bar. Possible values are:
    * `percent`
    * `bar`
    * `simple`
* `question`
  * `font`: Font of the questions titles. Defaults to `Source Sans Pro`.
  * `color`: Color of the font of the questions titles.
  * `align`: Alignment of the questions titles.
* `answer`
  * `font`: Font of the questions' options. Defaults to `Source Sans Pro`.
  * `color`: Color of the font of the questions' options.
  * `align`: Alignment of the questions' options.
* `nextPreviousButton`
  * `type`: Type of the previous button. Possible values are:
    * `default`
    * `simple`
    * `bigger`

## Logo

The logo of the project is an object with the following structure:

```json theme={null}
{
    "url": "string"
}
```

* `url`: Url of the logo of the project. Can be base64 or regular url.

#### Note

If base64 string is posted then the api saves the image and saves the url.

If a normal url is posted then the api just saves it.

## Survey

The structure of the survey object is the following:

```json theme={null}
{
    "endOfSurveyText": "string",
    "pages": "array",
    "termsAndConditions": "string",
    "welcomeText": "string"
}
```

* `welcomeText`: Text of the welcome page of the survey.
* `termsAndConditions`: Text of the terms and conditions of the survey.
* `endOfSurveyText`: Text of the thank you page of the survey.

## Pages

Pages is an array of objects. Each page contains the following information:

```json theme={null}
[
    {
        "frontendId": "number",
        "position": "number",
        "randomizeItems": "boolean",
        "title": "string",
        "type": "string",
        "items": "array",
    }
]
```

* `frontendId`: The id of the page.
* `position`: Position of the page in the survey. For example, if it is the first page, then `position` will be equal to `1`.
* `randomizeItems`: Whether the items inside the page should be randomized or not.
* `title`: The title of the page.
* `type`: The type of item. For pages, it will always be `page`.

## Items

The items are the questions inside the pages. Each item contains the following common structure:

```json theme={null}
{
    "_id": "string",
    "config": {
        "isRequired": "boolean",
        "allowNA": "boolean",
    },
    "frontendId": "number",
    "pageFrontendId": "number",
    "position": "number",
    "title": "string",
    "type": "string",
    "subtype": "string",
    "options": "array",
    "rows": "array",
    "conditionalDisplay": "object"
}
```

* `_id`: A unique id of the item. Its purpose is to identify the item in the Analysis dashboard.
* `config`
  * `isRequired`: Whether the item is required or not.
  * `allowNA`: Whether the item accepts N/A as an answer or not.
* `frontendId`: An id set in the frontend to identify the item.
* `pageFrontendId`: The id of the page that containing the item.
* `position`: The position of the item in the survey.
* `title`: The title of the item. All items have this field except for the Text block.
* `type`: The type of the item. Possible values are:
  * `multipĺe`
  * `input`
  * `scale`
  * `scaleNumeric`
  * `grid`
  * `conjoint`
  * `rank`
  * `decorator`
  * `pageBreak`
  * `promoter`
  * `constant-sum`
  * `date`
  * `contact-info`
* `subtype`: The subtype of the item. Possible values are:
  * `text`
  * `number`
  * `slider`
  * `icon`
  * `ìmage`
  * `info`
  * `information`
  * `separator`
  * `link`
  * `concept-test`
  * `max-diff`
  * `max-diff-experiment`
  * `nps`
  * `max-diff-aggregated`

For each type of item, there can be more specific properties.

## Options

Options is an array of objects containing the options for these types of questions:

* Multiple choice
* Multiple choice image
* Grid / Rating scale
* Rank order
* Max diff basic
* Max diff experiment
* Conjoint

It has the following structure:

```json theme={null}
[
    {
        "frontendId": "number",
        "isOther": "boolean",
        "itemId": "number",
        "label": "string",
        "position": "number",
        "isNoneOfAbove": "boolean",
        "autopopulated": "boolean",
        "sourceId": "number",
        "url": "string"
    }
]
```

* `frontendId`: An id set in the frontend to identify the option.
* `isOther`: Whether the option is the "other" option or not.
* `itemId`: Id of the item containing the option.
* `label`: The label of the option.
* `position`: The position of the option relative to the item.
* `isNoneOfAbove`: Whether the option is the "none of above" option or not.
* `autopopulated`: Whether the option comes from another source or not.
* `sourceId`: The frontendId from the option this was populated with if `autopopulated` is set to `true`.
* `url`: The URL of the image if the option contains one.

## Rows

Rows is an array of objects containing the options for these types of questions:

* Grid / Rating scale
* NPS
* Text entry
* Numeric entry
* Constant sum
* Max diff basic
* Max diff experiment
* Conjoint

It has the same structure as options.

## Conditional display

Conditional display is an object with the following structure:

```json theme={null}
{
    "visibleByDefault": "boolean",
    "rules": "array",
}
```

where:

* `visibleByDefault`: Whether the question is visible by default or not.
* `rules`: Array with the following structure:

```json theme={null}
[
    {
        "conditions": {
            "all": "array"
        },
        "event": {
            "type": "string",
            "params": {
                "frontendIds": "array"
            }
        }
    }
]
```

where:

* `event`
  * `type`: Type of event. Possible values are:
    * `question`
    * `option`
    * `concept`
    * `row`
    * `concept-test`
  * `params`
    * `frontendIds`: It is an array of ids. When `type` is `option`, it is an array of option ids. When `type` is `row`, it is an array of row ids. When `type` is `concept`, it is an array of concept ids. When `type` is either `question` or `concept-test`, this field is not present.
* `all`: Array of objects with the following structure:

```json theme={null}
[
    {
        "fact": "string",
        "operator": "string",
        "path": "string",
        "value": "number|array|object"
    }
]
```

where:

* `fact`: It is the id of the question that appears in the condition block.
* `operator`: The operator that is going to be used in the rule. Possible values are:
  * `equal`
  * `notEqual`
  * `lessThan`
  * `lessThanInclusive`
  * `greaterThan`
  * `greaterThanInclusive`
  * `betweenExclusive`
  * `betweenInclusive`
  * `arrayContainsAll`
  * `arrayDoesNotContainstAll`
  * `arrayContainsAny`
* `path`: Whether the rule needs to check a single value or multiple values. Possible values are:
  * `.value`
  * `.values`
* `value`: When we are comparing a single value, `value` will be a number. When we are comparing multiple values, `value` will be an array of ids. When we are comparing a minimum and a maximum, it will be an object with the following structure:

  ```json theme={null}
  {
      "min": "number",
      "max": "number"
  }
  ```

  When we are comparing rows and options, it will have the followin structure:

  ```json theme={null}
  {
      "option": "number",
      "row": "number"
  }
  ```

## Multiple choice

For multiple choice questions, we have that:

* `type`: `multiple`
* `subtype`: `text`

And the specific configuration is:

```json theme={null}
{
    "config": {
        "allowMultipleSelection": "boolean",
        "anchoredOption": "array",
        "columnCustomization": "string|number",
        "displayAs": "string",
        "exclusiveOptions": "array",
        "maxResponses": "number",
        "minResponses": "number",
        "randomize": "boolean",
        "image": "string",
        "allowOther": "boolean",
        "allowNoneOfAbove": "boolean",
        "noneOfAboveFrontendId": "number"
    }
}
```

where:

* `allowMultipleSelection`: Whether the question allows multiple selection or not.
* `maxResponses`: Maximum number of responses if `allowMultipleSelection` is set to `true`.
* `minResponses`: Minimum number of responses if `allowMultipleSelection` is set to `true`.
* `exclusiveOptions`: An array of the ids of the options that are exclusive. If a user selects an option from here, the question is considered to be answered and will ignore the `minResponses` configuration.
* `columnCustomization`: The number of columns shown for this question. If the value is `auto`, then the type of the value is `string`. Otherwise, it is a `number`. Possible values are:
  * `auto`
  * `1`
  * `2`
  * `3`
* `displayAs`: Whether the question should be displayed as a list or as a dropdown. Possible values are:
  * `list`
  * `dropdown`
* `randomize`: Whether the question should randomize its options or not.
* `anchoredOption`: An array of the ids of the options that are anchored when `randomize` is set to `true`. These options are always shown at the end of the list of options of the question and are not randomized.
* `image`: The URL of the title image (if any).
* `allowOther`: Whether the item accepts "Other" as an answer or not.
* `allowNoneOfAbove`: Whether the item accepts "None of above" as an answer or not.
* `noneOfAboveFrontendId`: Id of the "None of above" option if `allowNoneOfAbove` is set to `true`.

## Multiple choice image

For multiple choice questions, we have that:

* `type`: `multiple`
* `subtype`: `image`

The configuration object is the same as the Multiple choice questions' and, additionally, contains the following specific properties:

```json theme={null}
{
    "config": {
        "imageSize": "string",
        "showTitles": "boolean",
        "fitCover": "boolean"
    }
}
```

* `imageSize`: The size of the image. Possible values are:
  * `small`
  * `medium`
  * `large`
* `showTitles`: Whether the titles of the images should be shown or not.
* `fitCover`: If set to `false`, the image is not going to keep its aspect ratio.

## Grid / Rating scale

For grid, we have that:

* `type`: `grid`

And the specific configuration object is:

```json theme={null}
{
    "config": {
        "allowMultipleSelectionPerRow": "boolean",
        "maxResponsesPerRow": "number",
        "minResponsesPerRow": "number",
        "displayAs": "string",
        "autoPopulateData": "string",
        "displayNaColumn": "boolean",
        "randomize": "boolean",
        "randomizeColumns": "boolean",
        "requires": {
            "type": "string",
            "value": "number",
            "min": "number",
            "max": "number"
        },
        "rowPerPage": "boolean",
        "shouldForceRanking": "boolean"
    }
}
```

where:

* `allowMultipleSelectionPerRow`: Whether the user can select multiple choices for each row or not.
* `maxResponsesPerRow`: Maximum number of responses if `allowMultipleSelectionPerRow` is set to `true`.
* `minResponsesPerRow`: Minimum number of responses if `allowMultipleSelectionPerRow` is set to `true`.
* `displayAs`: Whether the question should be displayed as multiple rows or a single row. Possible values are:
  * `multipleRows`
  * `singleRow`
* `autoPopulateData`: Whether the rows come from another source or not.
* `displayNaColumn`: Whether an additional N/A column should be displayed or not.
* `randomize`: Whether rows should be randomized or not.
* `randomizeColumns`: Whether columns should be randomized or not.
* `requires`
  * `type`: Whether the question requires to answer all rows or not. Possible values are:
    * `all`
    * `exactly`
    * `atLeast`
    * `atMost`
    * `range`
  * `value`: If `type` is `exactly`, `atLeast` or `atMost`, then a value must be specified.
  * `min`: If `type` is `range`, then a minimum number of rows to answer must be set.
  * `max`: If `type` is `range`, then a maximum number of rows to answer  must be set.
* `rowPerPage`: Whether we should display the question by row or not.
* `shouldForceRanking`: Whether we should force ranking (one response per column) or not.

## NPS

For NPS, we have that:

* `type`: `grid`
* `subtype`: `nps`

The configuration object is the same as the Grids' and, additionally, contains the following specific properties:

```json theme={null}
{
    "config": {
        "allowComments": "boolean",
        "leftLabel": "string",
        "rightLabel": "string",
    }
}
```

where:

* `allowComments`: Whether NPS allows comments or not.
* `leftLabel`: The label of left anchor.
* `rightLabel`: The label of the right anchor.

We also force the following properties inside `config`:

* `displayAs`: `promoter`
* `requires`
  * `type`: `all`

## Max diff basic

For Max diff basic, we have that:

* `type`: `grid`
* `subtype`: `max-diff`

The configuration object is the same as the Grids', with the particularity that we force the following values inside `config`:

* `allowMultipleSelectionPerRow`: `false`
* `displayAs`: `multipleRows`
* `requires`
  * `type`: `exactly`
  * `value`: `2`
* `shouldForceRanking`: `true`

## Max diff experiment

For Max diff experiment, we have that:

* `type`: `grid`
* `subtype`: `max-diff-experiment`

The configuration object is the same as the Grids' and, additionally, contains the following specific properties:

```json theme={null}
{
    "config": {
        "numberOfSets": "number",
        "setSize": "number"
    }
}
```

where:

* `numberOfSets`: The number of sets to be shown in the survey.
* `setSize`: The size of each set.

We also force the following properties inside `config`:

* `allowMultipleSelectionPerRow`: `false`
* `displayAs`: `multipleRows`
* `requires`
  * `type`: `exactly`
  * `value`: `2`
* `shouldForceRanking`: `true`

## Rank order

For Rank order, we have that:

* `type`: `rank`

And the specific configuration object:

```json theme={null}
{
    "config": {
        "randomize": "boolean",
    }
}
```

where:

* `randomize`: Whether the options are randomized or not.

## Scale

When the scale is shown as slider, we have that:

* `type`: `scale`
* `subtype`: `slider`

And when the scale is shown as rating, we have that:

* `type`: `scale`
* `subtype`: `icon`

And the specific configuration object is:

```json theme={null}
{
    "config": {
        "granularity": "number",
        "leftLabel": "string",
        "rightLabel": "string",
        "minValue": "number",
        "maxValue": "number"
    }
}
```

where:

* `granularity`: The granularity of the scale. If `subtype` is `icon`, possible values are:
  * 1
  * 0.5
* `leftLabel`: The far left side of scale answer. Only available when `subtype` is `slider`.
* `rightLabel`: The far right side of scale answer. Only available when `subtype` is `slider`.
* `minValue`: The minimum value of the scale.
* `maxValue`: The maximum value of the scale.

## Text entry

For text entry, we have that:

* `type`: `input`
* `subtype`: `text`

And the specific configuration object is:

```json theme={null}
{
    "config": {
        "maxLength": "number",
        "multipleInputs": "boolean"
    }
}
```

where:

* `maxLength`: If the short response option is enabled, then `maxLength` is equal to `250`. Otherwise, its value is `0`.
* `multipleInputs`: Whether we should allow multiple inputs or not.

> Note: when `multipleInputs` is set to `true`, oher items of `type` equal to `input` and `subtype` equal to `text` are going to be created.

## Numeric entry

For text entry, we have that:

* `type`: `input`
* `subtype`: `number`

And the specific configuration object is:

```json theme={null}
{
    "config": {
        "minValue": "number",
        "maxValue": "number",
        "allowDecimals": "boolean",
        "multipleInputs": "boolean",
        "maxLength": "number"
    }
}
```

where:

* `minValue`: The minimum number allowed.
* `maxValue`: The maximum number allowed.
* `allowDecimals`: Whether decimals are allowed or not.
* `multipleInputs`: Whether multiple inputs should be allowed or not.

> Note: contrary to text entry questions, other items **are not** created when `multipleInputs` is set to `true`.

## Constant sum

For Constant sum, we have that:

* `type`: `constant-sum`

And the specific configuration object is:

```json theme={null}
{
    "config": {
        "validationType": "string",
        "mustTotalValue": "number",
        "minSumValue": "number",
        "maxSumValue": "number",
        "randomize": "boolean"
    }
}
```

where:

* `validationType`: Validation type of the total sum. Possible values are:
  * `mustTotal`
  * `range`
* `mustTotalValue`: Total sum value when `validationType` is `mustTotal`.
* `minSumValue`: Minimum total sum when `validationType` is `range`.
* `maxSumValue`: Maximum total sum when `validationType` is `range`.
* `randomize`: Whether the rows are randomized or not.

## Text block

For Text block, we have that:

* `type`: `decorator`
* `subtype`: `info`

For this question, we have other things that change besides the configuration object:

```json theme={null}
{
    "text": "string"
}
```

* `text`: The text to be shown in the survey.

## Date

For Date, we have that:

* `type`: `date`

And the specific configuration object is:

```json theme={null}
{
    "config": {
        "maxYear": "number",
        "minYear": "number"
    }
}
```

where:

* `maxYear`: The maximum year to be shown in the survey.
* `minYear`: The minimum year to be shown in the survey.

## Contact info

For Contact info, we have that:

* `type`: `contact-info`

And the specific configuration object is:

```json theme={null}
{
    "config": {
        "showAddressLine1": "boolean",
        "showAddressLine2": "boolean",
        "showCountry": "boolean",
        "showEmail": "boolean",
        "showFirstName": "boolean",
        "showLastName": "boolean",
        "showPhone": "boolean",
        "showUsState": "boolean",
        "showZipCode": "boolean",
        "countryMultipleChoiceId": "number",
        "stateMultipleChoiceId": "number"
    }
}
```

where:

* `showAddressLine1`: Whether the address line 1 should be asked in the survey or not.
* `showAddressLine2`: Whether the address line 2 should be asked in the survey or not.
* `showCountry`: Whether the country should be asked in the survey or not.
* `showEmail`: Whether the email should be asked in the survey or not.
* `showFirstName`: Whether the first name should be asked in the survey or not.
* `showLastName`: Whether the last name should be asked in the survey or not.
* `showUsState`: Whether the US State should be asked in the survey or not.
* `showZipCode`: Whether the zip code should be asked in the survey or not.
* `countryMultipleChoiceId`: If `showCountry` is set to `true`, another item (more specifically, a multiple choice question where the options are the countries) is created automatically. This field represents the id of that new item.
* `stateMultipleChoiceId`: If `showUsState` is set to `true`, another item (more specifically, a multiple choice question where the options are the US states) is created automatically. This field represents the id of that new item.

## Conjoint

For conjoint, we have that:

* `type`: `conjoint`

And the specific properties of this item will be:

```json theme={null}
{
    "config": {
        "numberOfCardsPerSet": "number",
        "numberOfSets": "number",
        "allowNone": "boolean",
    },
    "description": "string",
    "rows": "array",
    "options": "array",
}
```

where:

* `config`
  * `numberOfCardsPerSet`: The number of cards per set to be shown in the survey.
  * `numberOfSets`: The number of sets to be shown in the survey.
  * `allowNone`: Whether we should allow the "None" card or not.
* `description`: The description text of the conjoint experiment.

## Conjoint rows

Conjoint rows correspond to the attributes of the conjoint experiment. They have the same structure as the common `rows` array of objects, with the following additional properties:

```json theme={null}
[
    {
        "allowLevelImages": "boolean",
        "enableRangeLevels": "boolean",
        "levels": "array"
    }
]
```

where:

* `allowLevelImages`: Whether images are allowed in the levels of the attribute or not.
* `enableRangeLevels`: Whether we should add a range of levels instead or not.
* `levels`: An array containing the ids of the levels. If `enableRangeLevels` is set to `true`, then `levels` will be an empty array.

## Conjoint options

Conjoint options correspond to the levels of the conjoint experiment. They have the same structure as the common `options` array of objects, with the following additional property:

```json theme={null}
[
    {
        "attributeId": "number"
    }
]
```

where:

* `attributeId`: Id of the corresponding attribute for the level.

## Concept test

The concept test works very differently to other type of questions. For each concept inside the concept test, a new `page` object is created. As usual, this page will have `items`, which is again an array of objects. However, the first item will contain the information of the concept itself. It will have the same structure as a normal item, but with additional properties. First of all, we will have that:

* `type`: `decorator`
* `subtype`: `concept-test`

And the specific properties of this item will be:

```json theme={null}
{
    "config": {
        "type": "string",
        "url": "string",
        "title": "string",
        "hideLinkAfterShow": "boolean",
        "timeToDisplay": "number",
        "videoId": "string",
        "thumbnailUrl": "string"
    },
    "children": "number",
    "conceptTestId": "number",
    "conceptTitle": "string",
    "randomizeConcept": "boolean",
    "showConceptsNotDisplayed": "boolean"
}
```

where:

* `config`
  * `type`: Type of concept to be shown. Possible values are:
    * `imageUpload`
    * `youtubeVideo`
    * `externalLink`
    * `audio`
  * `url`: URL of the image, video or external link.
  * `title`: Name of the concept (if any).
  * `hideLinkAfterShow`: Whether the link of the resource should be hidden or not after it was shown in the survey.
  * `timeToDisplay`: The number of seconds the image, video or external link should be displayed in the survey.
  * `videoId`: Id of the YouTube video. Only present if `type` is `youtubeVideo`.
  * `thumbnailUrl`: URL of the external link. Only present if `type` is `externalLink`.
* `children`: Number of questions inside the concept test.
* `conceptTestId`: Id of the concept.
* `conceptTitle`: Name of the concept test question that contains the current concept.
* `randomizeConcept`: Whether the concepts should be randomized or not.
* `showConceptsNotDisplayed`: Whether we should show concepts that are not displayed or not.

## conceptTestPerUser

The `conceptTestPerUser` object, which is not inside the `survey` object, contains information about how many concepts are going to be shown to the user. It will be an object where the keys are the `conceptTestId` of each concept test present in the survey and the value is the number of concept tests per user.

```json theme={null}
{
    "[conceptTestId]": "number"
}
```

### Page jumps

For page jumps (Always skip), we have the following structure:

```json theme={null}
{
    "[pageFrontendId]": {
        "pageJump": {
            "jumpType": "string",
            "skipTo": "string"
        }
    }
}
```

where:

* `pageFrontendId`: Id of the page that contains the skip logic rule. If we are applying skip logic rules to a whole page, then this will be the id of the first question of that page.
* `jumpType`: The type of jump. Possible values are:
  * `DISQUALIFY`
  * `END_OF_SURVEY`
  * `PAGE`
* `skipTo`: Id of the page we want to jump to. This field is present only if `jumpType` is `PAGE`.

### Conditional and unconditional skips

For conditional skips, we have the following structure:

```json theme={null}
{
    "[pageFrontendId]": {
        "logic": {
            "[questionFrontendId]": {
                "type": "string",
                "jumps": "array"
            }
        }
    }
}
```

where:

* `pageFrontendId`: Id of the page that contains questions with skip logic rules.
* `questionFrontendId`: Id of the question with skip logic rules.
* `type`: The type of the skip. Possible values are:
  * `UNCONDITIONAL`
  * `BY_OPTION`
  * `BY_EXPRESSION`
  * `BY_GRID_SELECTION`

Now, `jumps` is an array of objects containing the logic of the skip.

```json theme={null}
[
    {
        "jumpType": "string",
        "skipTo": "string",
        "areOptionsSelected": "boolean",
        "logicOperator": "string",
        "options": "array",
        "selections": "array",
        "expressions": "array",
    }
]
```

where:

* `jumpType`: It is the type of of jump. The possible values are the same for the page jumps.
* `skipTo`: The id of the page we want to skip to if `jumpType` is `PAGE`.
* `areOptionsSelected`: Whether the options specified in the `options` array are selected or not.
* `logicOperator`: The operator to be used. Possible values are:
  * `OR`
  * `AND`
* `options`: An array of ids of options where the logic rule is being applied to. Only available if `type` is `BY_OPTION`.
* `selections`: An array of objects containing the ids of the options and rows where the logic rule is being applied to. Only available if `type` is `BY_GRID_SELECTION`.
* `expressions`: An array of expressions for when the `type` of skip is `BY_EXPRESSION`.

# Response

## 200 OK

```json theme={null}
{
    "customization": {
        "backgroundColor": "string",
        "foregroundColor": "string",
        "paging": "none|page|question",
        "mobilePaging": "none|page|question",
        "showNumbers": "boolean",
        "showTitle": "boolean",
        "disableBackButton": "boolean",
        "progressBar": {
            "enabled": "boolean",
            "type": "percent|simple|numeric"
        },
        "question": {
            "font": "string",
            "color": "string",
            "align": "string"
        },
        "answer": {
            "font": "string",
            "color": "string",
            "align": "string"
        },
        "nextPreviousButton": {
            "type": "default|simple|bigger"
        }
    },
    "logo": {
        "url": "string"
    },
    "survey": {
        "endOfSurveyText": "string",
        "pages": "array",
        "termsAndConditions": "string",
        "welcomeText": "string"
    },
    "id": "string",
    "title": "string",
    "isSkipLogicEnabled": "boolean",
    "isTranslationEnabled": "boolean",
    "isPipingFromQuestionEnabled": "boolean",
    "isLive": "boolean",
    "hasSignatureConfirmation": "boolean",
    "hasConditionalDisplay": "boolean",
    "lastResponsesRecreationDate": "YYYY-MM-DDTHH:mm:ss.SSSZ",
    "showLocked": "boolean",
    "languages": ["string"],
    "conceptTestsPerUser": object,
    "audienceId": null,
    "conceptTestsToDisplay": object,
    "criteria": object,
    "projectVariables": object,
    "catalog": object
}
```

where:

See payload description.

## 401 Unauthorized

> The user doesn't have permissions.

## 500 Internal Server Error

> Error occurred while processing the request.


## OpenAPI

````yaml PATCH /projects-api/v1/projects/{projectId}/autoSave
openapi: 3.0.3
info:
  title: SightX API
  version: 1.0.0
  description: >-
    SightX REST API documentation. Most responses are JSON; some export
    endpoints return files. API access is a paid add-on — contact
    sales@sightx.io for details.
servers:
  - url: https://auth.admin.sightx.io
    description: Authentication (Production)
  - url: https://auth.staging-admin.sightx.io
    description: Authentication (Staging)
security:
  - AuthorizationHeader: []
paths:
  /projects-api/v1/projects/{projectId}/autoSave:
    patch:
      summary: Auto Save
      description: >-
        # Description


        Saves the project. The response will have the errors found on it.


        * **Note**:

        You must always send the entire project structure in the request
        payload.


        # Payload


        ```json

        {
            "lastResponsesRecreationDate": "string",
            "id": "string",
            "title": "string",
            "isLive": "boolean",
            "hasSignatureConfirmation": "boolean",
            "status": "string",
            "hasConditionalDisplay": "boolean",
            "showLocked": "boolean",
            "isPipingFromQuestionEnabled": "boolean",
            "isSkipLogicEnabled": "boolean",
            "isTranslationEnabled": "boolean",
            "languages": "array",
            "customization": "object",
            "logo": "object",
            "survey": "object",
            "conceptTestPerUser": "object",
            "conceptTestsToDisplay": "object"
        }

        ```

        where:


        - `lastResponsesRecreationDate`: Date of the last time someone recreated
        the data of the project in the format `YYYY-MM-DDTHH:mm:ss.SSSZ`.

        - `id`: Id of the project.

        - `title`: Name of the project.

        - `isLive`: Whether the project is live or not.

        - `hasSignatureConfirmation`: Whether the project has the signature
        configuration enabled or not.

        - `status`: Status of the project. Possible values are:
            - `draft`
            - `published`
        - `hasConditionalDisplay`: Whether the project contains conditional
        display or not.

        - `showLocked`: Whether the build section of the project should be shown
        locked or not. If the survey already has responses, `showLocked` will
        always be `true`.

        - `isPipingFromQuestionEnabled`: Whether piping from questions is
        enabled or not.

        - `isSkipLogicEnabled`: Whether skip logic is enabled or not.

        - `isTranslationEnabled`: Whether translations are enabled or not.

        - `languages`: An array of `string` with the country codes of the
        languages available in the project.


        ### Customization


        The customization object defines the customization options of the
        project. It has the following structure:


        ```json

        {
            "backgroundColor": "string",
            "foregroundColor": "string",
            "mobilePaging": "string",
            "paging": "string",
            "showNumbers": "boolean",
            "showTitle": "boolean",
            "disableBackButton": "boolean",
            "progressBar": {
                "enabled": "boolean",
                "type": "string",
            },
            "question": {
                "font": "string",
                "color": "string",
                "align": "string"
            },
            "answer": {
                "font": "string",
                "color": "string",
                "align": "string"
            },
            "nextPreviousButton": {
                "type": "string",
            }
        }

        ```


        - `backgroundColor`: Hex color code for the survey's background.

        - `foregroundColor`: Hex color code of buttons shown in the survey.

        - `paging`: The type of paging used for the desktop version of the
        survey. Possible values are:
            - `none`
            - `page`
            - `question`
        - `mobilePaging`: The type of paging used for the mobile version of the
        survey. The values are the same of `paging`.

        - `showNumbers`: Whether the survey should show question numbers or not.

        - `showTitle`: Whether to show the name of the project in the survey or
        not.

        - `disableBackButton`: Whether to disable the back button or not.

        - `progressBar`
            - `enabled`: Whether the progress bar is shown or not in the survey.
            - `type`: The type of progress bar. Possible values are:
                - `percent`
                - `bar`
                - `simple`
        - `question`
            - `font`: Font of the questions titles. Defaults to `Source Sans Pro`.
            - `color`: Color of the font of the questions titles.
            - `align`: Alignment of the questions titles.
        - `answer`
            - `font`: Font of the questions' options. Defaults to `Source Sans Pro`.
            - `color`: Color of the font of the questions' options.
            - `align`: Alignment of the questions' options.
        - `nextPreviousButton`
            - `type`: Type of the previous button. Possible values are:
                - `default`
                - `simple`
                - `bigger`

        ## Logo


        The logo of the project is an object with the following structure:


        ```json

        {
            "url": "string"
        }

        ```


        - `url`: Url of the logo of the project. Can be base64 or regular url.


        #### Note


        If base64 string is posted then the api saves the image and saves the
        url.


        If a normal url is posted then the api just saves it.


        ## Survey


        The structure of the survey object is the following:


        ```json

        {
            "endOfSurveyText": "string",
            "pages": "array",
            "termsAndConditions": "string",
            "welcomeText": "string"
        }

        ```


        - `welcomeText`: Text of the welcome page of the survey.

        - `termsAndConditions`: Text of the terms and conditions of the survey.

        - `endOfSurveyText`: Text of the thank you page of the survey.


        ## Pages


        Pages is an array of objects. Each page contains the following
        information:


        ```json

        [
            {
                "frontendId": "number",
                "position": "number",
                "randomizeItems": "boolean",
                "title": "string",
                "type": "string",
                "items": "array",
            }
        ]

        ```


        - `frontendId`: The id of the page.

        - `position`: Position of the page in the survey. For example, if it is
        the first page, then `position` will be equal to `1`.

        - `randomizeItems`: Whether the items inside the page should be
        randomized or not.

        - `title`: The title of the page.

        - `type`: The type of item. For pages, it will always be `page`.


        ## Items


        The items are the questions inside the pages. Each item contains the
        following common structure:


        ```json

        {
            "_id": "string",
            "config": {
                "isRequired": "boolean",
                "allowNA": "boolean",
            },
            "frontendId": "number",
            "pageFrontendId": "number",
            "position": "number",
            "title": "string",
            "type": "string",
            "subtype": "string",
            "options": "array",
            "rows": "array",
            "conditionalDisplay": "object"
        }

        ```


        - `_id`: A unique id of the item. Its purpose is to identify the item in
        the Analysis dashboard.

        - `config`
            - `isRequired`: Whether the item is required or not.
            - `allowNA`: Whether the item accepts N/A as an answer or not.
        - `frontendId`: An id set in the frontend to identify the item.

        - `pageFrontendId`: The id of the page that containing the item.

        - `position`: The position of the item in the survey.

        - `title`: The title of the item. All items have this field except for
        the Text block.

        - `type`: The type of the item. Possible values are:
            - `multipĺe`
            - `input`
            - `scale`
            - `scaleNumeric`
            - `grid`
            - `conjoint`
            - `rank`
            - `decorator`
            - `pageBreak`
            - `promoter`
            - `constant-sum`
            - `date`
            - `contact-info`
        - `subtype`: The subtype of the item. Possible values are:
            - `text`
            - `number`
            - `slider`
            - `icon`
            - `ìmage`
            - `info`
            - `information`
            - `separator`
            - `link`
            - `concept-test`
            - `max-diff`
            - `max-diff-experiment`
            - `nps`
            - `max-diff-aggregated`

        For each type of item, there can be more specific properties.


        ## Options


        Options is an array of objects containing the options for these types of
        questions:


        - Multiple choice

        - Multiple choice image

        - Grid / Rating scale

        - Rank order

        - Max diff basic

        - Max diff experiment

        - Conjoint


        It has the following structure:


        ```json

        [
            {
                "frontendId": "number",
                "isOther": "boolean",
                "itemId": "number",
                "label": "string",
                "position": "number",
                "isNoneOfAbove": "boolean",
                "autopopulated": "boolean",
                "sourceId": "number",
                "url": "string"
            }
        ]

        ```


        - `frontendId`: An id set in the frontend to identify the option.

        - `isOther`: Whether the option is the "other" option or not.

        - `itemId`: Id of the item containing the option.

        - `label`: The label of the option.

        - `position`: The position of the option relative to the item.

        - `isNoneOfAbove`: Whether the option is the "none of above" option or
        not.

        - `autopopulated`: Whether the option comes from another source or not.

        - `sourceId`: The frontendId from the option this was populated with if
        `autopopulated` is set to `true`.

        - `url`: The URL of the image if the option contains one.


        ## Rows


        Rows is an array of objects containing the options for these types of
        questions:


        - Grid / Rating scale

        - NPS

        - Text entry

        - Numeric entry

        - Constant sum

        - Max diff basic

        - Max diff experiment

        - Conjoint


        It has the same structure as options.


        ## Conditional display


        Conditional display is an object with the following structure:


        ```json

        {
            "visibleByDefault": "boolean",
            "rules": "array",
        }

        ```



        where:


        - `visibleByDefault`: Whether the question is visible by default or not.

        - `rules`: Array with the following structure:


        ```json

        [
            {
                "conditions": {
                    "all": "array"
                },
                "event": {
                    "type": "string",
                    "params": {
                        "frontendIds": "array"
                    }
                }
            }
        ]

        ```


        where:


        - `event`
            - `type`: Type of event. Possible values are:
                - `question`
                - `option`
                - `concept`
                - `row`
                - `concept-test`
            - `params`
                - `frontendIds`: It is an array of ids. When `type` is `option`, it is an array of option ids. When `type` is `row`, it is an array of row ids. When `type` is `concept`, it is an array of concept ids. When `type` is either `question` or `concept-test`, this field is not present.
        - `all`: Array of objects with the following structure:


        ```json

        [
            {
                "fact": "string",
                "operator": "string",
                "path": "string",
                "value": "number|array|object"
            }
        ]

        ```


        where:


        - `fact`: It is the id of the question that appears in the condition
        block.

        - `operator`: The operator that is going to be used in the rule.
        Possible values are:
            - `equal`
            - `notEqual`
            - `lessThan`
            - `lessThanInclusive`
            - `greaterThan`
            - `greaterThanInclusive`
            - `betweenExclusive`
            - `betweenInclusive`
            - `arrayContainsAll`
            - `arrayDoesNotContainstAll`
            - `arrayContainsAny`
        - `path`: Whether the rule needs to check a single value or multiple
        values. Possible values are:
            - `.value`
            - `.values`
        - `value`: When we are comparing a single value, `value` will be a
        number. When we are comparing multiple values, `value` will be an array
        of ids. When we are comparing a minimum and a maximum, it will be an
        object with the following structure:

            ```json
            {
                "min": "number",
                "max": "number"
            }
            ```

            When we are comparing rows and options, it will have the followin structure:

            ```json
            {
                "option": "number",
                "row": "number"
            }
            ```

        ## Multiple choice


        For multiple choice questions, we have that:


        - `type`: `multiple`

        - `subtype`: `text`


        And the specific configuration is:


        ```json

        {
            "config": {
                "allowMultipleSelection": "boolean",
                "anchoredOption": "array",
                "columnCustomization": "string|number",
                "displayAs": "string",
                "exclusiveOptions": "array",
                "maxResponses": "number",
                "minResponses": "number",
                "randomize": "boolean",
                "image": "string",
                "allowOther": "boolean",
                "allowNoneOfAbove": "boolean",
                "noneOfAboveFrontendId": "number"
            }
        }

        ```


        where:


        - `allowMultipleSelection`: Whether the question allows multiple
        selection or not.

        - `maxResponses`: Maximum number of responses if
        `allowMultipleSelection` is set to `true`.

        - `minResponses`: Minimum number of responses if
        `allowMultipleSelection` is set to `true`.

        - `exclusiveOptions`: An array of the ids of the options that are
        exclusive. If a user selects an option from here, the question is
        considered to be answered and will ignore the `minResponses`
        configuration.

        - `columnCustomization`: The number of columns shown for this question.
        If the value is `auto`, then the type of the value is `string`.
        Otherwise, it is a `number`. Possible values are:
            - `auto`
            - `1`
            - `2`
            - `3`
        - `displayAs`: Whether the question should be displayed as a list or as
        a dropdown. Possible values are:
            - `list`
            - `dropdown`
        - `randomize`: Whether the question should randomize its options or not.

        - `anchoredOption`: An array of the ids of the options that are anchored
        when `randomize` is set to `true`. These options are always shown at the
        end of the list of options of the question and are not randomized.

        - `image`: The URL of the title image (if any).

        - `allowOther`: Whether the item accepts "Other" as an answer or not.

        - `allowNoneOfAbove`: Whether the item accepts "None of above" as an
        answer or not.

        - `noneOfAboveFrontendId`: Id of the "None of above" option if
        `allowNoneOfAbove` is set to `true`.


        ## Multiple choice image


        For multiple choice questions, we have that:


        - `type`: `multiple`

        - `subtype`: `image`


        The configuration object is the same as the Multiple choice questions'
        and, additionally, contains the following specific properties:


        ```json

        {
            "config": {
                "imageSize": "string",
                "showTitles": "boolean",
                "fitCover": "boolean"
            }
        }

        ```


        - `imageSize`: The size of the image. Possible values are:
            - `small`
            - `medium`
            - `large`
        - `showTitles`: Whether the titles of the images should be shown or not.

        - `fitCover`: If set to `false`, the image is not going to keep its
        aspect ratio.


        ## Grid / Rating scale


        For grid, we have that:


        - `type`: `grid`


        And the specific configuration object is:


        ```json

        {
            "config": {
                "allowMultipleSelectionPerRow": "boolean",
                "maxResponsesPerRow": "number",
                "minResponsesPerRow": "number",
                "displayAs": "string",
                "autoPopulateData": "string",
                "displayNaColumn": "boolean",
                "randomize": "boolean",
                "randomizeColumns": "boolean",
                "requires": {
                    "type": "string",
                    "value": "number",
                    "min": "number",
                    "max": "number"
                },
                "rowPerPage": "boolean",
                "shouldForceRanking": "boolean"
            }
        }

        ```


        where:


        - `allowMultipleSelectionPerRow`: Whether the user can select multiple
        choices for each row or not.

        - `maxResponsesPerRow`: Maximum number of responses if
        `allowMultipleSelectionPerRow` is set to `true`.

        - `minResponsesPerRow`: Minimum number of responses if
        `allowMultipleSelectionPerRow` is set to `true`.

        - `displayAs`: Whether the question should be displayed as multiple rows
        or a single row. Possible values are:
            - `multipleRows`
            - `singleRow`
        - `autoPopulateData`: Whether the rows come from another source or not.

        - `displayNaColumn`: Whether an additional N/A column should be
        displayed or not.

        - `randomize`: Whether rows should be randomized or not.

        - `randomizeColumns`: Whether columns should be randomized or not.

        - `requires`
            - `type`: Whether the question requires to answer all rows or not. Possible values are:
                - `all`
                - `exactly`
                - `atLeast`
                - `atMost`
                - `range`
            - `value`: If `type` is `exactly`, `atLeast` or `atMost`, then a value must be specified.
            - `min`: If `type` is `range`, then a minimum number of rows to answer must be set.
            - `max`: If `type` is `range`, then a maximum number of rows to answer  must be set.
        - `rowPerPage`: Whether we should display the question by row or not.

        - `shouldForceRanking`: Whether we should force ranking (one response
        per column) or not.


        ## NPS


        For NPS, we have that:


        - `type`: `grid`

        - `subtype`: `nps`


        The configuration object is the same as the Grids' and, additionally,
        contains the following specific properties:


        ```json

        {
            "config": {
                "allowComments": "boolean",
                "leftLabel": "string",
                "rightLabel": "string",
            }
        }

        ```


        where:


        - `allowComments`: Whether NPS allows comments or not.

        - `leftLabel`: The label of left anchor.

        - `rightLabel`: The label of the right anchor.


        We also force the following properties inside `config`:


        - `displayAs`: `promoter`

        - `requires`
            - `type`: `all`

        ## Max diff basic


        For Max diff basic, we have that:


        - `type`: `grid`

        - `subtype`: `max-diff`


        The configuration object is the same as the Grids', with the
        particularity that we force the following values inside `config`:


        - `allowMultipleSelectionPerRow`: `false`

        - `displayAs`: `multipleRows`

        - `requires`
            - `type`: `exactly`
            - `value`: `2`
        - `shouldForceRanking`: `true`


        ## Max diff experiment


        For Max diff experiment, we have that:


        - `type`: `grid`

        - `subtype`: `max-diff-experiment`


        The configuration object is the same as the Grids' and, additionally,
        contains the following specific properties:


        ```json

        {
            "config": {
                "numberOfSets": "number",
                "setSize": "number"
            }
        }

        ```


        where:


        - `numberOfSets`: The number of sets to be shown in the survey.

        - `setSize`: The size of each set.


        We also force the following properties inside `config`:


        - `allowMultipleSelectionPerRow`: `false`

        - `displayAs`: `multipleRows`

        - `requires`
            - `type`: `exactly`
            - `value`: `2`
        - `shouldForceRanking`: `true`


        ## Rank order


        For Rank order, we have that:


        - `type`: `rank`


        And the specific configuration object:


        ```json

        {
            "config": {
                "randomize": "boolean",
            }
        }

        ```


        where:


        - `randomize`: Whether the options are randomized or not.


        ## Scale


        When the scale is shown as slider, we have that:


        - `type`: `scale`

        - `subtype`: `slider`


        And when the scale is shown as rating, we have that:


        - `type`: `scale`

        - `subtype`: `icon`


        And the specific configuration object is:


        ```json

        {
            "config": {
                "granularity": "number",
                "leftLabel": "string",
                "rightLabel": "string",
                "minValue": "number",
                "maxValue": "number"
            }
        }

        ```


        where:


        - `granularity`: The granularity of the scale. If `subtype` is `icon`,
        possible values are:
            - 1
            - 0.5
        - `leftLabel`: The far left side of scale answer. Only available when
        `subtype` is `slider`.

        - `rightLabel`: The far right side of scale answer. Only available when
        `subtype` is `slider`.

        - `minValue`: The minimum value of the scale.

        - `maxValue`: The maximum value of the scale.


        ## Text entry


        For text entry, we have that:


        - `type`: `input`

        - `subtype`: `text`


        And the specific configuration object is:


        ```json

        {
            "config": {
                "maxLength": "number",
                "multipleInputs": "boolean"
            }
        }

        ```


        where:


        - `maxLength`: If the short response option is enabled, then `maxLength`
        is equal to `250`. Otherwise, its value is `0`.

        - `multipleInputs`: Whether we should allow multiple inputs or not.


        > Note: when `multipleInputs` is set to `true`, oher items of `type`
        equal to `input` and `subtype` equal to `text` are going to be created.


        ## Numeric entry


        For text entry, we have that:


        - `type`: `input`

        - `subtype`: `number`


        And the specific configuration object is:


        ```json

        {
            "config": {
                "minValue": "number",
                "maxValue": "number",
                "allowDecimals": "boolean",
                "multipleInputs": "boolean",
                "maxLength": "number"
            }
        }

        ```


        where:


        - `minValue`: The minimum number allowed.

        - `maxValue`: The maximum number allowed.

        - `allowDecimals`: Whether decimals are allowed or not.

        - `multipleInputs`: Whether multiple inputs should be allowed or not.


        > Note: contrary to text entry questions, other items **are not**
        created when `multipleInputs` is set to `true`.


        ## Constant sum


        For Constant sum, we have that:


        - `type`: `constant-sum`


        And the specific configuration object is:


        ```json

        {
            "config": {
                "validationType": "string",
                "mustTotalValue": "number",
                "minSumValue": "number",
                "maxSumValue": "number",
                "randomize": "boolean"
            }
        }

        ```


        where:


        - `validationType`: Validation type of the total sum. Possible values
        are:
            - `mustTotal`
            - `range`
        - `mustTotalValue`: Total sum value when `validationType` is
        `mustTotal`.

        - `minSumValue`: Minimum total sum when `validationType` is `range`.

        - `maxSumValue`: Maximum total sum when `validationType` is `range`.

        - `randomize`: Whether the rows are randomized or not.


        ## Text block


        For Text block, we have that:


        - `type`: `decorator`

        - `subtype`: `info`


        For this question, we have other things that change besides the
        configuration object:


        ```json

        {
            "text": "string"
        }

        ```


        - `text`: The text to be shown in the survey.


        ## Date


        For Date, we have that:


        - `type`: `date`


        And the specific configuration object is:


        ```json

        {
            "config": {
                "maxYear": "number",
                "minYear": "number"
            }
        }

        ```


        where:


        - `maxYear`: The maximum year to be shown in the survey.

        - `minYear`: The minimum year to be shown in the survey.


        ## Contact info


        For Contact info, we have that:


        - `type`: `contact-info`


        And the specific configuration object is:


        ```json

        {
            "config": {
                "showAddressLine1": "boolean",
                "showAddressLine2": "boolean",
                "showCountry": "boolean",
                "showEmail": "boolean",
                "showFirstName": "boolean",
                "showLastName": "boolean",
                "showPhone": "boolean",
                "showUsState": "boolean",
                "showZipCode": "boolean",
                "countryMultipleChoiceId": "number",
                "stateMultipleChoiceId": "number"
            }
        }

        ```


        where:


        - `showAddressLine1`: Whether the address line 1 should be asked in the
        survey or not.

        - `showAddressLine2`: Whether the address line 2 should be asked in the
        survey or not.

        - `showCountry`: Whether the country should be asked in the survey or
        not.

        - `showEmail`: Whether the email should be asked in the survey or not.

        - `showFirstName`: Whether the first name should be asked in the survey
        or not.

        - `showLastName`: Whether the last name should be asked in the survey or
        not.

        - `showUsState`: Whether the US State should be asked in the survey or
        not.

        - `showZipCode`: Whether the zip code should be asked in the survey or
        not.

        - `countryMultipleChoiceId`: If `showCountry` is set to `true`, another
        item (more specifically, a multiple choice question where the options
        are the countries) is created automatically. This field represents the
        id of that new item.

        - `stateMultipleChoiceId`: If `showUsState` is set to `true`, another
        item (more specifically, a multiple choice question where the options
        are the US states) is created automatically. This field represents the
        id of that new item.


        ## Conjoint


        For conjoint, we have that:


        - `type`: `conjoint`


        And the specific properties of this item will be:


        ```json

        {
            "config": {
                "numberOfCardsPerSet": "number",
                "numberOfSets": "number",
                "allowNone": "boolean",
            },
            "description": "string",
            "rows": "array",
            "options": "array",
        }

        ```


        where:


        - `config`
            - `numberOfCardsPerSet`: The number of cards per set to be shown in the survey.
            - `numberOfSets`: The number of sets to be shown in the survey.
            - `allowNone`: Whether we should allow the "None" card or not.
        - `description`: The description text of the conjoint experiment.


        ## Conjoint rows


        Conjoint rows correspond to the attributes of the conjoint experiment.
        They have the same structure as the common `rows` array of objects, with
        the following additional properties:


        ```json

        [
            {
                "allowLevelImages": "boolean",
                "enableRangeLevels": "boolean",
                "levels": "array"
            }
        ]

        ```


        where:


        - `allowLevelImages`: Whether images are allowed in the levels of the
        attribute or not.

        - `enableRangeLevels`: Whether we should add a range of levels instead
        or not.

        - `levels`: An array containing the ids of the levels. If
        `enableRangeLevels` is set to `true`, then `levels` will be an empty
        array.


        ## Conjoint options


        Conjoint options correspond to the levels of the conjoint experiment.
        They have the same structure as the common `options` array of objects,
        with the following additional property:


        ```json

        [
            {
                "attributeId": "number"
            }
        ]

        ```


        where:


        - `attributeId`: Id of the corresponding attribute for the level.


        ## Concept test


        The concept test works very differently to other type of questions. For
        each concept inside the concept test, a new `page` object is created. As
        usual, this page will have `items`, which is again an array of objects.
        However, the first item will contain the information of the concept
        itself. It will have the same structure as a normal item, but with
        additional properties. First of all, we will have that:


        - `type`: `decorator`

        - `subtype`: `concept-test`


        And the specific properties of this item will be:


        ```json

        {
            "config": {
                "type": "string",
                "url": "string",
                "title": "string",
                "hideLinkAfterShow": "boolean",
                "timeToDisplay": "number",
                "videoId": "string",
                "thumbnailUrl": "string"
            },
            "children": "number",
            "conceptTestId": "number",
            "conceptTitle": "string",
            "randomizeConcept": "boolean",
            "showConceptsNotDisplayed": "boolean"
        }

        ```


        where:


        - `config`
            - `type`: Type of concept to be shown. Possible values are:
                - `imageUpload`
                - `youtubeVideo`
                - `externalLink`
                - `audio`
            - `url`: URL of the image, video or external link.
            - `title`: Name of the concept (if any).
            - `hideLinkAfterShow`: Whether the link of the resource should be hidden or not after it was shown in the survey.
            - `timeToDisplay`: The number of seconds the image, video or external link should be displayed in the survey.
            - `videoId`: Id of the YouTube video. Only present if `type` is `youtubeVideo`.
            - `thumbnailUrl`: URL of the external link. Only present if `type` is `externalLink`.
        - `children`: Number of questions inside the concept test.

        - `conceptTestId`: Id of the concept.

        - `conceptTitle`: Name of the concept test question that contains the
        current concept.

        - `randomizeConcept`: Whether the concepts should be randomized or not.

        - `showConceptsNotDisplayed`: Whether we should show concepts that are
        not displayed or not.


        ## conceptTestPerUser


        The `conceptTestPerUser` object, which is not inside the `survey`
        object, contains information about how many concepts are going to be
        shown to the user. It will be an object where the keys are the
        `conceptTestId` of each concept test present in the survey and the value
        is the number of concept tests per user.


        ```json

        {
            "[conceptTestId]": "number"
        }

        ```


        ### Page jumps


        For page jumps (Always skip), we have the following structure:


        ```json

        {
            "[pageFrontendId]": {
                "pageJump": {
                    "jumpType": "string",
                    "skipTo": "string"
                }
            }
        }

        ```


        where:


        - `pageFrontendId`: Id of the page that contains the skip logic rule. If
        we are applying skip logic rules to a whole page, then this will be the
        id of the first question of that page.

        - `jumpType`: The type of jump. Possible values are:
            - `DISQUALIFY`
            - `END_OF_SURVEY`
            - `PAGE`
        - `skipTo`: Id of the page we want to jump to. This field is present
        only if `jumpType` is `PAGE`.


        ### Conditional and unconditional skips


        For conditional skips, we have the following structure:


        ```json

        {
            "[pageFrontendId]": {
                "logic": {
                    "[questionFrontendId]": {
                        "type": "string",
                        "jumps": "array"
                    }
                }
            }
        }

        ```


        where:


        - `pageFrontendId`: Id of the page that contains questions with skip
        logic rules.

        - `questionFrontendId`: Id of the question with skip logic rules.

        - `type`: The type of the skip. Possible values are:
            - `UNCONDITIONAL`
            - `BY_OPTION`
            - `BY_EXPRESSION`
            - `BY_GRID_SELECTION`

        Now, `jumps` is an array of objects containing the logic of the skip.


        ```json

        [
            {
                "jumpType": "string",
                "skipTo": "string",
                "areOptionsSelected": "boolean",
                "logicOperator": "string",
                "options": "array",
                "selections": "array",
                "expressions": "array",
            }
        ]

        ```


        where:


        - `jumpType`: It is the type of of jump. The possible values are the
        same for the page jumps.

        - `skipTo`: The id of the page we want to skip to if `jumpType` is
        `PAGE`.

        - `areOptionsSelected`: Whether the options specified in the `options`
        array are selected or not.

        - `logicOperator`: The operator to be used. Possible values are:
            - `OR`
            - `AND`
        - `options`: An array of ids of options where the logic rule is being
        applied to. Only available if `type` is `BY_OPTION`.

        - `selections`: An array of objects containing the ids of the options
        and rows where the logic rule is being applied to. Only available if
        `type` is `BY_GRID_SELECTION`.

        - `expressions`: An array of expressions for when the `type` of skip is
        `BY_EXPRESSION`.


        # Response


        ## 200 OK


        ```json

        {
            "customization": {
                "backgroundColor": "string",
                "foregroundColor": "string",
                "paging": "none|page|question",
                "mobilePaging": "none|page|question",
                "showNumbers": "boolean",
                "showTitle": "boolean",
                "disableBackButton": "boolean",
                "progressBar": {
                    "enabled": "boolean",
                    "type": "percent|simple|numeric"
                },
                "question": {
                    "font": "string",
                    "color": "string",
                    "align": "string"
                },
                "answer": {
                    "font": "string",
                    "color": "string",
                    "align": "string"
                },
                "nextPreviousButton": {
                    "type": "default|simple|bigger"
                }
            },
            "logo": {
                "url": "string"
            },
            "survey": {
                "endOfSurveyText": "string",
                "pages": "array",
                "termsAndConditions": "string",
                "welcomeText": "string"
            },
            "id": "string",
            "title": "string",
            "isSkipLogicEnabled": "boolean",
            "isTranslationEnabled": "boolean",
            "isPipingFromQuestionEnabled": "boolean",
            "isLive": "boolean",
            "hasSignatureConfirmation": "boolean",
            "hasConditionalDisplay": "boolean",
            "lastResponsesRecreationDate": "YYYY-MM-DDTHH:mm:ss.SSSZ",
            "showLocked": "boolean",
            "languages": ["string"],
            "conceptTestsPerUser": object,
            "audienceId": null,
            "conceptTestsToDisplay": object,
            "criteria": object,
            "projectVariables": object,
            "catalog": object
        }

        ```


        where:


        See payload description.


        ## 401 Unauthorized


        > The user doesn't have permissions.


        ## 500 Internal Server Error


        > Error occurred while processing the request.
      operationId: auto-save-patch-projects-api-v1-projects-projectid-autosave
      parameters:
        - name: Authorization
          in: header
          required: true
          description: Authorization token
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: true
            example:
              customization:
                backgroundColor: string
                foregroundColor: string
                paging: none|page|question
                mobilePaging: none|page|question
                showNumbers: boolean
                showTitle: boolean
                disableBackButton: boolean
                progressBar:
                  enabled: boolean
                  type: percent|simple|numeric
                question:
                  font: string
                  color: string
                  align: string
                answer:
                  font: string
                  color: string
                  align: string
                nextPreviousButton:
                  type: default|simple|bigger
              logo:
                url: string
              survey:
                endOfSurveyText: string
                pages: array
                termsAndConditions: string
                welcomeText: string
              id: '{{projectId}}'
              title: string
              isSkipLogicEnabled: boolean
              isTranslationEnabled: boolean
              isPipingFromQuestionEnabled: boolean
              isLive: boolean
              hasSignatureConfirmation: boolean
              hasConditionalDisplay: boolean
              lastResponsesRecreationDate: YYYY-MM-DDTHH:mm:ss.SSSZ
              showLocked: boolean
              languages:
                - string
              conceptTestsPerUser: null
              audienceId: null
              conceptTestsToDisplay: {}
              criteria: {}
              projectVariables: {}
              catalog: {}
      responses:
        '200':
          description: Auto Save
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
              example:
                createdAt: '2021-09-16T23:59:03.922Z'
                updatedAt: '2021-09-17T18:56:59.743Z'
                title: string
                logo:
                  url: string
                status: draft
                survey:
                  termsAndConditions: string
                  welcomeText: string
                  endOfSurveyText: string
                  pages: []
                customization:
                  foregroundColor: string
                  backgroundColor: string
                  disableBackButton: boolean
                  showNumbers: boolean
                  paging: none|page|question
                  mobilePaging: none|page|question
                  showTitle: boolean
                  question:
                    font: string
                    color: string
                    align: string
                  answer:
                    font: string
                    color: string
                    align: string
                  progressBar:
                    enabled: boolean
                    type: percent|simple|numeric
                  backgroundImage: {}
                  nextPreviousButton:
                    type: default|simple|bigger
                stats:
                  questions:
                    totalCount: 0
                    contactInfoRelatedItemsCount: 0
                  totalResponsesCount: 0
                  totalTimeToComplete: 0
                hasSignatureConfirmation: true
                isLive: true
                catalog: {}
                id: 6143da47ec80380d3543de6b
                color: 3632a8
                lastResponsesRecreationDate: YYYY-MM-DDTHH:mm:ss.SSSZ
                attributeTranslations: {}
                attributes: []
                availableLanguages: []
                hasAttributeQuestions: false
                languages:
                  - string
                audienceId: null
                conceptTestsPerUser: {}
                conceptTestsToDisplay: {}
                criteria: {}
                errors: {}
                hasConditionalDisplay: boolean
                hasErrors: false
                isPipingFromQuestionEnabled: boolean
                isSkipLogicEnabled: boolean
                isTranslationEnabled: boolean
                projectVariables: {}
                showLocked: boolean
                skipLogicVersion: 3
        '400':
          description: Bad request
        '401':
          description: Unauthorized
        '500':
          description: Internal server error
      servers:
        - url: https://project.sightx.io
components:
  securitySchemes:
    AuthorizationHeader:
      type: apiKey
      in: header
      name: Authorization
      description: Access token obtained from the m2m-token endpoint.

````