---
title: "Restore a post to an earlier version"
method: POST
path: "/cms/posts/{id}/versions/{versionId}/restore"
tags: ["CMS"]
---

# Restore a post to an earlier version

`POST /cms/posts/{id}/versions/{versionId}/restore`

## Request

- Base URL: `https://next.frase.io/api/v1`
- URL: `https://next.frase.io/api/v1/cms/posts/{id}/versions/{versionId}/restore`
- Auth: API key in header `X-API-KEY`

Restore a post's editorial content (title, body, excerpt, SEO fields) to the given version. Status, type, and taxonomy are intentionally not reverted. The restore routes through the normal update path, so it re-runs the content-rules gate: on a live post, a rule violation returns 422 with the violations and a `retry_with_force` hint.

## Path parameters

- `id` string, uuid, required
- `versionId` string, uuid, required

## Response `200`

The updated post

- object
  - `data` CmsPost
    - `id` string, uuid
    - `site_id` string, uuid
    - `slug` string
    - `type` 'blog_post' | 'page'
    - `title` string
    - `content` string: HTML content
    - `excerpt` string, nullable
    - `featured_image` string, uri, nullable
    - `seo_title` string, nullable
    - `seo_description` string, nullable
    - `focus_keyword` string, nullable
    - `canonical_url` string, uri, nullable
    - `schema_markup` object, nullable: JSON-LD structured data for the post. Must include `@context` and `@type`. Additional properties depend on the chosen schema type. See [schema.org](https://schema.org) for full type definitions.
      - `@context` string: Schema.org context URL. Almost always `https://schema.org`.
      - `@type` 'Article' | 'BlogPosting' | 'NewsArticle' | 'FAQPage' | 'HowTo' | 'TechArticle' | 'WebPage': The schema.org type for this content.
      - `headline` string: The headline of the article. Recommended for Article, BlogPosting, NewsArticle.
      - `description` string: A short description or summary of the content.
      - `author` union
        - object: Author as a Person or Organization.
          - `@type` 'Person' | 'Organization'
          - `name` string
          - `url` string, uri
        - object[]: Multiple authors.
          - `@type` 'Person' | 'Organization'
          - `name` string
          - `url` string, uri
      - `datePublished` string, date: Original publication date in ISO 8601 format (e.g., `2026-04-16`).
      - `dateModified` string, date: Last modification date in ISO 8601 format.
      - `image` union: Primary image. Can be a URL string or an ImageObject.
        - string, uri
        - object
          - `@type` 'ImageObject'
          - `url` string, uri
          - `width` integer
          - `height` integer
      - `publisher` object: The publisher of the content.
        - `@type` 'Organization'
        - `name` string
        - `logo` object
          - `@type` 'ImageObject'
          - `url` string, uri
      - `mainEntity` union: Primary entity of the page. Used by FAQPage (array of Question) and HowTo (HowToStep array).
        - object[]: For FAQPage: array of Question objects.
          - `@type` 'Question'
          - `name` string: The question text.
          - `acceptedAnswer` object
            - `@type` 'Answer'
            - `text` string: The answer text.
        - object
      - `step` object[]: For HowTo: ordered list of steps.
        - `@type` 'HowToStep'
        - `name` string: Step title.
        - `text` string: Step instructions.
        - `image` string, uri
    - `status` 'draft' | 'published' | 'scheduled'
    - `published_at` string, date-time, nullable
    - `meta` object, nullable
    - `created_at` string, date-time
    - `updated_at` string, date-time
    - `primary_author` object, nullable: Primary/canonical author, or null.
      - `id` string, uuid, required
      - `name` string, required
      - `slug` string, required
      - `avatar_url` string, uri, nullable
      - `bio` string, nullable
      - `role` string, nullable: e.g. "Head of Content". Set on author creation only; a re-import never overwrites an existing author's role.
    - `authors` object[]: Byline authors (incl. the primary), ordered by position.
      - `id` string, uuid, required
      - `name` string, required
      - `slug` string, required
      - `position` integer, required
      - `avatar_url` string, uri, nullable
      - `role` string, nullable: e.g. "Head of Content". Set on author creation only; a re-import never overwrites an existing author's role.
    - `category` object, nullable: Single category, or null.
      - `id` string, uuid, required
      - `name` string, required
      - `slug` string, required
      - `parent_id` string, uuid, nullable
    - `tags` object[]
      - `id` string, uuid, required
      - `name` string, required
      - `slug` string, required
  - `request_id` string

## Other responses

- `400`: Validation failed
- `401`: Authentication failed
- `404`: Resource not found
- `422`: Restoring this version would violate content rules on a live post
- `429`: Rate limited, or the org's monthly brief limit blocked minting the refreshed brief (only the FIRST supersession of a brief is billing-exempt; repeats meter normally)

---

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