Templates
A deliverable template is a reusable piece of work: a list of tasks, each with its resource (time) lines and cost lines. A project template groups deliverable templates into the structure a new project or opportunity starts with. Project Settings and Opportunity Settings are the two baseline project templates. Proposal templates are on their own page: Proposal templates.
These endpoints are in early access, and they follow the rules for every setup endpoint. Find template ids with GET /account_settings.
Endpoints
| Method and path | Does |
|---|---|
GET /api/v1/deliverable_templates/:id |
Reads a deliverable template with its tasks and lines |
POST /api/v1/deliverable_templates |
Creates a deliverable template, optionally with tasks |
PATCH /api/v1/deliverable_templates/:id |
Changes a deliverable template’s own fields |
DELETE /api/v1/deliverable_templates/:id |
Deletes a deliverable template |
PATCH /api/v1/deliverable_templates/:id/restore |
Restores a deleted deliverable template |
POST, PATCH, DELETE /api/v1/deliverable_templates/:id/tasks |
One task at a time |
PATCH /api/v1/deliverable_templates/:id/tasks/:task_id/restore |
Restores a deleted task |
POST, PATCH, DELETE /api/v1/deliverable_templates/:id/resources |
One resource line at a time |
POST, PATCH, DELETE /api/v1/deliverable_templates/:id/costs |
One cost line at a time |
GET /api/v1/project_templates/:id |
Reads a project template |
POST /api/v1/project_templates |
Creates a project or opportunity template |
PATCH /api/v1/project_templates/:id |
Changes a project template’s own fields |
DELETE /api/v1/project_templates/:id |
Deletes a project template |
PATCH /api/v1/project_templates/:id/restore |
Restores a deleted project template |
POST /api/v1/project_templates/:id/sync_custom_fields |
Pushes the template’s custom fields to active projects |
POST, PATCH, DELETE /api/v1/project_templates/:id/<rows> |
One phase, deliverable, status, lead score or custom field at a time |
PATCH and DELETE on a row take the row’s id: /api/v1/deliverable_templates/2210/tasks/9301.
Deliverable templates
The deliverable template document
GET /api/v1/deliverable_templates/:id returns the template with its kept tasks in order. A deleted template returns 404 deliverable_template_not_found.
| Parameter | Meaning |
|---|---|
include_deleted |
true adds deleted_tasks, the template’s deleted tasks, which can be restored |
Needs api_read and customisation.
{
"id": 2210,
"name": "Concept design",
"description": "Massing studies and concept package",
"status": "active",
"use_case": "all_types",
"default_budget_type": "fixed_fee",
"colour": "sky",
"resource_type": null,
"contract_value": {"cents": 1260000, "currency": "AUD", "formatted": "$12,600.00"},
"internal_budget": {"cents": 1080000, "currency": "AUD", "formatted": "$10,800.00"},
"tasks": [
{
"id": 9301,
"record_kind": "deliverable_template_task",
"kind": "dynamic",
"name": "Site analysis",
"item_type": "task",
"position": 1,
"description": "Review survey and planning controls",
"description_html": "<div>Review survey and planning controls</div>",
"delivery_task_name": null,
"quantity": null,
"quantity_unit": null,
"billable_rate": null,
"resources": [
{
"id": 7720,
"record_kind": "deliverable_template_task_resource",
"resource_type": {"id": 88, "name": "Senior Engineer"},
"quantity": 16.0,
"quantity_unit": "hour",
"notes": null,
"preferred_member": null,
"position": 1
}
],
"costs": [
{
"id": 3105,
"record_kind": "deliverable_template_task_cost",
"cost_type": {"id": 610, "name": "Subcontractor"},
"name": "Survey",
"description": null,
"quantity": 1.0,
"quantity_unit": "per_item",
"billable_rate": {"cents": 180000, "currency": "AUD", "formatted": "$1,800.00"},
"position": 1
}
]
}
],
"warnings": []
}
Template fields:
| Field | Meaning |
|---|---|
status |
draft or active |
use_case |
all_types, project or sales |
default_budget_type |
fixed_fee or time_and_materials |
colour |
A colour name, or null |
resource_type |
The template’s default resource type, or null |
contract_value, internal_budget |
Totals of the tasks |
Task fields:
| Field | Meaning |
|---|---|
kind |
fixed, dynamic or non_financial (see Task kinds) |
item_type |
task or event for a fixed or dynamic task. heading or process_only for a non-financial task |
description, description_html |
The description as plain text and as rich text |
delivery_task_name |
The name the task takes on a project, when it differs, or null |
quantity, quantity_unit, billable_rate |
A fixed task’s own price. null on other kinds |
resources, costs |
The task’s lines |
Resource line: resource_type, quantity (a number), quantity_unit (hour, day or per_item), notes, preferred_member (the person the line suggests, or null) and position.
Cost line: cost_type, name, description, quantity, quantity_unit (hour, day or per_item), billable_rate and position.
Warnings a template can carry:
code |
Means |
|---|---|
empty_dynamic_item |
Dynamic tasks with no lines, so their value is zero. count and subject_ids (task ids) |
no_billable_path |
The template has no task, event or process-only task, so it adds no contract value |
Task kinds
The kind of a task decides where its money comes from:
fixed: the task’s ownquantity×billable_rate_centsis its contract value. Its lines, if any, make its internal budget.dynamic: the sum of the lines makes both the contract value and the internal budget. With no lines the task is worth zero.non_financial: a heading or a process-only step. It has no money and no lines.
quantity, quantity_unit and billable_rate_cents are accepted on a fixed task only. On another kind they return 422 invalid_input. Switching a task from dynamic to fixed without a price sets quantity 1, per item, at the current line total.
Create a deliverable template
POST /api/v1/deliverable_templates creates a template. Send tasks to add tasks in the same request. Each task takes the task fields and can carry its own resources and costs. Everything is saved in one transaction.
Needs api_create and customisation.
| Field | Required | Rules |
|---|---|---|
name |
Yes, unless copy_from_id is sent |
Cannot be blank |
description |
No | Text, or null |
status |
No | draft or active |
use_case |
No | all_types, project or sales |
default_budget_type |
No | fixed_fee (default) or time_and_materials |
colour |
No | A colour name, or null |
resource_type_id |
No | A kept resource type, or null |
copy_from_id |
No | Copies this template with its kept tasks and lines first. The copy is named after the source with “ (copy)” added unless you send name. Tasks you send are added after the copied ones |
tasks |
No | New tasks, in order |
POST /api/v1/deliverable_templates
{
"name": "Concept design",
"status": "active",
"default_budget_type": "fixed_fee",
"tasks": [
{
"name": "Site analysis",
"kind": "dynamic",
"resources": [{"resource_type_id": 88, "quantity": 16, "quantity_unit": "hour"}],
"costs": [{"cost_type_id": 610, "name": "Survey", "quantity": 1, "billable_rate_cents": 180000}]
},
{"name": "Concept package", "kind": "fixed", "quantity": 1, "quantity_unit": "per_item", "billable_rate_cents": 900000}
]
}
Returns 201 with the template document. An error in a task names it in field, such as tasks[1].billable_rate_cents.
Change a deliverable template
PATCH /api/v1/deliverable_templates/:id changes name, description, status, use_case, default_budget_type, colour and resource_type_id. tasks is refused: change tasks with the row endpoints.
Needs api_update and customisation. Returns 200 with the template document.
Delete and restore a deliverable template
DELETE /api/v1/deliverable_templates/:id soft deletes the template. PATCH /api/v1/deliverable_templates/:id/restore restores it. Both return a summary:
{"id": 2210, "name": "Concept design", "status": "active", "use_case": "all_types", "default_budget_type": "fixed_fee", "deleted": true, "warnings": []}
A delete needs api_delete, and a restore api_update. Both need customisation. Deleting a deleted template, or restoring a kept one, returns 404 deliverable_template_not_found.
Deliverable template rows
| Path | Row | POST also needs |
|---|---|---|
/api/v1/deliverable_templates/:id/tasks |
A task | |
/api/v1/deliverable_templates/:id/resources |
A resource line | deliverable_template_task_id |
/api/v1/deliverable_templates/:id/costs |
A cost line | deliverable_template_task_id |
POSTadds a row. It goes last in its list unless you sendposition(1 is first). Returns201.PATCH .../:row_idchanges the fields you send.positionmoves the row. An empty body returns422 missing_input.DELETE .../:row_iddeletes the row.- A row of another template returns
404.
Task fields:
| Field | Rules |
|---|---|
name |
Required on create unless copy_from_id is sent |
kind |
fixed, dynamic (default) or non_financial. A PATCH without it keeps the task’s kind |
item_type |
task (default) or event for fixed and dynamic tasks. process_only (default) or heading for non-financial tasks |
description or description_html |
Plain text or rich text. Send one. A description equal to the current plain text keeps the formatting |
delivery_task_name |
Text, or null |
quantity, quantity_unit, billable_rate_cents |
Fixed tasks only. quantity_unit is hour (default), day or per_item |
position |
1 or more |
resources, costs |
POST only. New lines for the new task |
copy_from_id |
POST only. Copies a kept task of the same template with its lines, just below it. The other fields you send then apply to the copy |
Resource line fields: resource_type_id (required on create, a kept resource type), quantity (default 0), quantity_unit (hour default, day or per_item), notes, preferred_member_id (a kept member, or null) and position.
Cost line fields: cost_type_id and name (both required on create), description, quantity (default 0), quantity_unit (per_item default, hour or day), billable_rate_cents (default 0) and position.
Rules:
- A non-financial task cannot have lines.
resourcesorcostson a new non-financial task return422 invalid_input. A line added to one returns422 item_not_billable. - A task with lines cannot become
non_financial:422 item_has_lines. Delete its lines first. - A line cannot move to another task.
deliverable_template_task_idon a linePATCHreturns422 invalid_input. Delete the line and add it to the other task. - Deleting a task that delivery tasks or budget items were built from soft deletes it, so it can be restored with
PATCH .../tasks/:task_id/restore. Any other task is deleted for good with its lines. A deleted line is gone for good.
A row write returns the row in its document shape:
POST /api/v1/deliverable_templates/2210/resources
{"deliverable_template_task_id": 9301, "resource_type_id": 91, "quantity": 8}
{
"deliverable_template_id": 2210,
"row_type": "deliverable_template_task_resource",
"record_kind": "deliverable_template_task_resource",
"row": {
"id": 7721,
"record_kind": "deliverable_template_task_resource",
"resource_type": {"id": 91, "name": "Graduate Engineer"},
"quantity": 8.0,
"quantity_unit": "hour",
"notes": null,
"preferred_member": null,
"position": 2
},
"warnings": []
}
A DELETE returns:
{"deliverable_template_id": 2210, "row_type": "deliverable_template_task", "id": 9301, "deleted": true, "permanently_deleted": false, "warnings": []}
permanently_deleted is false when the task was soft deleted and can be restored.
Row writes need customisation, and api_create, api_update or api_delete for the method. Restoring a task needs api_update.
Project templates
A project template has use_case project or opportunity. The two baselines (baseline: true) are Project Settings and Opportunity Settings. Every account has one of each, and they cannot be created or deleted. Read and change their own fields through /project_settings and /opportunity_settings, and their rows through the row endpoints on this page, using the baseline’s id.
The project template document
GET /api/v1/project_templates/:id returns a template. A deleted template returns 404 project_template_not_found.
| Parameter | Meaning |
|---|---|
include_deleted |
true also returns deleted deliverables, statuses, lead scores and custom fields, each with "deleted": true |
Needs api_read and customisation.
{
"id": 655,
"name": "Residential new build",
"description": null,
"status": "active",
"use_case": "project",
"baseline": false,
"default": true,
"code": null,
"contract_type": "fixed_price",
"default_rate_card": {"id": 95, "name": "2026 rates"},
"numbering": {"part_one_generator": null, "part_two_generator": null, "part_three_generator": null, "code_separator": null, "number_padding": null, "all_time_starting_number": null, "joining_year_starting_number": null, "number_prefix": null, "number_suffix": null, "client_number_padding": null, "defer_number_until_quote": false},
"phases": [
{"id": 120, "record_kind": "project_template_phase", "name": "Design", "description": null, "colour": "blue", "position": 1}
],
"deliverables": [
{
"id": 4410,
"record_kind": "project_template_deliverable",
"project_template_id": 655,
"deliverable_template": {"id": 2210, "name": "Concept design"},
"name": "Concept design",
"project_template_phase_id": 120,
"position": 1,
"deleted": false
}
],
"statuses": [],
"lead_scores": [],
"custom_fields": [],
"warnings": [
{"code": "auto_applied_on_new_projects", "message": "this template is the default, so new projects use it automatically", "subject_id": 655}
]
}
| Field | Meaning |
|---|---|
use_case |
project or opportunity |
baseline |
true for Project Settings and Opportunity Settings |
default |
New projects or opportunities get this template automatically |
code, numbering |
Set on a baseline only. Numbering fields are listed under Change Project Settings |
contract_type |
fixed_price or time_and_materials |
default_rate_card |
The rate card new projects from this template use, or null |
phases |
Phases group deliverables. Only an extra (non-baseline) project template has phases |
deliverables |
The template’s deliverables, each built from a deliverable template, in order |
statuses |
The statuses of a baseline (see Statuses) |
lead_scores |
The lead scores of Opportunity Settings |
custom_fields |
The custom fields new records get, with their defaults (see Custom fields) |
Warnings a template can carry:
code |
Means |
|---|---|
auto_applied_on_new_projects |
The template is the default |
project_template_drift |
Proposal templates linked to this template do not have all its deliverables. subject_ids are those proposal template ids |
custom_fields_sync_queued |
After a sync, the sync runs in the background |
Create a project template
POST /api/v1/project_templates creates an extra template. A create never makes a baseline.
Needs api_create and customisation.
| Field | Required | Rules |
|---|---|---|
use_case |
Yes | project or opportunity. Cannot change later |
name |
Yes, unless copy_from_id is sent |
Cannot be blank |
description |
No | Text, or null |
status |
No | draft or active |
contract_type |
No | fixed_price or time_and_materials |
default |
No | true or false |
default_rate_card_id |
No | An active account rate card whose effective date has passed, or null |
copy_from_id |
No | Copies this template with its phases, deliverables, bookings and custom fields first. The copy keeps the source’s use_case, is named after the source with “ (copy)” added unless you send name, and is not the default unless you send default: true |
phases |
No | New phases: {name, description, colour, position}. project templates only |
deliverables |
No | New deliverables (see Project template rows). A deliverable can name a phase of the same request with project_template_phase_name |
code, the numbering fields, statuses and lead_scores are refused on an extra template. custom_fields on an extra template returns 422 invalid_input: custom fields are added to a baseline.
POST /api/v1/project_templates
{
"name": "Residential new build",
"use_case": "project",
"status": "active",
"default_rate_card_id": 95,
"phases": [{"name": "Design", "colour": "blue"}, {"name": "Documentation", "colour": "green"}],
"deliverables": [
{"deliverable_template_id": 2210, "project_template_phase_name": "Design"},
{"deliverable_template_id": 2215, "project_template_phase_name": "Documentation"}
]
}
Returns 201 with the template document.
Change a project template
PATCH /api/v1/project_templates/:id changes the template’s own fields: name, description, status, contract_type, default and default_rate_card_id. On a baseline it also takes code and the numbering fields. use_case cannot change (422 invalid_input).
The row lists (phases, deliverables, statuses, lead_scores, custom_fields) and sync_custom_fields are refused. Use the row endpoints.
Needs api_update and customisation. Returns 200 with the template document.
Delete and restore a project template
DELETE /api/v1/project_templates/:id soft deletes an extra template. A baseline cannot be deleted: 422 baseline_template_not_archivable. PATCH /api/v1/project_templates/:id/restore restores a deleted template. Both return a summary:
{"id": 655, "name": "Residential new build", "use_case": "project", "baseline": false, "default": true, "status": "active", "deleted": true, "warnings": []}
A delete needs api_delete, and a restore api_update. Both need customisation.
Sync custom fields to active projects
POST /api/v1/project_templates/:id/sync_custom_fields does what Sync To Active Projects does in Drum. On each active project or opportunity that uses the template, it adds the template’s missing custom fields with their defaults, and removes empty custom fields that no template names any more. On a baseline, it covers every active project, or every active opportunity.
Because it can remove fields, it needs api_update and api_delete (not api_create), and customisation.
The sync runs in the background and can take a few minutes. The response is the template document with the warning custom_fields_sync_queued.
Project template rows
| Path | Row | Belongs on |
|---|---|---|
/api/v1/project_templates/:id/phases |
A phase | An extra project template only |
/api/v1/project_templates/:id/deliverables |
A template deliverable | Any template |
/api/v1/project_templates/:id/statuses |
A status | A baseline only |
/api/v1/project_templates/:id/lead_scores |
A lead score | Opportunity Settings only |
/api/v1/project_templates/:id/custom_fields |
A custom field and its default | New rows on a baseline only |
A row on the wrong kind of template returns 422 invalid_input with field project_template_id.
POSTadds a row. It goes last in its list unless you sendposition(1 is first). Returns201.PATCH .../:row_idchanges the fields you send.positionmoves the row. An empty body returns422 missing_input.DELETE .../:row_iddeletes the row. A phase is deleted for good, and its deliverables move to no phase. Other rows are soft deleted.PATCH .../:row_id/restorerestores a deleted deliverable, status, lead score or custom field. Phases have no restore.- A row of another template returns
404.
Row writes need customisation, and api_create, api_update or api_delete for the method. Restoring a row needs api_update.
Phases
| Field | Rules |
|---|---|
name |
Text |
description |
Text, or null |
colour |
gray, red, orange, yellow, blue, green or indigo |
position |
1 or more |
Deliverables
| Field | Rules |
|---|---|
deliverable_template_id |
Required on create. A kept deliverable template |
name |
A name for the deliverable in this template, or leave it out |
project_template_phase_id |
A phase of this template, or null for no phase. On a PATCH it moves the deliverable to that phase |
project_template_phase_name |
A phase of this template, by name (case and spaces ignored). Send this or project_template_phase_id, not both |
position |
1 or more |
Statuses
| Field | Rules |
|---|---|
name |
Text |
colour |
gray, red, orange, yellow, blue, green or indigo, or null |
complete_status |
true marks a record in this status as complete |
default |
true makes this the status new records get. The previous default stops being the default |
default_successful_status, default_lost_status |
The status an opportunity moves to when it is won or lost. One of each per template |
sales_status_type |
standard, won or lost. Opportunity Settings only. On Project Settings only standard is accepted |
position |
1 or more |
The flags refuse null. A baseline keeps at least one status: deleting the last one returns 422 baseline_status_required.
Lead scores
| Field | Rules |
|---|---|
name |
Required |
percentage |
Required. An integer, such as 50 |
default |
true or false |
position |
1 or more |
Custom fields
| Field | Rules |
|---|---|
custom_field_id |
Required on create. A kept field from the custom field catalog |
primary_filter |
true makes the field a filter on the project or opportunity list |
default_value |
For text, long_text, link and select fields. For select, one of the field’s options |
default_number_value |
For number fields |
default_date_value |
For date and date_and_time fields. An ISO 8601 date or time |
default_array_value |
For multiselect fields. An array of the field’s options |
position |
1 or more |
A default that does not fit the field’s type, or is not one of its options, returns 422 invalid_input with the default as field. null clears a default. The document returns all four defaults, and the ones that do not fit the type are null.
An extra template that already has custom fields keeps them, and they can be changed or deleted there. New ones are added to a baseline.
A row write returns the row in its document shape:
POST /api/v1/project_templates/641/statuses
{"name": "Won", "colour": "green", "sales_status_type": "won", "default_successful_status": true}
{
"project_template_id": 641,
"row_type": "project_status",
"record_kind": "project_status",
"row": {
"id": 307,
"record_kind": "project_status",
"name": "Won",
"colour": "green",
"position": 6,
"complete_status": false,
"default": false,
"default_successful_status": true,
"default_lost_status": false,
"sales_status_type": "won",
"project_template_id": 641,
"deleted": false
},
"warnings": []
}
A DELETE returns {project_template_id, row_type, id, deleted, permanently_deleted, warnings}.
Errors
Error bodies are {"error", "code"}, with field on input and lookup errors (see Errors). An error in a row of a create names the row, such as tasks[0].costs[0].cost_type_id.
| Status | code |
When |
|---|---|---|
403 |
not_authorized |
A missing API permission, or no customisation |
404 |
not_found |
The setup endpoints are not turned on for the account |
404 |
deliverable_template_not_found, project_template_not_found |
The template is not in the account, or is deleted |
404 |
deliverable_template_task_not_found, deliverable_template_task_resource_not_found, deliverable_template_task_cost_not_found |
The row is not on this deliverable template |
404 |
project_template_phase_not_found, project_template_deliverable_not_found, project_status_not_found, lead_score_not_found, project_template_custom_field_not_found |
The row is not on this project template |
404 |
resource_type_not_found, cost_type_not_found, member_not_found, custom_field_not_found, rate_card_not_found |
A record a field names cannot be used |
422 |
missing_input, invalid_input |
A required field is missing, a field is unknown or has the wrong type, or a rule above refused the value |
422 |
item_has_lines, item_not_billable |
A task’s kind does not fit its lines |
422 |
baseline_template_not_archivable, baseline_status_required |
A baseline rule refused the change |
422 |
validation_failed |
The record would not save. errors lists why |