Project page templates overview
A project page template is a page template that belongs to one project. It has the same shape as a workspace page template, with project_id set to its project. It stores a title, an HTML body, and display settings that Plane copies into a new page.
The project and workspace sets never overlap. A template stays in the scope it was created through, and no write moves it. A project template's id returns 404 on the workspace routes and on another project's routes.
Learn more about page templates
The project page template object
Attributes
idstring (uuid)Unique identifier for the template.
namestringDisplay name of the template, shown in the template picker. Maximum 255 characters.
short_descriptionstringOne-line summary of what the template is for. Nullable.
description_htmlstringLonger description of the template itself, as HTML. The body of the page that the template creates is
template_data.description_html, not this field.template_typestringAlways
pagefor page templates.is_publishedbooleanWhether the template is published. Defaults to
false.short_idstringShort unique id that Plane generates when the template is created, for example
m5v8c1. Filter on it with?short_id=.slugstringURL-safe form of
name. Plane regenerates it whenever the name changes.project_idstring (uuid)The project the template belongs to. Read-only, because the route you create a template through fixes its scope.
template_dataobjectThe page seed, with the keys
name,description_html,color,parent,view_props, andlogo_props. The keys, their defaults, and theparentrules are the same as for workspace page templates. See The template_data object.created_atstring (date-time)When the template was created.
updated_atstring (date-time)When the template was last updated.
created_by_idstring (uuid)The user who created the template.
updated_by_idstring (uuid)The user who last updated the template.
{
"id": "9e1c7a52-3b4d-4f86-a0d2-5c8e7b1f3a94",
"name": "Incident postmortem",
"short_description": "Timeline, impact, root cause, and follow-ups",
"description_html": "<p>Fill this in within 48 hours of an incident.</p>",
"template_type": "page",
"is_published": false,
"short_id": "m5v8c1",
"slug": "incident-postmortem",
"project_id": "4af68566-94a4-4eb3-94aa-50dc9427067b",
"template_data": {
"name": "Postmortem",
"description_html": "<h2>Timeline</h2><p></p><h2>Impact</h2><p></p><h2>Root cause</h2><p></p><h2>Follow-ups</h2><p></p>",
"color": "#e5484d",
"parent": {
"id": "c2f5a8d1-7e3b-4c96-8a14-0b9d6e2f5c71",
"project_id": "4af68566-94a4-4eb3-94aa-50dc9427067b",
"project_identifier": "ENG"
},
"view_props": {
"full_width": true
},
"logo_props": {}
},
"created_at": "2026-01-14T09:22:41.478363Z",
"updated_at": "2026-01-14T09:22:41.478363Z",
"created_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
"updated_by_id": null
}Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/v2/workspaces/{slug}/projects/{project_id}/page-templates/ | List project page templates |
GET | /api/v2/workspaces/{slug}/projects/{project_id}/page-templates/{pk}/ | Get a project page template |
POST | /api/v2/workspaces/{slug}/projects/{project_id}/page-templates/ | Create a project page template |
PATCH | /api/v2/workspaces/{slug}/projects/{project_id}/page-templates/{pk}/ | Update a project page template |
DELETE | /api/v2/workspaces/{slug}/projects/{project_id}/page-templates/{pk}/ | Delete a project page template |
Workspace governance
Workspace governance is the Enterprise Grid feature where the workspace owns states, workflows, and templates instead of each project. Turning it on moves the existing project page templates to the workspace with their ids unchanged. From then on the workspace page template routes serve them, and their ids return 404 on the project routes.
In a workspace with governance turned on, the project routes stop accepting writes:
- Create, update, and delete return
409 templates_managed_at_workspace. Make the change through the workspace page template routes instead. - List and get keep working.
In an ungoverned workspace, every route here works normally. While the governance migration runs, every write in the workspace returns 409 governance_migration_in_progress instead, and reads keep working.
{
"type": "conflict",
"code": "templates_managed_at_workspace",
"detail": "Templates are managed at the workspace level."
}The governance check runs after the existence and permission checks on update and delete, so an unknown id is still 404 and a missing permission is still 403. On create it runs before body validation, so a governed workspace answers 409 even when the body is invalid.
Updating template_data
template_data on a PATCH replaces the whole seed. Each omitted key goes back to its default: description_html to <p></p>, color to an empty string, and parent, view_props, and logo_props to {}. template_data.name is required whenever you send template_data. A PATCH without template_data leaves the seed alone.
Feature gating
Page templates are a paid feature. When the workspace's plan doesn't include them, or the feature is switched off, every endpoint here returns 402 payment_required. See Errors.
Response shaping
Every read accepts ?fields= for sparse responses. See Sparse fields.
List rows leave out description_html and template_data by default, because both carry HTML. Name them in ?fields=, or pass ?fields=all, to get them on list rows. A single-template response always includes them. Errors follow the shared problem+json contract.
Changed from v1
- The routes move from
/api/v1/workspaces/{slug}/projects/{project_id}/pages/templates/to/api/v2/workspaces/{slug}/projects/{project_id}/page-templates/. - In a governed workspace, project writes return
409 templates_managed_at_workspace. v1 returned a400with its own error body. - The list is paginated, filterable, and searchable. v1 returned every template in one array.
project_idin the path accepts the project identifier, for exampleENG, as well as the UUID.
See Migrating from v1 for the full list.

