Skip to main content

Reference data API

Look up project statuses, lead scores, cost types, finance accounts, members and companies before writing data through the Drum API.

Written by Ben Walker

Read-only lists an integration needs to pick valid ids before it writes an opportunity, a project, or a cost. All endpoints sit under /api/v1/, need an account-scoped bearer token, and paginate with page and items (default 25, max 100). See API authentication, permissions and rate limits.

GET /api/v1/project_statuses

Lists the kept statuses of the account's two baseline templates: opportunity statuses first, then project statuses, each in list order (position).

Parameter

Meaning

type

opportunity or project. Narrows the list to one template. Any other value returns 422 invalid_input

GET /api/v1/project_statuses?type=project

Response (200):

[
{
"id": 401,
"name": "Not Started",
"type": "project",
"position": 1,
"default": true,
"complete_status": false,
"sales_status_type": "standard",
"default_successful_status": false,
"default_lost_status": false,
"colour": "#94a3b8"
},
{
"id": 410,
"name": "Quote Accepted",
"type": "project",
"position": 2,
"default": false,
"complete_status": false,
"sales_status_type": "standard",
"default_successful_status": false,
"default_lost_status": false,
"colour": "#22c55e"
}
]

Field

Meaning

type

opportunity (usable in PATCH /opportunities/:id) or project (usable as project_status_id on convert)

default

The status new records take when none is given

complete_status

The status marks the record complete

sales_status_type

standard, won, or lost

default_successful_status, default_lost_status

The template's chosen won and lost statuses

position

List order inside the template

colour

Hex colour shown in Drum

Status ids are stable. Look up the id you need once and cache it.

GET /api/v1/lead_scores

Lists the kept lead scores of the account's opportunity template in list order.

Response (200):

[
{
"id": 51,
"name": "Warm",
"percentage": 50,
"default": true,
"position": 1
},
{
"id": 52,
"name": "Hot",
"percentage": 80,
"default": false,
"position": 2
}
]

GET /api/v1/cost_types

Lists the account's kept cost types (the categories a cost is filed under) in name order. A cost type is the cost_type_id of a cost; see Costs API.

Response (200):

[
{
"id": 610,
"name": "Subcontractor",
"code": "SUB",
"description": "Trade packages let to subcontractors",
"default": false,
"expense_default": false,
"default_finance_account_id": 310,
"line_item_code_id": null
}
]

Field

Meaning

code

Short code shown beside the name in Drum

default

The account's default cost type. POST /costs still requires an explicit cost_type_id; nothing is filled in for you

expense_default

The default cost type for expense claims in Drum

default_finance_account_id

Applied to any cost line item created without a finance_account_id. null when the cost type names none

line_item_code_id

A line item code the cost type applies to its lines. When set, that code's own finance account and price can replace what a cost line item gave

This endpoint takes no filters.

GET /api/v1/finance_accounts

Lists the account's finance accounts (its chart of accounts) in code then name order. A finance account is the finance_account_id of a cost line item; see Costs API.

Parameter

Meaning

account_type

Only accounts of this type. An unknown type returns 422 {"error": "...", "code": "invalid_input"}, and the message lists the accepted types

include_hidden

true also returns retired (hidden) accounts. Default false

GET /api/v1/finance_accounts?account_type=expense

Response (200):

[
{
"id": 310,
"name": "Subcontractors",
"code": "310",
"account_type": "expense",
"default": false,
"visible": true,
"tax_rate_id": 12
}
]

Field

Meaning

account_type

The chart of accounts classification

default

The account marked default for its group. Drum keeps one default sales account and one default expense account. A cost line item does not use this flag: it falls back to the cost type's default account

visible

false for a retired account. A hidden account is refused on a new cost line item, so post only visible ones

tax_rate_id

The tax rate the account carries. Drum copies it onto a cost line item that uses this account

Cost type ids and finance account ids are stable. Look up the ids you need once and cache them.

GET /api/v1/members

Lists the account's members (its staff) in name order. A member is the account_user_id of a cost, which is how a cost incurred by a member of staff is posted instead of one bought from a supplier; see Costs API. Deleted memberships are left out by default.

Parameter

Meaning

search

Name search

include_deleted

true also returns deleted memberships. Default false

GET /api/v1/members?search=jordan

Response (200):

[
{
"id": 4821,
"name": "Jordan Reed",
"full_name": "Jordan Reed",
"email": "[email protected]",
"role": "member",
"active": true,
"default_resource_type_id": 88
}
]

Field

Meaning

id

The account_user_id to send on a cost

name

The name the account gives the membership. This is what a staff cost returns as its supplier_name

full_name

The person's own name. This is what the API returns as account_user_name on a tracked time and as approved_by_name and created_by_name on a cost

email

The user's sign-in email, the stable key for matching a member to your own staff records

role

admin, member, or timesheet_only. An admin holds every permission in the account

active

false for a deleted membership, which only appears when include_deleted is true. POST /costs refuses a deleted member with account_user_not_found, so post only active ones

default_resource_type_id

The member's default resource type (their charge-out role), or null when they have none

Member ids are stable. Look up the id you need once and cache it.

This endpoint needs the member read permission (read_account_users), not read_costs; see API authentication, permissions and rate limits.

GET /api/v1/companies

Lists kept companies the token user can see, ordered by trading name.

Parameter

Meaning

search

Name search

company_type

client, supplier, or both. The filter matches the stored value exactly, so supplier leaves out a company typed both. To list everything you can buy from, request supplier and both and join the two results. Any other value returns an empty list

status

Company status id

company_tag_list

Tag names; a company must carry all of them

GET /api/v1/companies?search=acme&company_type=client

Response (200):

[
{
"id": 789,
"trading_name": "Acme Corporation",
"legal_name": "Acme Corporation Pty Ltd",
"finance_name": "Acme Corp",
"client_code": "ACME",
"client_number": 118,
"company_type": "client",
"email": "[email protected]",
"phone": "+61 2 5550 1234",
"website": "https://acme.example",
"company_status": {
"id": 7,
"name": "Active"
},
"created_at": "2025-03-02T01:12:44Z",
"updated_at": "2026-08-30T22:05:10Z"
}
]

company_status is null when the company has none. The tax number is never returned.

GET /api/v1/companies/:id

Returns one company in the same shape. A discarded company, or an id from another account, returns 404 with {"error": "Not found", "code": "not_found"}.

Did this answer your question?