Skip to Content
Delmare Digital

API reference

The fourteen /api/page-tree/* endpoints the tree view uses, with their methods, parameters and responses.

The tree view talks to these endpoints. They are registered under Payload's API route (/api by default), and every one passes through the access gate first, so you need an authenticated user to call them. Endpoint reads and writes apply your collection access rules; URL maintenance runs with full access, as described in Access control.

rename, redirects, restore-slug, edit-url and check-segment reject unconfigured page collections with 400. Errors come back as { error: string }.

create, duplicate and status do not check whether the requested collection is configured for page-tree. They pass it to Payload, where collection access checks still apply. Do not use the configured collections list as an authorization boundary; restrict collection access and the endpoint gate.

Structure

MethodPathInputWhat it does
POST/page-tree/move{ type, id, collection?, newParentId, newIndex, updateSlugs? }Moves a page or folder. updateSlugs defaults to false (keep URLs). Pass the page's collection to look only there; without it every configured collection is tried. Returns 404 if the page or folder doesn't exist or the user can't read it, 404 { error: 'Folder not found' } for a missing or unreadable newParentId, and 403 if they can read the target but not update it.
POST/page-tree/reorder{ type, collection?, items: [{ id, sortOrder }] }Saves the order of siblings, one at a time. Every page is checked before anything is written; 403/404 as for move.
POST/page-tree/create{ type, parentId, name, collection? }Creates a folder, or a draft page in collection. The URL segment is made unique within the parent. Returns 404 { error: 'Folder not found' } if parentId doesn't exist or the user can't read it.
DELETE/page-tree/deleteQuery: type, id, collection (required for pages), deleteChildren?Deletes a page from that collection, or a folder. A missing or unconfigured page collection returns 400. With deleteChildren=true, a folder is deleted with everything inside it, all or nothing.
POST/page-tree/duplicateQuery: id, collectionDuplicates a page through Payload's duplicate operation.
POST/page-tree/status{ id, collection, status }Sets _status to draft or published.
POST/page-tree/rename{ type, id, name, collection? }Changes a folder's name or a page's title. Never changes a URL. 404 if the user can't read the target, 403 if they can read it but not update it.

URLs

MethodPathInputWhat it does
POST/page-tree/edit-url{ type, id, segment, collection? }Changes a page's or folder's URL segment and rebuilds affected slugs. Answers 409 when the segment is already used in that location.
GET/page-tree/check-segmentQuery: type, segment, parentId?, excludeId?, collection (pages)Returns { available, slugifiedSegment }. Counts segments held by pages the user can't see, so it agrees with what a save will accept. Returns 404 { error: 'Folder not found' } if parentId doesn't exist or the user can't read it, and 404 { error: 'Not found' } for such an excludeId.
GET/page-tree/folder-impactQuery: folderIdReturns { childPageCount }: pages whose slugs a segment change would rewrite, including nested subfolders and pages the user can't see. Returns 404 { error: 'Folder not found' } if the folder doesn't exist or the user can't read it.
POST/page-tree/regenerate-slugsQuery: folderId?Rebuilds slugs for every page in the folder and its subfolders. Without folderId, rebuilds every page in every configured collection. Returns { success, message, count }.
POST/page-tree/restore-slug{ id, collection, slug }Restores a slug from the page's history.
GET/page-tree/redirectsQuery: collectionReturns { redirects: [{ from, to }], count }. See Redirects.
POST/page-tree/migrate—Fills in pathSegment from the name on folders that have none, without changing page slugs. Returns { success, message, count, folders }.

type is always 'page' or 'folder', and parentId / newParentId are null for the root.

Types

type SlugChangeReason = 'move' | 'rename' | 'regenerate' | 'restore' | 'manual' | 'edit-url'

interface SlugHistoryEntry {
  slug: string             // The previous slug
  changedAt: Date | string // When it was replaced
  reason?: SlugChangeReason
}

interface TreeNode {
  id: string               // Prefixed for the tree: 'folder-1' or 'page-1'
  rawId?: string           // Database ID without the prefix
  type: 'folder' | 'page'
  name: string
  slug?: string
  pathSegment?: string
  status?: 'draft' | 'published'
  children: TreeNode[]
  pageCount: number
  folderId?: string | null
  sortOrder: number
  collection?: string
  slugHistory?: SlugHistoryEntry[] // Pages only
}
Edit this page on GitHub

On this page