Authentication and permissions
Every request runs as the Drum user who owns the token, inside the one account the token belongs to. The API applies the same permissions that user has in Drum.
Tokens
| Fact | Detail |
|---|---|
| Header | Authorization: Bearer <api-token> |
| Where tokens live | Your user menu, Profile, then API (https://app.getdrum.com/api_tokens) |
| Who can open that page | Account admins, and users whose role has at least one API permission |
| Account | Each token belongs to one account, chosen when it is created. It cannot be changed |
| Viewing the token | The token page shows the token (blurred, with a copy button) whenever you open it |
| Expiry | Tokens created in Drum do not expire. Revoke a token when it is no longer needed |
| Revoking | Revoke Token on the token page. The token stops working at once |
| Last used | The token page shows when the token was last used, updated at most once a minute |
To create, edit or revoke a token, see Create an API token.
A token also stores the MCP toolsets that AI clients may use with it. The REST endpoints on these pages ignore that setting.
Authentication errors
| Status | Body | When |
|---|---|---|
401 |
Empty | The header is missing, or the token is unknown, revoked or expired |
401 |
{"error": "This endpoint requires an account-scoped API token. ..."} |
An old token that has no account. Create a new token |
403 |
{"error": "Account access revoked"} |
The token’s user has been removed from the account |
The four API permissions
Each request first needs the API permission for its HTTP method. These are role permissions, set on the role in Drum.
| Method | Role permission |
|---|---|
GET, HEAD |
api_read |
POST |
api_create |
PATCH, PUT |
api_update |
DELETE |
api_delete |
Without it the request returns 403 {"error": "Insufficient API permissions"}.
Account admins skip this check and hold every record permission, so an admin’s token can change anything in the account.
Record permissions
After the API permission, Drum applies the same record rules as the web app. The page for each resource lists what it needs. In short:
| Area | Needs |
|---|---|
| Projects | read_all_projects, read_team_projects (projects of your teams) or read_assigned_projects (projects you are assigned to) |
| Opportunities | The opportunity read permissions to read. create_opportunities to create. update_all_opportunities, update_team_opportunities or update_assigned_opportunities to update. To convert: the update rights and create_projects, or read_quotes and accept_quotes (see Opportunities) |
| Opportunity money | view_opportunity_financial_values to see the deal value, and to set the deal value, deposit, lead score or invoicing structure |
| Project money | view_project_metrics, or a project role that can view budgets. view_gross_profit for gross profit |
| Staff cost rates | resource_financials |
| Costs | read_costs, create_costs, update_costs, approve_costs |
| Invoices | read_invoices, or a project role that can view invoices. create_invoices to allocate a Xero invoice |
| Write-offs | read_write_offs |
| Planned invoices | read_invoices, or a project role that can view planned invoices |
| Members | read_account_users |
| Webhook subscriptions | manage_webhooks |
Fields you cannot see are left out
When the token’s user may read a record but not its money, the money fields are left out of the response, or sent as null where the page says so. Treat every money field as optional.
Hidden records
Most endpoints answer 404 for a record the token’s user cannot read, so a hidden record looks the same as one that does not exist. A few older endpoints answer 403 instead (each resource page says which). Treat both as “not available to this token”.
Recommended setup for an integration
- Create a separate Drum user for the integration, with its own role.
- Give that role only the permissions the integration needs. It does not need to be an admin.
- Use one token for each integration, so you can revoke one without breaking the others.
- Keep tokens on your server. Never put one in browser or mobile code, a URL, a log, or a support message.
- Revoke the token straight away if it may have been exposed, then create a new one.
For example, an integration that posts supplier costs needs api_read, api_create, read_all_projects, read_costs and create_costs. Add read_account_users if it posts costs incurred by staff, and view_project_metrics if it needs the totals back.