Skip to content

Create a project from a template ​

POST/api/v2/workspaces/{slug}/project-templates/{pk}/use/

Create a new project in this workspace from one of the workspace's project templates. The body takes project create fields. You name the project and give it an identifier, and the template supplies its states, feature toggles, and starter content.

The response is the new project, with 201. Plane creates the project, adds you and the project lead as admins, and creates its work item states before it responds. Labels, estimates, work item types, modules, and the bundled work items come from a background job that runs after the response, so they can take a moment to appear. See What the template applies.

The template doesn't need to be published, but it must belong to this workspace. To use a template published by another workspace, copy it in first.

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 id of the project template to use. Plane ignores any template_id in the body.

Body parameters ​

name:requiredstring

Name of the new project, unique within the workspace. Plane doesn't check this before saving, so a name another project already uses returns 500 server_error. Maximum 255 characters. It can't contain <, >, ", {, }, [, ], *, ^, !, #, %, or \.

identifier:requiredstring

Short project key used to prefix work item numbers, for example PAY in PAY-12. Unique within the workspace, and stored in upper case. Punctuation such as -, ., @, and # isn't allowed.

description:optionalstring

Plain-text description of the project. When you send only description, Plane builds description_html from it.

description_html:optionalstring

Description as HTML. Plane sanitizes it and fills description from it when you don't send one.

network:optionalinteger

Project visibility. 0 is private to members, 2 is visible to the whole workspace. Defaults to 2.

project_lead:optionalstring (uuid)

User id of the project lead, who must be a workspace member. The lead joins the project as an admin. This endpoint takes project_lead, not the project_lead_id that Create a project takes.

default_assignee:optionalstring (uuid)

User id of the default assignee, who must be a workspace member. Named default_assignee here, not default_assignee_id.

state_id:optionalstring (uuid)

The project's lifecycle state. It must belong to this workspace. When the workspace uses project grouping and the template sets project_state, the template's state replaces this one.

priority:optionalstring

Project priority. One of none, low, medium, high, or urgent.

start_date:optionalstring

Planned start date, as YYYY-MM-DD or a full ISO 8601 date-time. Nullable.

target_date:optionalstring

Planned due date, as YYYY-MM-DD or a full ISO 8601 date-time. Nullable.

timezone:optionalstring

IANA time zone, for example Europe/Berlin. Defaults to UTC.

archive_in:optionalinteger

Months before completed work items are auto-archived, from 0 to 12. 0 turns it off.

close_in:optionalinteger

Months before stale work items are auto-closed, from 0 to 12. 0 turns it off.

logo_props:optionalobject

Project icon settings used by the Plane editor. When you omit it, Plane picks a random icon and color.

cover_image:optionalstring

URL of a cover image. When you send one, the template's cover isn't copied.

emoji:optionalstring

Emoji shown with the project name. Maximum 255 characters. Nullable.

icon_prop:optionalobject

Legacy icon descriptor. Nullable.

external_id:optionalstring

Your system's identifier for this project, for sync and import correlation. Maximum 255 characters.

external_source:optionalstring

The system external_id came from, for example jira. Maximum 255 characters.

The body also accepts module_view, cycle_view, issue_views_view, page_view, intake_view, is_issue_type_enabled, and is_time_tracking_enabled, but Plane replaces them with the values in template_data.

Response shaping ​

fields:optionalstring

Comma-separated list of fields to return. Fields you don't request are left out of the response instead of coming back as null, so a missing key means you didn't ask for it and null means the value is null. id is always included, whether or not you name it.

Pass all to get every requestable field. An unknown field name returns 400 with the list of valid names and the closest match, so a typo is caught instead of being silently ignored.

Requestable here: archive_in, archived_at, close_in, cover_image, cover_image_url, created_at, created_by_id, cycle_view, default_assignee_id, default_state_id, description, description_html, emoji, estimate_id, external_id, external_source, guest_view_all_features, icon_prop, id, identifier, intake_view, is_issue_type_enabled, is_time_tracking_enabled, issue_views_view, logo_props, module_view, name, network, page_view, priority, project_lead_id, start_date, state_id, target_date, timezone, updated_at, updated_by_id.

See Sparse fields.

expand:optionalstring

Comma-separated relations to embed alongside the ids: default_assignee (the default assignee's user) and project_lead (the lead's user).

Expanded objects get their own key: ?expand=project_lead keeps project_lead_id and adds a project_lead object next to it. An unknown value returns 400. See Expanding relations.

Scopes ​

templates.projects:write

Errors ​

StatusCodeCause
400invalid_requestname or identifier is missing or has a forbidden character, the identifier is taken or too long, the lead or default assignee isn't a workspace member, or state_id belongs to another workspace.
401unauthorizedMissing or invalid credentials.
402payment_requiredProject templates aren't in your plan, or the feature is switched off for this workspace.
403forbiddenYour role or token scope can't use project templates, or you can't create projects in this workspace. You need both.
404not_foundNo project template with this id in this workspace.
406not_acceptableThe Accept header asks for a representation the API can't produce.
409governance_migration_in_progressThe workspace is migrating to workspace governance. Writes are blocked until it finishes, so retry later.
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.
500server_errorAnother project in this workspace already has this name.
Create a project from a template
bash
curl -X POST \
  "https://api.plane.so/api/v2/workspaces/my-team/project-templates/5b7e3c1a-9d24-4f68-b5a0-2e8c6d4f1b97/use/" \
  -H "X-Api-Key: $PLANE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Payments",
  "identifier": "PAY",
  "description": "Card and bank payment flows",
  "project_lead": "16c61a3a-512a-48ac-b0be-b6b46fe6f430"
}'
Response201
json
{
  "id": "6d2a8f4c-0b7e-4a19-93c5-e8f1b6d4a207",
  "name": "Payments",
  "description": "Card and bank payment flows",
  "description_html": "<p>Card and bank payment flows</p>",
  "identifier": "PAY",
  "network": 2,
  "project_lead_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
  "default_assignee_id": null,
  "default_state_id": null,
  "estimate_id": null,
  "state_id": "0e5b9c3a-7d21-4f86-b4a8-2c6f1e9d7b30",
  "priority": "none",
  "start_date": null,
  "target_date": null,
  "emoji": null,
  "icon_prop": null,
  "logo_props": {
    "in_use": "icon",
    "icon": {
      "name": "rocket",
      "color": "#5e6ad2"
    }
  },
  "cover_image": null,
  "cover_image_url": null,
  "module_view": true,
  "cycle_view": true,
  "issue_views_view": true,
  "page_view": true,
  "intake_view": false,
  "is_time_tracking_enabled": false,
  "is_issue_type_enabled": false,
  "guest_view_all_features": false,
  "archive_in": 0,
  "close_in": 0,
  "timezone": "UTC",
  "archived_at": null,
  "external_id": null,
  "external_source": null,
  "created_at": "2026-02-03T16:45:12.478363Z",
  "updated_at": "2026-02-03T16:45:13.478363Z",
  "created_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
  "updated_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430"
}
Response400
json
{
  "type": "invalid_request",
  "code": "invalid_request",
  "detail": "One or more fields failed validation.",
  "errors": [
    {
      "field": "non_field_errors",
      "code": "identifier_already_taken",
      "message": "Project Identifier is taken"
    }
  ]
}

What the template applies ​

Before the response, Plane:

  • creates the project from your body and adds you to it as an admin, along with the project lead when the lead is someone else;
  • creates the template's states as the project's work item states;
  • copies the feature toggles module_view, cycle_view, issue_views_view, page_view, intake_view, is_time_tracking_enabled, and is_issue_type_enabled from the template and replaces any you sent;
  • switches project updates, epics, and workflows on or off to match is_project_updates_enabled, is_epic_enabled, and is_workflow_enabled;
  • sets up intake from intake_settings when intake_view is on;
  • copies the template's cover image when it is stored in Plane, unless you sent cover_image;
  • sets the project's lifecycle state from project_state, when the workspace uses project grouping and that state still exists.

After the response, a background job:

  • creates the template's labels and estimates;
  • creates the template's workitem_types and epics, or links the workspace's default work item type when the workspace manages work item types at the workspace level;
  • creates the template's modules when module_view is on;
  • creates one work item per entry in workitems, mapped onto the new states, labels, types, and modules by their template ids.

The project's other settings, such as network, timezone, priority, and its dates, come from your request body, not from the template.

use ignores these template keys: members, workflows, milestones, recurring_work_items, automations, is_milestone_enabled, guest_view_all_features, project_lead, and default_assignee. The only members it adds are you and the project_lead from your body.

Poll for the bundled work items

The background job runs after you get the 201, so an immediate List work items on the new project can return an incomplete list. If your integration needs the bundled work items, poll the list with a timeout until the count matches the template's workitems. The background steps don't retry, so a step that fails leaves its content out of the project.