---
title: "Restore a creative"
method: POST
path: "/api/v3/creatives/{creativeId}/restore"
tags: ["V3 Creatives"]
---

# Restore a creative

`POST /api/v3/creatives/{creativeId}/restore`

## Request

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

Brings an archived creative back, always as a **draft**, whatever status it had: it never reappears on a site by surprise, and showing it again means publishing it again. Its content, styling and counts come back as they were, and so does its Destination, unless its survey can no longer be one (it became Restricted, single-use or PIN-protected), in which case it is unlinked now. `publishedAt` keeps when it was first published. Restoring a creative that isn't archived changes nothing. Read/write access to its workspace; an unknown or inaccessible `creativeId` answers **403**.

## Path parameters

- `creativeId` string, cuid2, required

## Response `200`

Creative restored

- object
  - `data` union, required: A creative: a page element the web SDK renders on the customer's site next to surveys, with its own content, look, display rules and schedule. `type` selects the `content` and `styling` shape: switch on it. The writable groups are `name`, `status`, `defaultLanguage` with `languages`, `autoSelectLanguage`, `content`, `styling`, `destination`, `distribution` and `schedule`; a `PATCH` replaces each group it sends as a whole. `displayStatus`, `displayStatusReason`, `warnings`, the timestamps, `creator` and `destination.opensAs` are read-only.
    - FeedbackButtonCreative: A feedback button.
      - `id` string, cuid2, required
      - `workspaceId` string, cuid2, required
      - `name` string, required: Internal name, shown to authors only. Never shown or announced to visitors.
      - `type` 'feedbackButton', required: The kind of creative, which fixes its `content` and `styling` shape. A `feedbackButton` is a tab on an edge of the page that always opens its Destination; a `banner` is a bar across the top or bottom of the page with a message and an optional button. Fixed at creation: it can never change.
      - `status` 'draft' | 'inProgress' | 'paused' | 'completed', required: The author's intent, and the only status a write sets: `draft` (never published), `inProgress` (published), `paused` (paused by its author) or `completed` (closed by its author). The same values as a survey's `status`. What visitors get is `displayStatus`, which the server derives from this value, `archivedAt`, the schedule and the Destination survey. Nothing writes `status` on its own: a schedule ending or a survey pausing changes `displayStatus` only.
      - `displayStatus` 'draft' | 'scheduled' | 'active' | 'paused' | 'closed' | 'archived', required: What the creative is doing now, derived in this order: `archived` when archived; `draft` and `closed` (status `completed`) when the author said so; `closed` when the schedule's `endAt` has passed; `paused` when the author paused it; `scheduled` before the schedule's `startAt`; `paused` when its Destination survey isn't active (not `inProgress`, or archived); otherwise `active`.
      - `displayStatusReason` 'surveyNotActive' | 'scheduleEnded' | 'destinationMissing' | 'actionMissing' | 'null', nullable, required: Why `displayStatus` differs from what `status` alone would give: `surveyNotActive` on a `paused` creative whose Destination survey isn't active ("Paused with its survey": it comes back by itself when the survey is active again), `scheduleEnded` on a `closed` creative whose `endAt` has passed, `destinationMissing` on a `paused` creative that needs a Destination (a feedback button, or a banner with a button) and has none, and `actionMissing` on a `paused` creative that shows on an action and has none. Sites never show a creative paused for either of the last two until it gets what it lacks (see `warnings`). `null` otherwise. New values may be added.
      - `createdAt` string, date-time, required
      - `updatedAt` string, date-time, required
      - `publishedAt` string, date-time, nullable, required: When the creative was first published; `null` while it has never been.
      - `archivedAt` string, date-time, nullable, required: When the creative was archived; `null` unless it is archived.
      - `creator` object, nullable, required: The user who created the creative, or `null` for one created with an API key.
        - `name` string, required
      - `defaultLanguage` string, required: Canonical locale code accepted by v3 survey APIs, for example `en-US`, `de-DE`, or `zh-Hans-CN`.
      - `languages` CreativeLanguage[], required: Every language the texts are written in, the default first.
        - `code` string, required: Canonical locale code accepted by v3 survey APIs, for example `en-US`, `de-DE`, or `zh-Hans-CN`.
        - `default` boolean, required: Whether this is `defaultLanguage`. Exactly one entry is the default.
        - `enabled` boolean, required: Whether visitors in this language see this translation. The default language is always enabled; a disabled or missing translation falls back to the default language.
      - `autoSelectLanguage` boolean, nullable, required: Show the texts in the visitor's browser language when the site sets none with `setLanguage` and it matches the default or an enabled language; otherwise the default language is used. `null` (never chosen) and `false` both mean off.
      - `destination` union, required: What the creative opens when pressed, with the read-only `opensAs`. A write takes `CreativeDestinationInput`, which carries neither `opensAs` nor `surveyName`.
        - CreativeSurveyDestination: The survey the creative opens.
          - `type` 'survey', required
          - `surveyId` string, cuid2, required
          - `surveyName` string, required
          - `opensAs` 'popup' | 'newTab', required: Follows the survey's type: an app survey opens as a popup in its own placement, a link survey in a new tab.
        - CreativeLinkDestination: The link the creative opens.
          - `type` 'link', required
          - `url` string, required
          - `opensAs` 'newTab', required: A link always opens in a new tab.
      - `distribution` CreativeDistribution, required: When the creative shows. `showOn: pageView` shows it on every page view; `showOn: action` only when one of `triggers` fires, and publishing needs at least one. `triggers` must be empty with `pageView`. A creative never falls back to every page view. `conditions` (Show when) narrows either, and `displayPercentage` (Share of visitors) shows it to that share of visitors, each decided once and kept on every page; `null` means everyone.
        - `showOn` 'pageView' | 'action', required
        - `triggers` CreativeTrigger[], required: Each id must name an action class in the creative's workspace, at most once; an unknown or repeated id answers **422**.
          - `actionClassId` string, cuid2, required: Id of an action class in the creative's workspace.
        - `conditions` ShowConditionGroup, required: Show when: the page, visit and device conditions that must hold, joined by `connector`. The same conditions surveys use. At most 20 conditions in all, groups nested at most two levels deep, and 10 240 characters of JSON; a set beyond those answers **400**. Empty groups are dropped on write, and a top-level group left empty is stored as `null` (always show).
          - `id` string, cuid2, required
          - `connector` 'and' | 'or', required
          - `conditions` union[], required
            - union
              - …
        - `displayPercentage` number, nullable, required
      - `schedule` CreativeSchedule, required: When a published creative shows, to the minute. Before `startAt` it is `scheduled`; from `endAt` on it is `closed`. `null` leaves that side open. `endAt` must be after `startAt`, or the write answers **422**.
        - `startAt` string, date-time, nullable, required
        - `endAt` string, date-time, nullable, required
      - `warnings` CreativeWarning[], required
        - `code` 'destinationMissing' | 'destinationNotAllowed' | 'actionMissing', required
        - `message` string, required: The same warning in English, for people.
      - `content` FeedbackButtonContent, required: What a feedback button shows.
        - `label` CreativeText, required: Plain text per language, keyed by locale code. Must hold `defaultLanguage`; every other key must be declared in `languages`. A visitor whose language is missing sees the default language.
        - `icon` 'messageSquare' | 'messageCircle' | 'megaphone' | 'sparkles' | 'null', nullable, required: An icon before the label, or `null` for none.
      - `styling` FeedbackButtonStyling, required: A feedback button's position and custom styles. The position applies whether or not custom styles are on.
        - `position` object, required
          - `desktop` FeedbackButtonPlacement, required: Where a feedback button sits: an edge of the page plus an offset along it, in percent, that places the button's centre. On the left and right edges the offset runs from the top; on the bottom edge, from the left. 50 centres the button on its edge. Near either end the button stops at the end of the edge instead, so it stays fully on screen: 0 puts its top (or left) end at the start of the edge and 100 its bottom (or right) end at the end.
            - `edge` 'left' | 'right' | 'bottom', required
            - `offset` integer, required
          - `phone` FeedbackButtonPlacement, required: Where a feedback button sits: an edge of the page plus an offset along it, in percent, that places the button's centre. On the left and right edges the offset runs from the top; on the bottom edge, from the left. 50 centres the button on its edge. Near either end the button stops at the end of the edge instead, so it stays fully on screen: 0 puts its top (or left) end at the start of the edge and 100 its bottom (or right) end at the end.
            - `edge` 'left' | 'right' | 'bottom', required
            - `offset` integer, required
        - `theme` FeedbackButtonTheme, required: The feedback button's custom styles. With `customStyles` off the button follows the workspace Look & Feel (the survey button) and the values below are kept but not applied. With it on, each value overrides the workspace one; `null` keeps the workspace value. A colour has a `light` value and an optional `dark` one for the visitor's dark appearance. Without a `dark` value: when the background or the text colour is set, both keep their light values in dark appearance so their contrast holds, a background set without a text colour gets readable text (`#0f172a` or `#ffffff`) in each appearance, and a border keeps its light value. Colours left to the workspace follow its dark palette when the visitor's appearance is dark. Sizes and the position apply in both appearances.
          - `customStyles` boolean, required: The "Add custom styles" switch.
          - `backgroundColor` CreativeColor, required: A custom colour per appearance, `#rrggbb`, as the survey styling stores its colours. `light` applies in light appearance. `dark` applies when the visitor's appearance is dark; `null` (or absent) derives it as the theme describes.
            - `light` string, required
            - `dark` string, nullable
          - `textColor` CreativeColor, required: A custom colour per appearance, `#rrggbb`, as the survey styling stores its colours. `light` applies in light appearance. `dark` applies when the visitor's appearance is dark; `null` (or absent) derives it as the theme describes.
            - `light` string, required
            - `dark` string, nullable
          - `borderColor` CreativeColor, required: A custom colour per appearance, `#rrggbb`, as the survey styling stores its colours. `light` applies in light appearance. `dark` applies when the visitor's appearance is dark; `null` (or absent) derives it as the theme describes.
            - `light` string, required
            - `dark` string, nullable
          - `borderRadius` integer, nullable, required: Corner radius in px.
          - `fontWeight` 400 | 500 | 600 | 700 | null, nullable, required
          - `fontSize` CreativeFontSize, required: Font size in px, per device. `phone` applies below 768 px viewport width; `null` there uses the `desktop` value, and `null` on `desktop` uses the workspace Look & Feel.
            - `desktop` integer, nullable, required
            - `phone` integer, nullable, required
          - `paddingX` CreativePadding, required: Padding in px, per device. `phone` applies below 768 px viewport width; `null` there uses the `desktop` value, and `null` on `desktop` uses the workspace Look & Feel.
            - `desktop` integer, nullable, required
            - `phone` integer, nullable, required
          - `paddingY` CreativePadding, required: Padding in px, per device. `phone` applies below 768 px viewport width; `null` there uses the `desktop` value, and `null` on `desktop` uses the workspace Look & Feel.
            - `desktop` integer, nullable, required
            - `phone` integer, nullable, required
          - `pageFont` boolean, nullable: Page font: `true` renders in the host page's font, `false` in the survey font, `null` (or absent) follows the workspace's Page font setting. Applies only with `customStyles` on.
          - `customCss` CustomCssInput: Custom CSS **source** as a caller writes it (ENG-3641). Both keys are required. `light` is base CSS that applies in both appearances; `dark` adds overrides on top of it when the survey renders dark. `null`, an empty string or whitespace means "no CSS" for that field. Source only: compiled output and the processor version are computed by the server on every write, and a request that supplies either is rejected. The combined source is limited to 100 000 UTF-8 bytes for a workspace and 20 000 for a survey; larger CSS is a **422** with error code `source_too_large`.
            - `light` string, nullable, required: Base CSS, applied in light and dark appearance.
            - `dark` string, nullable, required: Additional CSS applied only in dark appearance.
    - BannerCreative: A banner.
      - `id` string, cuid2, required
      - `workspaceId` string, cuid2, required
      - `name` string, required: Internal name, shown to authors only. Never shown or announced to visitors.
      - `type` 'banner', required: The kind of creative, which fixes its `content` and `styling` shape. A `feedbackButton` is a tab on an edge of the page that always opens its Destination; a `banner` is a bar across the top or bottom of the page with a message and an optional button. Fixed at creation: it can never change.
      - `status` 'draft' | 'inProgress' | 'paused' | 'completed', required: The author's intent, and the only status a write sets: `draft` (never published), `inProgress` (published), `paused` (paused by its author) or `completed` (closed by its author). The same values as a survey's `status`. What visitors get is `displayStatus`, which the server derives from this value, `archivedAt`, the schedule and the Destination survey. Nothing writes `status` on its own: a schedule ending or a survey pausing changes `displayStatus` only.
      - `displayStatus` 'draft' | 'scheduled' | 'active' | 'paused' | 'closed' | 'archived', required: What the creative is doing now, derived in this order: `archived` when archived; `draft` and `closed` (status `completed`) when the author said so; `closed` when the schedule's `endAt` has passed; `paused` when the author paused it; `scheduled` before the schedule's `startAt`; `paused` when its Destination survey isn't active (not `inProgress`, or archived); otherwise `active`.
      - `displayStatusReason` 'surveyNotActive' | 'scheduleEnded' | 'destinationMissing' | 'actionMissing' | 'null', nullable, required: Why `displayStatus` differs from what `status` alone would give: `surveyNotActive` on a `paused` creative whose Destination survey isn't active ("Paused with its survey": it comes back by itself when the survey is active again), `scheduleEnded` on a `closed` creative whose `endAt` has passed, `destinationMissing` on a `paused` creative that needs a Destination (a feedback button, or a banner with a button) and has none, and `actionMissing` on a `paused` creative that shows on an action and has none. Sites never show a creative paused for either of the last two until it gets what it lacks (see `warnings`). `null` otherwise. New values may be added.
      - `createdAt` string, date-time, required
      - `updatedAt` string, date-time, required
      - `publishedAt` string, date-time, nullable, required: When the creative was first published; `null` while it has never been.
      - `archivedAt` string, date-time, nullable, required: When the creative was archived; `null` unless it is archived.
      - `creator` object, nullable, required: The user who created the creative, or `null` for one created with an API key.
        - `name` string, required
      - `defaultLanguage` string, required: Canonical locale code accepted by v3 survey APIs, for example `en-US`, `de-DE`, or `zh-Hans-CN`.
      - `languages` CreativeLanguage[], required: Every language the texts are written in, the default first.
        - `code` string, required: Canonical locale code accepted by v3 survey APIs, for example `en-US`, `de-DE`, or `zh-Hans-CN`.
        - `default` boolean, required: Whether this is `defaultLanguage`. Exactly one entry is the default.
        - `enabled` boolean, required: Whether visitors in this language see this translation. The default language is always enabled; a disabled or missing translation falls back to the default language.
      - `autoSelectLanguage` boolean, nullable, required: Show the texts in the visitor's browser language when the site sets none with `setLanguage` and it matches the default or an enabled language; otherwise the default language is used. `null` (never chosen) and `false` both mean off.
      - `destination` union, required: What the creative opens when pressed, with the read-only `opensAs`. A write takes `CreativeDestinationInput`, which carries neither `opensAs` nor `surveyName`.
        - CreativeSurveyDestination: The survey the creative opens.
          - `type` 'survey', required
          - `surveyId` string, cuid2, required
          - `surveyName` string, required
          - `opensAs` 'popup' | 'newTab', required: Follows the survey's type: an app survey opens as a popup in its own placement, a link survey in a new tab.
        - CreativeLinkDestination: The link the creative opens.
          - `type` 'link', required
          - `url` string, required
          - `opensAs` 'newTab', required: A link always opens in a new tab.
      - `distribution` CreativeDistribution, required: When the creative shows. `showOn: pageView` shows it on every page view; `showOn: action` only when one of `triggers` fires, and publishing needs at least one. `triggers` must be empty with `pageView`. A creative never falls back to every page view. `conditions` (Show when) narrows either, and `displayPercentage` (Share of visitors) shows it to that share of visitors, each decided once and kept on every page; `null` means everyone.
        - `showOn` 'pageView' | 'action', required
        - `triggers` CreativeTrigger[], required: Each id must name an action class in the creative's workspace, at most once; an unknown or repeated id answers **422**.
          - `actionClassId` string, cuid2, required: Id of an action class in the creative's workspace.
        - `conditions` ShowConditionGroup, required: Show when: the page, visit and device conditions that must hold, joined by `connector`. The same conditions surveys use. At most 20 conditions in all, groups nested at most two levels deep, and 10 240 characters of JSON; a set beyond those answers **400**. Empty groups are dropped on write, and a top-level group left empty is stored as `null` (always show).
          - `id` string, cuid2, required
          - `connector` 'and' | 'or', required
          - `conditions` union[], required
            - union
              - …
        - `displayPercentage` number, nullable, required
      - `schedule` CreativeSchedule, required: When a published creative shows, to the minute. Before `startAt` it is `scheduled`; from `endAt` on it is `closed`. `null` leaves that side open. `endAt` must be after `startAt`, or the write answers **422**.
        - `startAt` string, date-time, nullable, required
        - `endAt` string, date-time, nullable, required
      - `warnings` CreativeWarning[], required
        - `code` 'destinationMissing' | 'destinationNotAllowed' | 'actionMissing', required
        - `message` string, required: The same warning in English, for people.
      - `content` BannerContent, required: What a banner shows.
        - `message` CreativeRichText, required: Formatted text per language, keyed by locale code: each value is the text as a list of runs. Must hold `defaultLanguage`; every other key must be declared in `languages`.
        - `button` BannerButton, required: The button inside a banner. Pressing it opens the creative's Destination.
          - `label` CreativeText, required: Plain text per language, keyed by locale code. Must hold `defaultLanguage`; every other key must be declared in `languages`. A visitor whose language is missing sees the default language.
        - `dismissible` boolean, required: Whether visitors can close the banner. A dismissed banner stays closed for the rest of the visit, in that browser tab; a new tab shows it again.
        - `accessibleName` CreativeText, required: Plain text per language, keyed by locale code. Must hold `defaultLanguage`; every other key must be declared in `languages`. A visitor whose language is missing sees the default language.
      - `styling` BannerStyling, required: A banner's position and custom styles. The position applies whether or not custom styles are on.
        - `position` object, required
          - `desktop` union, required: Where a banner sits and how it lays out. A bottom banner is always an overlay.
            - BannerTopPlacement: A banner at the top of the page, either `inPage` (in the page flow, scrolling away with it) or `overlay` (fixed and always visible).
              - …
            - BannerBottomPlacement: A banner at the bottom of the page, which is always `overlay`.
              - …
          - `phone` union, required: Where a banner sits and how it lays out. A bottom banner is always an overlay.
            - BannerTopPlacement: A banner at the top of the page, either `inPage` (in the page flow, scrolling away with it) or `overlay` (fixed and always visible).
              - …
            - BannerBottomPlacement: A banner at the bottom of the page, which is always `overlay`.
              - …
        - `theme` BannerTheme, required: The banner's custom styles. With `customStyles` off the banner follows the workspace Look & Feel (the survey card, with the survey button inside) and the values below are kept but not applied. With it on, each value overrides the workspace one; `null` keeps the workspace value. A colour has a `light` value and an optional `dark` one for the visitor's dark appearance. Without a `dark` value: when the background or the text colour is set, both keep their light values in dark appearance so their contrast holds, a background set without a text colour gets readable text (`#0f172a` or `#ffffff`) in each appearance, and a border keeps its light value. Colours left to the workspace follow its dark palette when the visitor's appearance is dark. Sizes and the position apply in both appearances. The banner's button always looks like the survey button.
          - `customStyles` boolean, required: The "Add custom styles" switch.
          - `backgroundColor` CreativeColor, required: A custom colour per appearance, `#rrggbb`, as the survey styling stores its colours. `light` applies in light appearance. `dark` applies when the visitor's appearance is dark; `null` (or absent) derives it as the theme describes.
            - `light` string, required
            - `dark` string, nullable
          - `textColor` CreativeColor, required: A custom colour per appearance, `#rrggbb`, as the survey styling stores its colours. `light` applies in light appearance. `dark` applies when the visitor's appearance is dark; `null` (or absent) derives it as the theme describes.
            - `light` string, required
            - `dark` string, nullable
          - `borderColor` CreativeColor, required: A custom colour per appearance, `#rrggbb`, as the survey styling stores its colours. `light` applies in light appearance. `dark` applies when the visitor's appearance is dark; `null` (or absent) derives it as the theme describes.
            - `light` string, required
            - `dark` string, nullable
          - `fontWeight` 400 | 500 | 600 | 700 | null, nullable, required
          - `fontSize` CreativeFontSize, required: Font size in px, per device. `phone` applies below 768 px viewport width; `null` there uses the `desktop` value, and `null` on `desktop` uses the workspace Look & Feel.
            - `desktop` integer, nullable, required
            - `phone` integer, nullable, required
          - `paddingX` CreativePadding, required: Padding in px, per device. `phone` applies below 768 px viewport width; `null` there uses the `desktop` value, and `null` on `desktop` uses the workspace Look & Feel.
            - `desktop` integer, nullable, required
            - `phone` integer, nullable, required
          - `paddingY` CreativePadding, required: Padding in px, per device. `phone` applies below 768 px viewport width; `null` there uses the `desktop` value, and `null` on `desktop` uses the workspace Look & Feel.
            - `desktop` integer, nullable, required
            - `phone` integer, nullable, required
          - `pageFont` boolean, nullable: Page font: `true` renders in the host page's font, `false` in the survey font, `null` (or absent) follows the workspace's Page font setting. Applies only with `customStyles` on.
          - `customCss` CustomCssInput: Custom CSS **source** as a caller writes it (ENG-3641). Both keys are required. `light` is base CSS that applies in both appearances; `dark` adds overrides on top of it when the survey renders dark. `null`, an empty string or whitespace means "no CSS" for that field. Source only: compiled output and the processor version are computed by the server on every write, and a request that supplies either is rejected. The combined source is limited to 100 000 UTF-8 bytes for a workspace and 20 000 for a survey; larger CSS is a **422** with error code `source_too_large`.
            - `light` string, nullable, required: Base CSS, applied in light and dark appearance.
            - `dark` string, nullable, required: Additional CSS applied only in dark appearance.

## Other responses

- `400`: Bad Request — malformed JSON, invalid query/body/params, duplicate name, or unsupported field.
- `401`: Not authenticated (no valid session or API key).
- `403`: Forbidden, one of two codes. `forbidden`: the caller lacks the workspace access the operation needs, or the creative does not exist (404 is not used, so creative ids cannot be probed for existence). `creatives_not_entitled`: Creatives is not available on this instance (Formbricks Cloud, or a self-hosted license that does not include it). It is checked only after the caller's own access, so it says nothing about a workspace the caller cannot see. A workspace that still has creatives is in wind-down: listing, reading, stats, a PATCH that sets nothing but `status` to `paused` or `completed`, pausing a survey's creatives (`POST /api/v3/creatives/pause`), and DELETE keep working, and everything else answers this. A workspace without creatives answers it on every operation.
- `429`: Rate limit exceeded.
- `500`: Internal Server Error.

## Changes

- **2026-11-02** `03d5b9b896e2`: 2 info
  - added the required property `data/oneOf[#/components/schemas/BannerCreative]/allOf[#/components/schemas/CreativeResourceBase]/autoSelectLanguage` to the response with the `200` status
  - added the required property `data/oneOf[#/components/schemas/FeedbackButtonCreative]/allOf[#/components/schemas/CreativeResourceBase]/autoSelectLanguage` to the response with the `200` status
- **2026-10-28** `84820a01e550`: 15 warning
  - added the new `chart_in_use` enum value to the `code` response property for the response status `400`
  - added the new `chart_in_use` enum value to the `code` response property for the response status `401`
  - added the new `chart_in_use` enum value to the `code` response property for the response status `403`
  - added the new `chart_in_use` enum value to the `code` response property for the response status `429`
  - …11 more
- **2026-10-27** `aad5dc1d8236`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/formbricks/apis/formbricks-api-v3/changes/api/v3/creatives/:creativeId/restore/post.md)

---

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