REST API — Projects
Manage Drumbeats projects, members, and roles via the REST API. Writes require an account-scoped API key with the manage_projects scope.
The Drumbeats Projects API lists, retrieves, creates, updates, and deletes projects and their membership. GET /v1/projects is the only management endpoint that is not project-scoped — it returns every project the authenticated principal is a member of. Reads behave like the rest of the REST API: X-API-Key header on every request.
Project writes — create, update, delete — are reachable only by an account-scoped key with the right permission scope; a project-scoped key cannot create sibling projects, update a project, or delete one. Each write also enforces a project-role gate, listed per operation below.
List projects
GET /v1/projectsGET /v1/projectsReturns all projects where the authenticated principal is a member. Use this on the authenticated user's first call to discover their projects; subsequent calls can scope to a single project via /v1/projects/<project-id>.
curl https://api.drumbeats.io/v1/projects \
-H "X-API-Key: dk_live_<key>"curl https://api.drumbeats.io/v1/projects \
-H "X-API-Key: dk_live_<key>"Response:
{
"projects": [
{
"id": "<project-uuid>",
"name": "Drumbeats Internal",
"description": "Internal monitors for the Drumbeats stack",
"owner_id": "<user-uuid>",
"owner": {
"id": "<user-uuid>",
"email": "samed@drumbeats.io",
"first_name": "Samed",
"last_name": "Kahyaoglu"
},
"members": [
{
"id": "<member-uuid>",
"project_id": "<project-uuid>",
"user_id": "<user-uuid>",
"role": "OWNER",
"joined_at": "2026-01-15T10:30:00Z"
}
],
"_count": { "members": 3 },
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-05-10T08:00:00Z"
}
]
}{
"projects": [
{
"id": "<project-uuid>",
"name": "Drumbeats Internal",
"description": "Internal monitors for the Drumbeats stack",
"owner_id": "<user-uuid>",
"owner": {
"id": "<user-uuid>",
"email": "samed@drumbeats.io",
"first_name": "Samed",
"last_name": "Kahyaoglu"
},
"members": [
{
"id": "<member-uuid>",
"project_id": "<project-uuid>",
"user_id": "<user-uuid>",
"role": "OWNER",
"joined_at": "2026-01-15T10:30:00Z"
}
],
"_count": { "members": 3 },
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-05-10T08:00:00Z"
}
]
}Get a project
GET /v1/projects/<project-id>GET /v1/projects/<project-id>Returns one project with full member details — each members[i] row includes the embedded user object.
curl https://api.drumbeats.io/v1/projects/<project-id> \
-H "X-API-Key: dk_live_<key>"curl https://api.drumbeats.io/v1/projects/<project-id> \
-H "X-API-Key: dk_live_<key>"Response:
{
"project": {
"id": "<project-uuid>",
"name": "Drumbeats Internal",
"description": "Internal monitors for the Drumbeats stack",
"owner_id": "<user-uuid>",
"owner": { "id": "<user-uuid>", "email": "samed@drumbeats.io", "first_name": "Samed", "last_name": "Kahyaoglu" },
"members": [
{
"id": "<member-uuid>",
"project_id": "<project-uuid>",
"user_id": "<user-uuid>",
"role": "OWNER",
"joined_at": "2026-01-15T10:30:00Z",
"user": { "id": "<user-uuid>", "email": "samed@drumbeats.io", "first_name": "Samed", "last_name": "Kahyaoglu" }
}
],
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-05-10T08:00:00Z"
}
}{
"project": {
"id": "<project-uuid>",
"name": "Drumbeats Internal",
"description": "Internal monitors for the Drumbeats stack",
"owner_id": "<user-uuid>",
"owner": { "id": "<user-uuid>", "email": "samed@drumbeats.io", "first_name": "Samed", "last_name": "Kahyaoglu" },
"members": [
{
"id": "<member-uuid>",
"project_id": "<project-uuid>",
"user_id": "<user-uuid>",
"role": "OWNER",
"joined_at": "2026-01-15T10:30:00Z",
"user": { "id": "<user-uuid>", "email": "samed@drumbeats.io", "first_name": "Samed", "last_name": "Kahyaoglu" }
}
],
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-05-10T08:00:00Z"
}
}| Error status | Meaning |
|---|---|
404 | Project not found, or the API key does not have access. |
Create a project
POST /v1/projectsPOST /v1/projectsRequires an account-scoped key with the manage_projects scope. The authenticated user becomes the new project's owner, so there is no pre-existing project-role requirement.
| Field | Required | Type | Description |
|---|---|---|---|
name | Yes | string | Display name. |
description | No | string | Free-text description. |
curl -X POST https://api.drumbeats.io/v1/projects \
-H "X-API-Key: dk_live_<account-key>" \
-H "Content-Type: application/json" \
-d '{ "name": "API Monitors", "description": "Monitors for the public API" }'curl -X POST https://api.drumbeats.io/v1/projects \
-H "X-API-Key: dk_live_<account-key>" \
-H "Content-Type: application/json" \
-d '{ "name": "API Monitors", "description": "Monitors for the public API" }'Returns 201 with { "message": "Project created successfully", "project": { … } }.
Update a project
Requires the manage_projects scope and a MANAGER (or higher) role on the target project. Send only the fields you want to change.
Delete a project
Hard-gated: requires the destroy scope, an account-scoped key, and the OWNER role on the project. Deleting a project removes its monitors, ping history, and notification wiring — this cannot be undone.
A key that holds destroy but is not OWNER on the project — or a project-scoped key — is rejected with 403.
Member roles
The role field on each member determines what they can do across the management API.
| Role | Permissions |
|---|---|
OWNER | Everything, including deleting the project and managing the workspace owner seat. |
MANAGER | Create / update / delete monitors and notification channels, manage members, create / revoke API keys. |
MEMBER | View monitors, acknowledge and resolve incidents, view notification channels and groups. |
READONLY | View-only across all resources. Cannot acknowledge incidents. |
Related guides
- REST API overview — auth, pagination, and the full role matrix.
- Workspace setup — how owners onboard members and assign roles in the dashboard.
- REST API — Monitors — the project-scoped endpoints most automation actually wants.