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. For potential projects in the sales pipeline, see the Opportunities API.

Ben Walker avatar
Written by Ben Walker
Updated this week

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 (active work).

contract_type

string

Either "fixed_price" or "time_and_materials".

budget_type

string | null

Either "project_level" or "per_stage".

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").

company_id

integer | null

Legacy field - ID of the associated Company. Use client for polymorphic client support.

team

object | null

Team assignment with id and name.

Financial Metrics

Note: Financial data requires the view_project_metrics permission. Without this permission, these fields will not be included in the response.

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.

Profitability Metrics

Note: These fields require the view_gross_profit permission in addition to view_project_metrics. Without this permission, these fields will not be included in the response.

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 (only in GET /projects/:id endpoint). See Deliverables below.

Example Object (Index)

The index endpoint returns a lightweight representation:

{
"id": 42,
"name": "Website Redesign for Acme Corp",
"project_number": "PRJ-001",
"description": "Complete overhaul of corporate website",
"currency": "AUD",
"project_type": "project",
"contract_type": "fixed_price",
"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
}

Example Object (Show)

The show endpoint includes comprehensive details and nested data:

{
"id": 42,
"name": "Website Redesign for Acme Corp",
"project_number": "PRJ-001",
"description": "Complete overhaul of corporate website",
"currency": "AUD",
"project_type": "project",
"contract_type": "fixed_price",
"budget_type": "project_level",
"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"
},
"company_id": 123,
"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",
"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,
"plan_only": false,
"purchase_number": null,
"claim_items_count": 0,
"tasks": [
{
"id": 1,
"name": "Client Interviews",
"note": "Interview key stakeholders",
"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"
}
}
]
}
]
}

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.

budget

decimal

Total budget (requires view_project_metrics permission).

invoiced_amount

decimal

Amount invoiced (requires view_project_metrics permission).

total_cost

decimal

Actual costs (requires view_project_metrics permission).

budget_invoiced_percent

decimal

Percentage invoiced (requires view_project_metrics permission).

plan_only

boolean

Whether this is a planning deliverable only.

purchase_number

string | null

Purchase order number.

claim_items_count

integer

Number of progress claim items.

project_phase_id

integer | null

Associated phase ID if grouped.

tasks

array

Array of task objects. See Task Object below.

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.

budget_type

string

Either "fixed" or "hourly" (requires view_project_metrics permission).

original_quantity_unit

string

Either "hour", "day", or "per_item" (requires view_project_metrics permission).

original_rate

decimal

Rate per unit (requires view_project_metrics permission).

original_duration

decimal

Estimated duration (requires view_project_metrics permission).

original_total

decimal

Original budget (rate × duration) (requires view_project_metrics permission).

variation_duration

decimal

Duration adjustments from variations (requires view_project_metrics permission).

variation_total

decimal

Budget adjustments from variations (requires view_project_metrics permission).

actual_duration

decimal

Actual time tracked (requires view_project_metrics permission).

actual_total

decimal

Actual costs incurred (requires view_project_metrics permission).

budget

decimal

Total budget including variations (requires view_project_metrics permission).

total

decimal

Total budget (original + variations) (requires view_project_metrics permission).

remaining

decimal

Budget remaining (requires view_project_metrics permission).

budget_used_percentage

decimal

Percentage of budget used (requires view_project_metrics permission).

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.


List all projects

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

Endpoint

GET /api/v1/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.getdrum.com/api/v1/projects \
-H "Authorization: Bearer YOUR_API_TOKEN"

Example Request with Filters

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

Example Request with Tags

curl "https://app.getdrum.com/api/v1/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",
"contract_type": "fixed_price",
"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",
"contract_type": "time_and_materials",
"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/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.getdrum.com/api/v1/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",
"contract_type": "fixed_price",
"budget_type": "project_level",
"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"
},
"company_id": 123,
"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,
"plan_only": false,
"purchase_number": null,
"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,
"plan_only": false,
"purchase_number": null,
"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"
}
}
]
}
]
}

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

Unauthorised - 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 Unauthorised

Occurs when:

  • No Authorisation 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 authorised 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

  • Multi-tenancy: All projects are scoped to accounts. Users can only access projects from accounts they belong to.

  • Authorisation: The API enforces permission-based access. Users are restricted to projects they have permission to view based on their role configuration.

  • Soft Deletes: Deleted projects are soft-deleted (archived) rather than permanently removed. Archived projects are not returned by the API.

  • Money Format: All monetary amounts are returned in decimal format (e.g., 75000.00 for $75,000). The currency field indicates the currency code.

  • Date Format: Dates are returned in ISO 8601 format (YYYY-MM-DD). Date times include time zone information.

  • Project vs Opportunity: This endpoint returns only won projects (project_type: "project"). Opportunities (sales pipeline projects) are accessed through the Opportunities API. If you attempt to access an opportunity through this endpoint, you will receive a 404 Not Found response.

  • Nested Data: The show endpoint includes nested deliverables and tasks arrays, ordered by position field. The index endpoint excludes this nested data for performance.

  • Polymorphic Clients: Projects can be associated with either a Company (external client) or BusinessOverhead (internal work). The client object includes a type field to distinguish between these.

  • Permission-Gated Fields: Financial and profitability data are conditionally included based on user permissions. API clients should handle missing fields gracefully.

  • Eager Loading: The API uses efficient eager loading to minimise database queries. Large projects with many deliverables/tasks may still result in substantial response payloads.

Did this answer your question?