Skip to main content
POST
/
v1
/
pages
/
{page_id}
/
move
TypeScript SDK
import { Client } from "@notionhq/client"

const notion = new Client({ auth: process.env.NOTION_API_KEY })

const response = await notion.pages.move({
  page_id: "b55c9c91-384d-452b-81db-d1ef79372b75",
  parent: {
    page_id: "3c357473-a281-49a4-88c0-10d2b245a589"
  }
})
curl --request POST \
--url https://api.notion.com/v1/pages/{page_id}/move \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Notion-Version: <notion-version>' \
--data '
{
"parent": {
"page_id": "<string>",
"type": "<string>"
}
}
'
import requests

url = "https://api.notion.com/v1/pages/{page_id}/move"

payload = { "parent": {
"page_id": "<string>",
"type": "<string>"
} }
headers = {
"Notion-Version": "<notion-version>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.notion.com/v1/pages/{page_id}/move",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'parent' => [
'page_id' => '<string>',
'type' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Notion-Version: <notion-version>"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"strings"
"net/http"
"io"
)

func main() {

url := "https://api.notion.com/v1/pages/{page_id}/move"

payload := strings.NewReader("{\n \"parent\": {\n \"page_id\": \"<string>\",\n \"type\": \"<string>\"\n }\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Notion-Version", "<notion-version>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.notion.com/v1/pages/{page_id}/move")
.header("Notion-Version", "<notion-version>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"parent\": {\n \"page_id\": \"<string>\",\n \"type\": \"<string>\"\n }\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.notion.com/v1/pages/{page_id}/move")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Notion-Version"] = '<notion-version>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"parent\": {\n \"page_id\": \"<string>\",\n \"type\": \"<string>\"\n }\n}"

response = http.request(request)
puts response.read_body
{
  "object": "<string>",
  "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
{
"object": "<unknown>",
"message": "<string>",
"status": "<unknown>",
"additional_data": {}
}
{
"object": "<unknown>",
"message": "<string>",
"code": "unauthorized",
"status": "<unknown>",
"additional_data": {}
}
{
"object": "<unknown>",
"message": "<string>",
"code": "restricted_resource",
"status": "<unknown>",
"additional_data": {}
}
{
"object": "<unknown>",
"message": "<string>",
"code": "object_not_found",
"status": "<unknown>",
"additional_data": {}
}
{
"object": "<unknown>",
"message": "<string>",
"code": "row_limit_exceeded",
"status": "<unknown>",
"additional_data": {}
}
{
"object": "<unknown>",
"message": "<string>",
"code": "conflict_error",
"status": "<unknown>",
"additional_data": {}
}
{
"object": "<unknown>",
"message": "<string>",
"code": "rate_limited",
"status": "<unknown>",
"additional_data": {}
}
{
"object": "<unknown>",
"message": "<string>",
"code": "internal_server_error",
"status": "<unknown>",
"additional_data": {}
}
{
"object": "<unknown>",
"message": "<string>",
"code": "service_unavailable",
"status": "<unknown>",
"additional_data": {}
}
{
"object": "<unknown>",
"message": "<string>",
"code": "gateway_timeout",
"status": "<unknown>",
"additional_data": {}
}
{
"object": "<unknown>",
"message": "<string>",
"code": "service_overload",
"status": "<unknown>",
"additional_data": {}
}

Authentication

Requires bearer token authentication with appropriate page edit permissions.

Path parameters

page_id (required)
  • Type: string (UUIDv4)
  • Description: The ID of the page to move
    • This must be a regular Notion page, and not a database. Moving databases or other block types in the API is not currently supported.
  • Format: UUIDs can be provided with or without dashes
  • Example: 195de9221179449fab8075a27c979105 or 195de922-1179-449f-ab80-75a27c979105

Body parameters

parent (required)
  • Type: object
  • Description: The new parent location for the page.
    • The bot must have edit access to the new parent.
The parent object can be one of two types:

Page parent

Move the page under another page:
JSON
{
  "parent": {
    "type": "page_id",
    "page_id": "<parent-page-id>"
  }
}
  • type: Always "page_id"
  • page_id: UUID of the parent page (with or without dashes)
Page parent must be a regular Notion pageThe parent[page_id] parameter must be a page and cannot be any other type of block.One limited exception: for databases that only have a single data source , the database_id can be provided under page_id, but this is not recommended, since your connection will start encountering HTTP 400 errors if a second data source is added to the database.

Database parent

Move the page into a database:
JSON
{
  "parent": {
    "type": "data_source_id",
    "data_source_id": "<database-data-source-id>"
  }
}
  • type: Always "data_source_id"
  • data_source_id: UUID of the database’s data source (with or without dashes)
Note: You must use data_source_id rather than database_id. Use the Retrieve a database endpoint to get the child data source ID(s) from the database.

Example requests

Move page under another page

cURL
curl -X POST https://api.notion.com/v1/pages/195de9221179449fab8075a27c979105/move \
  -H "Authorization: Bearer secret_xxx" \
  -H "Notion-Version: 2026-03-11" \
  -H "Content-Type: application/json" \
  -d '{
    "parent": {
      "type": "page_id",
      "page_id": "f336d0bc-b841-465b-8045-024475c079dd"
    }
  }'

Move page into a database

cURL
curl -X POST https://api.notion.com/v1/pages/195de9221179449fab8075a27c979105/move \
  -H "Authorization: Bearer secret_xxx" \
  -H "Notion-Version: 2026-03-11" \
  -H "Content-Type: application/json" \
  -d '{
    "parent": {
      "type": "data_source_id",
      "data_source_id": "1c7b35e6-e67f-8096-bf3f-000ba938459e"
    }
  }'

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Headers

Notion-Version
enum<string>
required

The API version to use for this request. The latest version is 2026-03-11.

Available options:
2026-03-11

Path Parameters

page_id
string
required

The ID of the page to move.

Body

application/json
parent
object
required

The new parent of the page.

Response

object
string
required

The page object type name.

Allowed value: "page"
id
string<uuid>
required

The ID of the page.