Skip to main content

Projects API

The Projects API allows you to retrieve and manage won projects within your Drum account. Projects represent actual work engagements that have been won and are active or completed.

Written by Ben Walker
Updated over a week ago

Authentication

All API requests require authentication using a Bearer token. Include your API token in the Authorization header of each request:

Authorization: Bearer YOUR_API_TOKEN

For detailed information about authentication, token generation, and permissions, see the API Authentication documentation.

All endpoints are scoped to a specific account. Only projects belonging to the authenticated user's account will be accessible.

The Project Object

A project object represents a won client engagement or internal project within Drum. This endpoint only returns projects with project_type: "project". For opportunities in the sales pipeline, use the Opportunities API.

Core Attributes

Attribute

Type

Description

id

integer

Unique identifier for the project.

name

string

The project name.

description

string | null

Optional detailed description of the project.

project_number

string

Unique project number/code.

currency

string

Three-letter ISO currency code (e.g., "AUD", "USD", "GBP").

Classification

Attribute

Type

Description

project_type

string

Always "project" for this endpoint.

progress_claim_mode

string

Either "deliverable" or "task".

Dates

Attribute

Type

Description

start_date

string | null

Project start date in ISO 8601 format (YYYY-MM-DD).

end_date

string | null

Project end date in ISO 8601 format (YYYY-MM-DD).

completed_date

string | null

Date the project was completed.

Associations

Attribute

Type

Description

project_status

object | null

Project status details including id, name, and complete_status boolean.

client

object | null

Client information with id, name, and type (either "Company" or "BusinessOverhead").

team

object | null

Team assignment with id and name.

Financial Metrics

Note:

  • total_budget follows the same view_project_metrics check used on the HTML project page.

  • total_invoiced, costs_to_date, and unbilled_costs are only included when time tracking is enabled and the user can view project metrics, matching the HTML project page's financial views.

  • On the index endpoint, total_budget follows the same rules as the HTML projects index financial column: time tracking must be enabled and the user must have project insights access.

Attribute

Type

Description

total_budget

decimal

Total project budget in currency units.

total_invoiced

decimal

Total amount invoiced to client.

costs_to_date

decimal

Actual costs incurred on the project.

unbilled_costs

decimal

Costs not yet invoiced to client.

Project Health Metrics

Note:

  • work_in_progress is only included when the account is configured to show WIP on project financial views.

  • remaining_cost_to_complete is only included when cost-to-complete estimates are enabled and shown for projects.

  • Both fields also require the same time-tracking and view_project_metrics access needed for the HTML project financial views.

Attribute

Type

Description

work_in_progress

decimal

WIP calculation (invoiced - earned revenue).

remaining_cost_to_complete

decimal

Estimated costs remaining to complete the project.

Retention (if enabled)

Attribute

Type

Description

retention_percent

decimal

Percentage of each progress claim withheld.

retention_amount

decimal

Total retention amount on project budget.

retention_withheld

decimal

Amount withheld from approved claims.

retention_released

decimal

Retention released back to client.

retention_outstanding

decimal

Retention still withheld.

Counters

Attribute

Type

Description

quotes_count

integer

Number of quotes associated with project.

invoices_count

integer

Number of invoices.

progress_claims_count

integer

Number of progress claims.

costs_count

integer

Number of cost entries.

Metadata

Attribute

Type

Description

project_tags

array of strings

Tags applied to the project.

planned

boolean

Whether project is in planning state.

skip_planning

boolean

Whether to skip planning phase.

Nested Data (Show Endpoint Only)

Attribute

Type

Description

deliverables

array

Array of deliverable objects. See Deliverable Object.

contacts

array

Array of contact objects associated with the project, ordered by position. See Contact Object.

addresses

array

Array of address objects associated with the project. Ordered with primary addresses first, then billing addresses, then by id. See Address Object.

Example Payloads

For concrete JSON payloads, see:

Deliverable Object

A deliverable represents a phase or work package within a project. In Drum, deliverables structure project work into logical chunks. Deliverables are ordered by the position field.

Attributes

Attribute

Type

Description

id

integer

Unique identifier for the procedure.

name

string

Name of the deliverable/phase.

description

string | null

Detailed description.

position

integer

Sort order within the project (1-indexed).

status

string

One of: "not_started", "in_progress", "completed", "not_applicable", "blocked".

billing_type

string

Either "fixed_fee" or "time_and_materials".

allow_time_tracking

string

Either "allowed", "allowed_if_assigned", or "not_allowed".

percentage_complete

integer

Completion percentage (0-100).

currency

string

Currency code.

start_date

string | null

Start date.

end_date

string | null

End date.

duration

decimal

Estimated duration in hours.

claim_items_count

integer

Number of progress claim items.

project_phase_id

integer | null

Associated phase ID if grouped. Only included when set.

tasks

array

Array of task objects. See Task Object.

Requires the same access as the HTML project deliverables view (omitted otherwise): time tracking must be enabled and the user must have view_project_metrics.

Task Object

A task represents an individual work item within a deliverable. Tasks are ordered by the position field.

Attributes

Attribute

Type

Description

id

integer

Unique identifier for the task.

name

string

Task name.

note

text | null

Additional notes or description.

position

integer

Sort order within the deliverable (1-indexed).

item_type

string

One of: "task", "heading", "event", "process_only".

status

string

One of: "not_started", "in_progress", "completed", "not_applicable", "blocked".

allow_time_tracking

string

Either "allowed", "not_allowed", or "allowed_if_assigned".

active

boolean

Whether the task is active.

visible

boolean

Whether the task is visible.

currency

string

Currency code.

due_date

string | null

Task due date.

start_date

string | null

Task start date.

estimated_start_date

string | null

Estimated start date.

completed_date

string | null

Date the task was completed.

tracked_times_count

integer

Number of time entries.

costs_count

integer

Number of cost entries.

booked_bookings_count

integer

Number of bookings.

resource_type

object | null

Resource type with id and name if assigned.

Requires the same access as the HTML project tasks view (omitted otherwise): time tracking must be enabled and the user must have view_project_metrics.

Contact Object

A contact represents a person associated with the project — typically the client-side point of contact, site representative, or other stakeholder. Contacts are ordered by the position field.

Attributes

Attribute

Type

Description

id

integer

Unique identifier for the contact.

first_name

string

Contact's first name.

last_name

string | null

Contact's last name.

name

string

Full name (first + last).

email

string | null

Email address.

mobile_phone

string | null

Mobile phone number.

office_phone

string | null

Office phone number.

title

string | null

Job title or role (e.g., "Project Manager", "CEO").

description

string | null

Notes about this contact's involvement in the project.

pinned

boolean

Whether the contact is pinned/highlighted on the project.

position

integer | null

Sort order within the project's contacts list.

Address Object

An address represents a physical location associated with the project — typically the site address, billing address, or other location-specific details. A project may have multiple addresses.

Attributes

Attribute

Type

Description

id

integer

Unique identifier for the address.

address_type

string | null

Either "physical" or "postal".

billing_address

boolean

Whether this is the billing address for the project.

primary

boolean

Whether this is the primary address for the project.

line_one

string

First address line (e.g., street number and name).

line_two

string | null

Second address line (e.g., unit number).

suburb

string | null

Suburb or city.

state

string | null

State, province, or region.

post_code

string | null

Postal or ZIP code.

country

string | null

Two-letter ISO country code (e.g., "AU", "US").

lot_number

string | null

Lot number (used primarily for construction projects in AU/NZ markets).

note

string | null

Freeform notes about the address.


List all projects

Returns a paginated list of projects for the authenticated account. Results can be filtered using query parameters.

Endpoint

GET /api/v1/accounts/:account_id/projects

Path Parameters

Parameter

Type

Description

account_id

integer

The ID of the account to retrieve projects from. Must be an account the authenticated user has access to.

Query Parameters

Parameter

Type

Description

status

integer

Filter by project status ID. Only projects with this project_status_id will be returned.

project_status

integer

Alternative filter by project status ID (same as status).

assigned_to

integer

Filter by assigned user. Provide an account_user_id to return only projects where that user is assigned.

project_tag_list

array of strings

Filter by project tags. Provide one or more tag names to return projects with any of those tags. Example: project_tag_list[]=urgent&project_tag_list[]=client-facing

page

integer

Page number for pagination. Defaults to 1.

items

integer

Number of items per page. Defaults to 20.

Example Request

curl https://app.drumhq.com/api/v1/accounts/1/projects \
-H "Authorization: Bearer YOUR_API_TOKEN"

Example Request with Filters

curl "https://app.drumhq.com/api/v1/accounts/1/projects?status=5&assigned_to=42&page=1&items=50" \
-H "Authorization: Bearer YOUR_API_TOKEN"

Example Request with Tags

curl "https://app.drumhq.com/api/v1/accounts/1/projects?project_tag_list[]=urgent&project_tag_list[]=design" \
-H "Authorization: Bearer YOUR_API_TOKEN"

Response

Returns an array of project objects. The index endpoint returns a lightweight representation without nested data.

Note: Financial fields (total_budget) are only included if the user has the view_project_metrics permission.

[
{
"id": 42,
"name": "Website Redesign for Acme Corp",
"project_number": "PRJ-001",
"description": "Complete overhaul of corporate website including new branding, responsive design, and CMS integration",
"currency": "AUD",
"project_type": "project",
"start_date": "2025-01-15",
"end_date": "2025-04-30",
"project_status": {
"id": 5,
"name": "In Progress",
"complete_status": false
},
"client": {
"id": 123,
"name": "Acme Corp",
"type": "Company"
},
"team": {
"id": 2,
"name": "Design Team"
},
"total_budget": 75000.00,
"planned": false
},
{
"id": 43,
"name": "Mobile App Development",
"project_number": "PRJ-002",
"description": "Native iOS and Android app for customer portal",
"currency": "AUD",
"project_type": "project",
"start_date": "2025-02-01",
"end_date": "2025-07-31",
"project_status": {
"id": 5,
"name": "In Progress",
"complete_status": false
},
"client": {
"id": 124,
"name": "Tech Startup Inc",
"type": "Company"
},
"team": {
"id": 3,
"name": "Development Team"
},
"total_budget": 120000.00,
"planned": false
}
]

Note: The API uses pagination via the page and items query parameters. Use pagination metadata from response headers if available, or implement client-side pagination based on the number of results returned.


Retrieve a project

Retrieves the details of a specific project by ID.

Endpoint

GET /api/v1/accounts/:account_id/projects/:id

Path Parameters

Parameter

Type

Description

account_id

integer

The ID of the account the project belongs to.

id

integer

The ID of the project to retrieve.

Example Request

curl https://app.drumhq.com/api/v1/accounts/1/projects/42 \
-H "Authorization: Bearer YOUR_API_TOKEN"

Response

Returns a comprehensive project object with nested deliverables and tasks.

Note: Financial fields require appropriate permissions:

  • Basic financial data (total_budget, total_invoiced, etc.) requires view_project_metrics permission

  • Profitability metrics (work_in_progress, remaining_cost_to_complete) require both view_project_metrics AND view_gross_profit permissions

{
"id": 42,
"name": "Website Redesign for Acme Corp",
"project_number": "PRJ-001",
"description": "Complete overhaul of corporate website including new branding, responsive design, and CMS integration",
"currency": "AUD",
"project_type": "project",
"progress_claim_mode": "deliverable",
"start_date": "2025-01-15",
"end_date": "2025-04-30",
"completed_date": null,
"project_status": {
"id": 5,
"name": "In Progress",
"complete_status": false
},
"client": {
"id": 123,
"name": "Acme Corp",
"type": "Company"
},
"team": {
"id": 2,
"name": "Design Team"
},
"total_budget": 75000.00,
"total_invoiced": 45000.00,
"costs_to_date": 38000.00,
"unbilled_costs": 5000.00,
"work_in_progress": 2000.00,
"remaining_cost_to_complete": 12000.00,
"quotes_count": 1,
"invoices_count": 3,
"progress_claims_count": 2,
"costs_count": 45,
"project_tags": ["web-design", "urgent"],
"planned": false,
"skip_planning": false,
"deliverables": [
{
"id": 1,
"name": "Discovery & Research",
"description": "Initial discovery phase including stakeholder interviews and requirements gathering",
"position": 1,
"status": "completed",
"billing_type": "fixed_fee",
"allow_time_tracking": "allowed",
"percentage_complete": 100,
"currency": "AUD",
"start_date": "2025-01-15",
"end_date": "2025-02-01",
"duration": 80.0,
"budget": 10000.00,
"invoiced_amount": 10000.00,
"total_cost": 9500.00,
"budget_invoiced_percent": 100.0,
"claim_items_count": 0,
"tasks": [
{
"id": 1,
"name": "Client Interviews",
"note": "Interview key stakeholders to understand requirements",
"position": 1,
"item_type": "task",
"status": "completed",
"allow_time_tracking": "allowed",
"active": true,
"visible": true,
"currency": "AUD",
"due_date": "2025-01-20",
"start_date": "2025-01-15",
"estimated_start_date": null,
"completed_date": "2025-01-20T10:30:00Z",
"budget_type": "hourly",
"original_quantity_unit": "hour",
"original_rate": 150.00,
"original_duration": 8.0,
"original_total": 1200.00,
"variation_duration": 0.0,
"variation_total": 0.0,
"actual_duration": 7.5,
"actual_total": 1125.00,
"budget": 1200.00,
"total": 1200.00,
"remaining": 75.00,
"budget_used_percentage": 93.75,
"tracked_times_count": 3,
"costs_count": 0,
"booked_bookings_count": 0,
"resource_type": {
"id": 5,
"name": "Senior Consultant"
}
},
{
"id": 2,
"name": "Competitive Analysis",
"note": null,
"position": 2,
"item_type": "task",
"status": "completed",
"allow_time_tracking": "allowed",
"active": true,
"visible": true,
"currency": "AUD",
"due_date": "2025-01-25",
"start_date": "2025-01-20",
"estimated_start_date": null,
"completed_date": "2025-01-24T16:00:00Z",
"budget_type": "hourly",
"original_quantity_unit": "hour",
"original_rate": 125.00,
"original_duration": 16.0,
"original_total": 2000.00,
"variation_duration": 0.0,
"variation_total": 0.0,
"actual_duration": 18.0,
"actual_total": 2250.00,
"budget": 2000.00,
"total": 2000.00,
"remaining": -250.00,
"budget_used_percentage": 112.5,
"tracked_times_count": 5,
"costs_count": 0,
"booked_bookings_count": 0,
"resource_type": {
"id": 6,
"name": "UX Researcher"
}
}
]
},
{
"id": 2,
"name": "Design Phase",
"description": "UI/UX design and prototyping",
"position": 2,
"status": "in_progress",
"billing_type": "fixed_fee",
"allow_time_tracking": "allowed",
"percentage_complete": 45,
"currency": "AUD",
"start_date": "2025-02-01",
"end_date": "2025-03-15",
"duration": 120.0,
"budget": 15000.00,
"invoiced_amount": 0.00,
"total_cost": 6750.00,
"budget_invoiced_percent": 0.0,
"claim_items_count": 0,
"tasks": [
{
"id": 3,
"name": "Wireframe Development",
"note": "Create low-fidelity wireframes for all pages",
"position": 1,
"item_type": "task",
"status": "completed",
"allow_time_tracking": "allowed",
"active": true,
"visible": true,
"currency": "AUD",
"due_date": "2025-02-15",
"start_date": "2025-02-01",
"estimated_start_date": null,
"completed_date": "2025-02-14T14:00:00Z",
"budget_type": "hourly",
"original_quantity_unit": "hour",
"original_rate": 125.00,
"original_duration": 24.0,
"original_total": 3000.00,
"variation_duration": 0.0,
"variation_total": 0.0,
"actual_duration": 24.0,
"actual_total": 3000.00,
"budget": 3000.00,
"total": 3000.00,
"remaining": 0.00,
"budget_used_percentage": 100.0,
"tracked_times_count": 8,
"costs_count": 0,
"booked_bookings_count": 0,
"resource_type": {
"id": 6,
"name": "UX Researcher"
}
},
{
"id": 4,
"name": "High-Fidelity Mockups",
"note": "Design visual mockups based on approved wireframes",
"position": 2,
"item_type": "task",
"status": "in_progress",
"allow_time_tracking": "allowed",
"active": true,
"visible": true,
"currency": "AUD",
"due_date": "2025-03-01",
"start_date": "2025-02-15",
"estimated_start_date": null,
"completed_date": null,
"budget_type": "hourly",
"original_quantity_unit": "hour",
"original_rate": 150.00,
"original_duration": 40.0,
"original_total": 6000.00,
"variation_duration": 0.0,
"variation_total": 0.0,
"actual_duration": 25.0,
"actual_total": 3750.00,
"budget": 6000.00,
"total": 6000.00,
"remaining": 2250.00,
"budget_used_percentage": 62.5,
"tracked_times_count": 12,
"costs_count": 0,
"booked_bookings_count": 1,
"resource_type": {
"id": 7,
"name": "Senior Designer"
}
}
]
}
],
"contacts": [
{
"id": 301,
"first_name": "Jane",
"last_name": "Doe",
"name": "Jane Doe",
"email": "[email protected]",
"mobile_phone": "+61 400 000 000",
"office_phone": "",
"title": "Head of Marketing",
"description": "Primary approver for creative decisions",
"pinned": true,
"position": 1
},
{
"id": 302,
"first_name": "John",
"last_name": "Smith",
"name": "John Smith",
"email": "[email protected]",
"mobile_phone": "",
"office_phone": "+61 2 9000 0000",
"title": "Finance Manager",
"description": null,
"pinned": false,
"position": 2
}
],
"addresses": [
{
"id": 1001,
"address_type": "physical",
"billing_address": true,
"primary": true,
"line_one": "10 George Street",
"line_two": "Level 3",
"suburb": "Sydney",
"state": "NSW",
"post_code": "2000",
"country": "AU",
"lot_number": "",
"note": "Access via rear loading bay"
}
]
}

Error Responses

The Projects API uses standard HTTP response codes to indicate success or failure.

HTTP Status Codes

Status Code

Description

200

Success - The request was successful.

401

Unauthorized - Missing, invalid, or expired API token.

403

Forbidden - The authenticated user lacks the required API permissions (api_read, api_create, api_update, or api_delete).

404

Not Found - The requested account or project does not exist, or the authenticated user does not have access.

Error Response Format

Error responses include a standard structure with details about what went wrong:

{
"error": {
"message": "Project not found or not accessible",
"type": "not_found",
"code": 404
}
}

Common Error Scenarios

401 Unauthorized

Occurs when:

  • No Authorization header is provided

  • The API token is invalid or malformed

  • The API token has expired

Solution: Verify your API token is valid and properly included in the Authorization header.

403 Forbidden

Occurs when:

  • The authenticated user's role lacks the required API permissions

  • The account user has been archived or deactivated

Solution: Contact your account administrator to verify your API permissions. Admin users automatically have all API permissions.

404 Not Found

Occurs when:

  • The specified account ID doesn't exist or you don't have access

  • The specified project ID doesn't exist within the account

  • The project exists but belongs to a different account

  • The ID refers to an opportunity (use the Opportunities API instead)

Solution: Verify the account_id and project id are correct and that you have access to the account. If you receive a 404 when you know the ID exists, check if it's an opportunity (project_type: "opportunity") rather than a won project.


Rate Limiting

Currently, rate limiting is not enforced on API requests. However, infrastructure is in place for future rate limiting:

  • General API: 300 requests per 5 minutes per IP address

  • Per endpoint throttling may be introduced as needed

We recommend implementing exponential backoff in your API client to handle potential future rate limits gracefully.


API Permissions

The Projects API requires multiple levels of permissions:

Base API Permissions

Required based on HTTP method:

Method

Required Permission

GET

api_read

POST

api_create

PUT/PATCH

api_update

DELETE

api_delete

Project Visibility Permissions

In addition to api_read, users need one of the following permissions to view projects:

Permission

Description

read_all_projects

Access all projects in the account

read_team_projects

Access projects assigned to team members

read_assigned_projects

Access only projects where user is directly assigned

Financial Data Permissions

Financial data visibility is controlled by additional permissions:

Permission

Data Included

view_project_metrics

Basic financial data: total_budget, total_invoiced, costs_to_date, unbilled_costs, and all task/deliverable financial fields

view_gross_profit

Profitability metrics: work_in_progress, remaining_cost_to_complete (requires view_project_metrics as well)

Note: Without these permissions, financial fields will be completely excluded from API responses. This ensures sensitive financial data is only visible to authorized users.

Permission Hierarchy

  • Account administrators automatically have all API permissions

  • Other users must be granted permissions through their account role configuration

  • Financial permissions are additive: view_gross_profit requires view_project_metrics to be useful


Notes

  • Soft Deletes: Deleted projects are archived (soft-deleted) and excluded from API responses.

  • Money Format: Monetary amounts are decimals (e.g., 75000.00) in the currency indicated by the currency field.

  • Date Format: Dates use ISO 8601 (YYYY-MM-DD); datetimes include a time zone.

  • Project vs Opportunity: This endpoint returns only won projects (project_type: "project"). Opportunities are served by the Opportunities API; requesting an opportunity ID here returns 404.

  • Nested Data: The show endpoint embeds deliverables (with tasks), contacts, and addresses. Deliverables, tasks, and contacts are ordered by position; addresses surface primary then billing first. Index excludes all nested data.

  • Polymorphic Clients: A project's client can be a Company (external) or BusinessOverhead (internal). The client.type field distinguishes them.

  • Permission-Gated Fields: Financial and profitability fields are omitted entirely when the user lacks the relevant permission — clients should treat them as optional.

Did this answer your question?