Skip to content

Move or reorder a collection page ​

PATCH/api/v2/workspaces/{slug}/collections/{pk}/pages/{page_id}/

Move a page from this collection into another one, change where it sits, or both, in one call. {page_id} is the page itself, the same id that Add or remove pages in a collection takes. The page must already be in collection {pk}.

Use this instead of a remove followed by an add. A move here keeps the page's single membership row and lets you set its position in the target collection at the same time.

The response is the page's membership row, not the page. Its sort_order is the page's position in the collection.

Path Parameters ​

slug:requiredstring

The workspace slug. It appears in your Plane URLs. In https://app.plane.so/my-team/projects/, the slug is my-team.

pk:requiredstring (uuid)

The collection the page is in now.

page_id:requiredstring (uuid)

The page to move or reorder. A page that isn't in collection {pk} returns 404, even if it exists in another collection.

Body Parameters ​

All three fields are optional, and you can combine them. With an empty body nothing changes, and the call returns the current row.

collection_id:optionalstring (uuid)

The collection to move the page into. Omit it, or send the current collection's id, to reorder in place. A collection that doesn't exist or that you can't see returns 400 with an errors entry for collection_id. The page's nested pages follow it to the new collection.

sort_order:optionalnumber

The page's new position, as a number. Lower values sort first. The server ignores it when you also send placement.

placement:optionalobject

Let the server work out the sort_order from a neighbor, so you don't have to read the branch first. When you also send collection_id, the placement applies in the target collection. Placing a page can renumber its siblings' positions to make room. Keys:

  • type (string, required). One of append (last in the branch), before, or after.
  • target_page_id (string, uuid). The neighbor to place the page next to. Required when type is before or after. It must be in the same branch, or the call returns 400.
  • parent_id (string, uuid, nullable). The parent page whose children form the branch. Omit it, or send null, for the collection's top level. It selects the branch to order within. It doesn't change the page's parent.

Response shaping ​

fields:optionalstring

Comma-separated list of fields to return. Unrequested keys are omitted from the response, not returned as null, so absent means "not requested" and null means "actually null". id always comes back whether or not you name it.

Pass all for every requestable field. An unknown name is a 400 that lists the valid set and suggests the closest match, so a typo can't silently cost you the saving.

Requestable here: collection_id, created_at, created_by_id, id, page_id, sort_order.

See Sparse fields.

Scopes ​

wiki.pages:write

Errors ​

StatusCodeCause
400invalid_requestUnknown target collection_id, a bad placement, a page that can't belong to the target collection, or a nested page moved out of a private collection.
401unauthorizedMissing or invalid credentials.
402payment_requiredThe feature this endpoint belongs to isn't enabled on your plan, or is switched off.
403forbiddenYou can't edit the source or target collection, or a private collection rule blocks the move or reorder.
404not_foundNo such collection, you can't see it, or the page isn't in it.
406not_acceptableThe Accept header asks for a representation the API can't produce.
409conflictAll write endpoints declare this status. This endpoint has no conflict case of its own.
413payload_too_largeThe request body is over the size limit.
415unsupported_media_typeThe Content-Type isn't one this endpoint accepts.
429rate_limitedThrottled. Honor the Retry-After header before retrying.
Move or reorder a collection page
bash
curl -X PATCH \
  "https://api.plane.so/api/v2/workspaces/my-team/collections/e1b7c9d3-4a2f-4c86-9d15-3b8f6a0e2c71/pages/9c1f0b3d-6d2e-4c9a-8b41-2f7e5a0d6c88/" \
  -H "X-Api-Key: $PLANE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "collection_id": "73a9f2c4-8e1d-4b57-a6c0-d4e2b9f81a35",
  "placement": {
    "type": "before",
    "target_page_id": "61c3e8a5-0b9d-4f27-a4e6-c8d2f5b1a097"
  }
}'
Response200
json
{
  "id": "2f8d4b6a-9c1e-4a73-8b05-6e3c7d1f9a42",
  "collection_id": "73a9f2c4-8e1d-4b57-a6c0-d4e2b9f81a35",
  "page_id": "9c1f0b3d-6d2e-4c9a-8b41-2f7e5a0d6c88",
  "sort_order": 4500.0,
  "created_at": "2026-01-14T09:22:41.478363Z",
  "created_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430"
}
Response400
json
{
  "type": "invalid_request",
  "code": "invalid_request",
  "detail": "One or more fields failed validation.",
  "errors": [
    {
      "field": "placement.target_page_id",
      "code": "invalid",
      "message": "Required when type is before or after."
    }
  ]
}
Response403
json
{
  "type": "forbidden",
  "code": "forbidden",
  "detail": "You don't have permission to move this page out of the private collection."
}

How the body fields combine ​

  • collection_id with sort_order or placement. Moves the page and sets its position in the target collection in one call.
  • sort_order and placement together. The call accepts both, uses placement, and ignores sort_order.
  • placement.type of before or after. Needs target_page_id. Without it, the call returns 400.
  • Neither sort_order nor placement. The page keeps its current sort_order, including when it moves to another collection.

Rules for private collections ​

Every call needs edit access to the collection in the path. A move also needs edit access to the target collection. The rules below apply on top of that, and the API checks each one against you, the caller.

Reordering in place

  • In a private collection, you need Edit access to the collection. The owner has it, and so does a member with Edit. Otherwise the call returns 403.
  • In a public collection, the page must still be a wiki page that isn't archived. Otherwise the call returns 400.

Moving out of a private collection

  • A nested page can't leave a private collection on its own. The call returns 400, with Sub-pages cannot be moved from a private collection independently. in errors. Move its top-level page instead.
  • You must be a workspace admin, or have Edit access to the collection and own the page's top-level page. Otherwise the call returns 403.

Moving into a collection

  • The page must be a wiki page that isn't archived. A private target also requires a top-level page, not a nested one. Otherwise the call returns 400.
  • To move a page into a private collection, you must be a workspace admin or the collection's owner, or have Edit access to the collection and own the page's top-level page. Otherwise the call returns 403.
  • To move a private page into a public collection, the page must be yours. Moving it makes the page and its nested pages public and removes their shares. Moving someone else's private page into a public collection returns 403.

Learn more about moving pages between collections