Archive a project page
Archive a project page. The call sets the page's archived_at to the current time and archives its nested pages with it. Archiving is reversible with Unarchive a project page.
Archiving is also the step before deletion. Delete a project page refuses an active page with 400, so archive the page first.
This is a bodyless POST. Send no JSON. A successful call returns 204 with no body. If you need the new archived_at, read the page afterward.
The call is idempotent. Archiving a page that is already archived returns 204 and changes nothing, including its original archived_at.
Path Parameters
slug:requiredstringThe workspace slug. It appears in your Plane URLs. In https://app.plane.so/my-team/projects/, the slug is my-team.
project_id:requiredstringThe project the page belongs to. Accepts the project UUID or its bare identifier, for example ENG.
pk:requiredstring (uuid)The id of the page to archive.
Body Parameters
None. The endpoint takes no request body.
Scopes
projects.pages:write
Errors
| Status | Code | Cause |
|---|---|---|
400 | invalid_request | The request could not be processed. |
401 | unauthorized | Missing or invalid credentials. |
402 | payment_required | The feature this endpoint belongs to isn't enabled on your plan, or is switched off. |
403 | forbidden | Your role or token scope can't archive this page. |
404 | not_found | No such page in this project, or you can't see it. |
406 | not_acceptable | The Accept header asks for a representation the API can't produce. |
409 | conflict | All write endpoints declare this status. This endpoint has no conflict case of its own. |
413 | payload_too_large | The request body is over the size limit. |
415 | unsupported_media_type | The Content-Type isn't one this endpoint accepts. |
429 | rate_limited | Throttled. Honor the Retry-After header before retrying. |
curl -X POST \
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b/pages/9c1f0b3d-6d2e-4c9a-8b41-2f7e5a0d6c88/archive/" \
-H "X-Api-Key: $PLANE_API_KEY"import requests
response = requests.post(
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b"
"/pages/9c1f0b3d-6d2e-4c9a-8b41-2f7e5a0d6c88/archive/",
headers={"X-Api-Key": "your-api-key"},
)
print(response.status_code)const response = await fetch(
"https://api.plane.so/api/v2/workspaces/my-team/projects/4af68566-94a4-4eb3-94aa-50dc9427067b" +
"/pages/9c1f0b3d-6d2e-4c9a-8b41-2f7e5a0d6c88/archive/",
{
method: "POST",
headers: { "X-Api-Key": "your-api-key" },
},
);
console.log(response.status);No response body.
{
"type": "not_found",
"code": "not_found",
"detail": "The requested resource was not found."
}What archiving changes
archived_aton the page goes fromnullto the current time.- Every nested page under it is archived too. The nested pages are updated in the background, so for a moment after the
204they can still readarchived_at: null. - The page and its nested pages are removed from everyone's favorites.
- If the page was published, it's unpublished, and so are its nested pages. Its anchor stops resolving in Get a published page.
Nothing is deleted. The page stays readable:
- Get a project page still returns it, with
archived_atset. - List project pages includes it by default.
?type=archivedlists only archived pages, and?type=public,?type=private, and?type=sharedleave archived pages out.
Use this endpoint, not a PATCH
Update a project page accepts archived_at, but it changes only that field on that one page. It doesn't archive nested pages, clear favorites, or unpublish the page. Archive through this endpoint.

