---
title: "Migration API Technical Reference"
description: "The Migration API endpoint allows developers to upload pages to a Prismic repository. "
meta_title: "Migration API Technical Reference"
audience: developers
lastUpdated: "2026-04-18T00:30:33.000Z"
---

<MigrationStudyRecruitment />

The Migration API endpoint allows developers to create and update pages in a Prismic repository.

> <CalloutHeading>**Migrating to Prismic?**</CalloutHeading>
>
> For a better understanding of how to work with the Migration API, [see the dedicated Migration article](https://prismic.io/docs/migration.md).

# Usage

The data format for the Migration API is described below. The format follows the response format from the [Content API](https://prismic.io/docs/content-api.md), though the Content API includes properties that are unnecessary for the Migration API.

If you query a page object from the Content API and then send it to the Migration API, the Migration API will ignore the unnecessary properties and accept the rest.

Pages will be created as drafts, which you can publish in your repository.

By default, pages created or updated via the Migration API will be added to a migration release, accessible from the `Migration Releases` tab in your repository.

To include media (images, files, videos) in your pages, you will need to upload the media to your repository (either via the UI or the [Asset API](https://prismic.io/docs/asset-api-technical-reference.md)) and then fetch the ID for the media asset to include in your request to the Migration API.

We recommend saving the `id` from the POST response for each page upon creation, as you will also require this `id` to make updates to existing pages.

> **Important**
>
> <CalloutHeading>You can't publish with the Migration API</CalloutHeading>
>
> Edits posted to the Migration API will be added as drafts. You can review and publish your changes in the Migration Release tab of your repository.
>
> As a security measure, it is impossible to programmatically publish changes in Prismic.

# Limits

* Each request to the API can contain one page, which will be saved in the repository as a draft.
* Requests are limited to one per second per repository.

# Example request body

Here is an example request body with all properties:

```json
{
  "title": "Example page",
  "uid": "example-page",
  "type": "example_type",
  "lang": "en-US",
  "tags": ["Red", "Yellow", "Blue"],
  "alternate_language_id": "ZRFHsxIAAFYAsY--",
  "data": {
    "example_boolean": false,
    "example_color": "#e0dbfd",
    "example_date": "2024-12-23",
    "example_timestamp": "2023-02-20T01:12:12+0100",
    "example_integration": {
      "id": "3"
    },
    "example_shopify_integration": {
      "id": 7505689739510
    },
    "example_embed": {
      "embed_url": "https://www.youtube.com/watch?v=S26CHpcD2zk"
    },
    "example_geopoint": {
      "latitude": "-9",
      "longitude": "-160"
    },
    "example_image_1": {
      "id": "ZMgV5hAAAEADVsPS"
    },
    "example_image_2": {
      "id": "ZMgV5hAAAEADVsPS",
      "alt": "Example alt text",
      "copyright": "Example copyright info",
      "dimensions": {
        "width": 800,
        "height": 200
      },
      "edit": {
        "x": 2,
        "y": 28,
        "zoom": 3,
        "background": "#ffffff"
      },
      "mobile": {
        "id": "ZMgV5hAAAEADVsPS",
        "alt": "this is some alt text",
        "copyright": "some copyright info"
      }
    },
    "example_web_link": {
      "link_type": "Web",
      "text": "Click Here",
      "url": "http://www.prismic.io"
    },
    "example_page_link": {
      "link_type": "Document",
      "id": "ZMI65RQAADkECUFM"
    },
    "example_media_link": {
      "link_type": "Media",
      "id": "ZMgV5hAAAEADVsPS"
    },
    "example_number": 23,
    "example_select": "Apples",
    "example_content_relationship": {
      "link_type": "Document",
      "id": "ZMI65RQAADkECUFM"
    },
    "example_group": [
      {
        "key_text_description": "Lorem",
        "number_price": 55
      },
      {
        "key_text_description": "Ipsum",
        "number_price": 60
      }
    ],
    "example_rich_text": [
      {
        "type": "heading3",
        "text": "This is a heading3",
        "spans": []
      },
      {
        "type": "paragraph",
        "text": "Bold and italic example.",
        "spans": [
          {
            "start": 0,
            "end": 3,
            "type": "strong"
          },
          {
            "start": 8,
            "end": 14,
            "type": "em"
          }
        ]
      },
      {
        "type": "image",
        "id": "ZPrkIhYAACcAYvyB",
        "alt": "Example alt text",
        "copyright": null,
        "dimensions": {
          "width": "512",
          "height": "512"
        }
      },
      {
        "type": "embed",
        "oembed": {
          "embed_url": "https://prismic.io/"
        }
      }
    ],
    "//": "The default slice zone is 'slices'",
    "slices": [
      {
        "variation": "default",
        "primary": {
          "example_number": 11
        },
        "slice_type": "example_slice_type_1"
      }
    ],
    "example_slice_zone": [
      {
        "variation": "example_variation",
        "items": [
          {
            "example_select": "Dog"
          }
        ],
        "slice_type": "example_slice_type_2"
      }
    ]
  }
}
```

# Headers

These headers should be included with each request to the Migration API.

<Table>
  <tbody>
    <tr>
      <TableCell>`Authorization`</TableCell> <TableCell>A [permanent token](https://prismic.io/docs/custom-types-api.md).</TableCell>
    </tr>

    <tr>
      <TableCell>`repository`</TableCell> <TableCell>The repository ID (e.g. `your-repo-name`).</TableCell>
    </tr>
  </tbody>
</Table>

# Methods

## POST

Create a page.

```
https://migration.prismic.io/documents
```

The JSON body of every POST request must contain the following required properties:

* `title`
* `type`
* `uid` (if present on type)
* `lang`
* `data`
* `alternate_language_id` (if creating a localized version of a singleton type)

## PUT

Update a page.

```
https://migration.prismic.io/documents/:id/
```

`:id` is the ID for an existing page.

The JSON body of every PUT request must contain the following required properties:

* `uid` (if present on type)
* `data`

The body can also include the following optional properties:

* `title`
* `tags`

The following properties cannot be modified on PUT requests and will be ignored if they are included in the body:

* `type`
* `lang`
* `alternate_language_id`

# Body

<Table>
  <tbody>
    <tr>
      <TableCell>`title`</TableCell> <TableCell>A display title to appear in the page list.</TableCell>
    </tr>

    <tr>
      <TableCell>`type`</TableCell> <TableCell>ID of the page’s type. Required for POST requests.</TableCell>
    </tr>

    <tr>
      <TableCell>`lang`</TableCell> <TableCell>The page’s locale.</TableCell>
    </tr>

    <tr>
      <TableCell>`data`</TableCell>

      <TableCell>
        An object containing the content of the page. Each key in the object should be a field or slice zone, and each value should be the content. (See the structure of the fields below.)
      </TableCell>
    </tr>

    <tr>
      <TableCell>`tags`</TableCell>

      <TableCell>
        An optional list of tags for the page. (Existing tags will be deleted if this property is omitted in a PUT request.)
      </TableCell>
    </tr>

    <tr>
      <TableCell>`uid`</TableCell>

      <TableCell>
        The page’s UID, which must be unique to that type. Required if present on the type and disallowed if absent on the type.
      </TableCell>
    </tr>

    <tr>
      <TableCell>`alternate_language_id`</TableCell>

      <TableCell>
        An optional ID for the page for which you are creating a translation.
      </TableCell>
    </tr>
  </tbody>
</Table>

# Data

The `data` property represents the content of the page. Each key in the data object should be a `field` or `slice zone` on the page type, and the value should be the content.

The content of `data` must conform to the structure of the page type.

## Boolean: null | boolean

If the field has a default value configured, the default value will be used for null values.

## Color: null | string

The string must be a hexadecimal color value.

## Content relationship: object

Same as the value for a link with a `link_type` of `"Document"`.

## Date: null | string

The string must match the format `YYYY-MM-DD`.

## Embed: object

The object can optionally contain an `embed_url` property with a URL as its value. Other properties will be ignored.

## Geopoint: object

An empty object or an object with `latitude` and `longitude` properties, each with a value string representing a number. The value of `latitude` must be between -90 and 90. The value of `longitude` must be between -180 and 180.

## Group: array

An array of field objects.

## Image: object

An object with the required property `id` and optional properties `alt`, `copyright`, `dimensions`, `edit`, `x`, `y`, `zoom`, and `background`.

<Table>
  <tbody>
    <tr>
      <TableCell>`id` string (required)</TableCell>

      <TableCell>
        A string that exactly matches the ID of an exiting image in Prismic’s media library.
      </TableCell>
    </tr>

    <tr>
      <TableCell>`alt` string</TableCell> <TableCell>The alt text for the image.</TableCell>
    </tr>

    <tr>
      <TableCell>`copyright` string</TableCell> <TableCell>Copyright information for the image.</TableCell>
    </tr>

    <tr>
      <TableCell>`dimensions` object</TableCell>

      <TableCell>
        An object with optional `width` and `height` properties, with numbers for their values, defining the image resize.

        <br />

        If thumbnail width or height is already configured in the type, this value will be ignored.
      </TableCell>
    </tr>

    <tr>
      <TableCell>`edit` object</TableCell>

      <TableCell>
        Parameters for editing the image. The object can contain: <br /> -`x`: X coordinate for crop as an integer <br /> -`y`: Y coordinate for crop as an integer <br /> -`zoom`: Zoom level as an integer <br /> -`background`: Background color as a hexadecimal code (defaults to transparent for PNGs and `#ffffff` for other file types)
      </TableCell>
    </tr>
  </tbody>
</Table>

The image object can also include thumbnail properties. Each thumbnail is a top-level key (for example, `mobile` or `tablet`), and its value is an object with the same fields as an image, as described in the table above.

## Integration: string | number

The ID of an item from your integration.

For shopify integration, the ID comes from your Shopify catalog. For [Custom API format](https://prismic.io/docs/integration#custom-api-format), the ID property is defined by the endpoint and duplicated in `blob`. See the [Integration docs](https://prismic.io/docs/integration#sync-with-a-shopify-catalog) for more information.

## Key text: string

A string of text.

## Link: object

An object with the required property `link_type` and conditional properties depending on the type.

<Table>
  <tbody>
    <tr>
      <TableCell>`link_type` string (required)</TableCell> <TableCell>One of `"Document"`, `"Web"`, or `"Media"`.</TableCell>
    </tr>

    <tr>
      <TableCell>`id` string</TableCell>

      <TableCell>
        Required if `link_type` is `"Document"` or `"Media"`. For `"Document"`, `id` must be the ID of any page in the repository, published or unpublished. For `"Media"`, `id` must be the ID of an item from the Media Library.
      </TableCell>
    </tr>

    <tr>
      <TableCell>`url` string</TableCell>

      <TableCell>
        Required if `link_type` is `"Web"`. An absolute URL.
      </TableCell>
    </tr>

    <tr>
      <TableCell>`target` string</TableCell>

      <TableCell>
        Where to open the linked URL (optional). Only accepts `_"__blank"`, to open links in a new window.
      </TableCell>
    </tr>

    <tr>
      <TableCell>`text` string</TableCell> <TableCell>The optional display text of the link</TableCell>
    </tr>
  </tbody>
</Table>

## Number: null | number

Value must conform to `max` and `min` if either is defined in the type.

## Rich text: array

An array in which each object represents a block element.

A rich text field must contain an array of content blocks. Every block must have a `type` property with one of the following values:

* `"paragraph"`
* `"o-list-item"`
* `"list-item"`
* `"heading1"`
* `"heading2"`
* `"heading3"`
* `"heading4"`
* `"heading5"`
* `"heading6"`
* `"preformatted"`
* `"embed"`
* `"image"`

Every block **except** for those with a type of embed or image can have the following properties:

<Table>
  <tbody>
    <tr>
      <TableCell>`text` string (required)</TableCell> <TableCell>The text content of the block.</TableCell>
    </tr>

    <tr>
      <TableCell>`spans` array</TableCell>

      <TableCell>
        An array of objects describing inline markup. Each object must have a type with the value of either `"em"`, `"strong"`, or `"hyperlink"`. Each object must also have `start` and `end` properties denoting the starting and ending indexes of the span. Spans can overlap. Spans of type `hyperlink` must also have the properties defined for a link field.
      </TableCell>
    </tr>

    <tr>
      <TableCell>`direction` string</TableCell>

      <TableCell>
        Value can only be `"rtl"`, which defines the text as right-to-left.
      </TableCell>
    </tr>

    <tr>
      <TableCell>`oembed` object</TableCell>

      <TableCell>
        Required only for blocks with a `type` of `"embed"`. The object should contain an `embed_url` property with an absolute URL as the value.
      </TableCell>
    </tr>
  </tbody>
</Table>

Blocks with a type of `"image"` must have the properties defined for the image field.

## Select: null | string

If value is a string, the string must match one of the options defined in the type. If the field has a default value configured, it will be used for null values.

## Slice zone: array

Each slice zone property must be an array of zero or more slice objects. By default, all types in Prismic have a slice zone property called `slices`, but the developer can change the name of the slice zone and add other slice zones.

Each slice object must have the following properties:

<Table>
  <tbody>
    <tr>
      <TableCell>`slice_type` string (required)</TableCell> <TableCell>The ID of the slice type (e.g. `"hero_image"`).</TableCell>
    </tr>

    <tr>
      <TableCell>`variation` string (required)</TableCell>

      <TableCell>
        Must match one of the variations defined in the configuration for the slice type, even if there is only one variation. The default variation for slice types is called `default`.
      </TableCell>
    </tr>

    <tr>
      <TableCell>`id` string</TableCell>

      <TableCell>
        A optional string in the following format: `slice_type` + `$` + `uuid
                v4`. Must be unique within the page. If omitted, it will be generated automatically.
      </TableCell>
    </tr>

    <tr>
      <TableCell>`slice_label` string</TableCell>

      <TableCell>
        A label that will appear in the Content API response. If omitted, it will be set to `null`.
      </TableCell>
    </tr>

    <tr>
      <TableCell>`primary` object</TableCell> <TableCell>An object containing the fields of the slice.</TableCell>
    </tr>

    <tr>
      <TableCell>`items` array</TableCell>

      <TableCell>
        An array of objects containing the fields of the repeatable zone of the slice (deprecated).
      </TableCell>
    </tr>
  </tbody>
</Table>

## Timestamp: null | string

The string must match the format `YYYY-MM-DDTHH:MM:SS+0000`.

# Errors

In addition to an error code, detailed error messages are displayed in the JSON body of the response. Enable your user agent to receive the error response body.<br />

* **Example 1:**

  ```json
  [
    {
      "property": "data.richtext.2.type",
      "value": "heading2",
      "error": "Invalid block type. Supported block types are: paragraph, embed"
    }
  ]
  ```

* **Example 2:**

  ```json
  [
    {
      "property": "title",
      "error": "The value must be a string"
    }
  ]
  ```
