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

http
GET /v1/projects
GET /v1/projects

Returns 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>.

bash
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:

json
{
  "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

http
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.

bash
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:

json
{
  "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 statusMeaning
404Project not found, or the API key does not have access.

Create a project

http
POST /v1/projects
POST /v1/projects

Requires 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.

FieldRequiredTypeDescription
nameYesstringDisplay name.
descriptionNostringFree-text description.
bash
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.

RolePermissions
OWNEREverything, including deleting the project and managing the workspace owner seat.
MANAGERCreate / update / delete monitors and notification channels, manage members, create / revoke API keys.
MEMBERView monitors, acknowledge and resolve incidents, view notification channels and groups.
READONLYView-only across all resources. Cannot acknowledge incidents.