Create a template
Changed onCreate a new template. The attributes.target_type field is a discriminator that selects one of four creation paths, each with its own required model_attributes shape and permission check.
| target_type | Creates | Required model_attributes keys | Permission |
|---|---|---|---|
| project | Empty workspace (no copy support — see /projects/copy) | client_id, project_manager_id, project_type_id, workflow_id | projects.manage (project manager) |
| budget | New quote (or copies one when target_id is set) | none required; optional editor_config, tracking_type_id, color_id | can_manage_budgets? |
| deal | New quote (or copies one when target_id is set) | none required; optional editor_config, color_id, retainer_interval / retainer_interval_count (retainer feature only) | can_manage_deals? |
| page | New page (or copies one when target_id is set); supports copy_attributes.copy_memberships and copy_attributes.copy_subpages | none | can_manage_docs? |
Create a project template (fresh workspace)
{
"data": {
"type": "templates",
"attributes": {
"name": "Onboarding playbook",
"description": "Standard intake project for new clients.",
"target_type": "project",
"model_attributes": {
"client_id": 412,
"project_manager_id": 13,
"project_type_id": 2,
"workflow_id": 1,
"project_color_id": 5
}
}
}
}
Create a budget template (fresh quote)
{
"data": {
"type": "templates",
"attributes": {
"name": "Standard retainer scaffold",
"target_type": "budget",
"model_attributes": {
"tracking_type_id": 1,
"color_id": 5
}
}
}
}
Create a budget template by copying an existing budget
{
"data": {
"type": "templates",
"attributes": {
"name": "Q3 enterprise migration template",
"target_type": "budget",
"target_id": "98231",
"model_attributes": { "color_id": 5 }
}
}
}
Create a deal template
{
"data": {
"type": "templates",
"attributes": {
"name": "Standard outbound deal",
"target_type": "deal",
"model_attributes": {
"color_id": 5,
"retainer_interval": "month",
"retainer_interval_count": 12
}
}
}
}
Create a page template by copying an existing page
{
"data": {
"type": "templates",
"attributes": {
"name": "Engineering RFC template",
"target_type": "page",
"target_id": "55421",
"copy_attributes": { "copy_memberships": false, "copy_subpages": true }
}
}
}
Save as Template — to create a project template from an existing project (boards, tasks, settings copied), use POST /projects/copy with attributes.copy_as_template: true. The target_type=project path on this endpoint only creates a fresh, empty template.
Request
- Base URLhttps://developer.productive.io (the document declares no server; this is the origin it was published from)
- URLhttps://developer.productive.io/api/v2/templates
- Authnone declared
Request body
Example request
{
"data": {
"type": "templates",
"attributes": {
"name": "New project template",
"description": "Used for kicking off enterprise migration projects.",
"target_type": "project",
"model_attributes": {
"client_id": 412,
"project_manager_id": 13,
"project_type_id": 2,
"workflow_id": 1
}
}
}
}Response
Successful response containing the requested template.
Example response
{
"data": {
"type": "templates",
"id": "18",
"attributes": {
"name": "Offboarding: General",
"description": "Popis stvari koje trebamo obaviti kada osoba odlazi iz firme",
"target_id": "258974",
"target_type": "project",
"color_id": null,
"created_at": "2023-01-24T14:08:06.857+01:00",
"updated_at": "2026-04-29T12:27:06.627+02:00",
"deleted_at": null
},
"relationships": {
"project": {
"data": {
"type": "projects",
"id": "258974"
}
},
"deal": {
"data": null
},
"page": {
"data": null
},
"task": {
"data": null
},
"creator": {
"data": {
"type": "people",
"id": "13"
}
}
}
},
"meta": {
"current_page": 1
},
"included": []
}Changes
- warning
added the new
bad_decimal_formatenum value to the//response property for the response status - warning
added the new
non_finite_numberenum value to the//response property for the response status - warning
added the new
null_bytes_in_paramsenum value to the//response property for the response status - info
added the non-success response with the status
- info
added the non-success response with the status
- info
added the non-success response with the status
- info
added the non-success response with the status
- info
added the non-success response with the status
- info
added the non-success response with the status
- info
added the non-success response with the status
- info
added the non-success response with the status
- info
added the non-success response with the status
- warning
- breaking
the
//response property's maxLength was unset from255for the response status - breaking
the
//response's property type changed fromintegerto no type for status - breaking
the
//response's property type changed fromstringto no type, and format fromdate-timeto no format for status - breaking
the
//response's property type changed fromstringto no type for status - breaking
the
//response's property type changed fromstringto no type for status - warning
deleted the
headerrequest parameterX-Organization-Id
This list may be incomplete.
- breaking