REST API projects

Manage projects and read their membership, and know what each destructive route actually destroys.

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

GET /v1/projects is the one management endpoint that takes no project_id. It returns every project the key can reach, which makes it the right first call when you do not know the IDs yet.

Writes here need an account-scoped key. A project-scoped key can read, but it cannot create a sibling project, rename its own, or delete anything. Each write also has a role gate, listed per operation.

List projects#

http
GET /v1/projects
GET /v1/projects
json
{
  "projects": [
    {
      "id": "<project-uuid>",
      "name": "Drumbeats Internal",
      "description": "Internal monitors for the Drumbeats stack",
      "owner_id": "<user-uuid>",
      "owner": {
        "id": "<user-uuid>",
        "email": "owner@example.com",
        "first_name": "Alex",
        "last_name": "Rivera"
      },
      "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-07-30T08: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": "owner@example.com",
        "first_name": "Alex",
        "last_name": "Rivera"
      },
      "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-07-30T08:00:00Z"
    }
  ]
}

Get one project#

http
GET /v1/projects/<project-id>
GET /v1/projects/<project-id>

Same shape, with each member row carrying an embedded user object.

A 404 here means either the project does not exist or the key cannot see it. The two are indistinguishable from outside.

Create a project#

http
POST /v1/projects
POST /v1/projects

Needs an account-scoped key with manage_projects. There is no role gate, because you become the new project's owner.

FieldRequiredNotes
nameyesDisplay name
descriptionnoFree text
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.

Update a project#

http
PATCH /v1/projects/<project-id>
PATCH /v1/projects/<project-id>

Needs manage_projects and MANAGER or higher on that project. Send only what changes.

Delete a project#

Roles#

RoleCan do
OWNEREverything, including deleting the project
MANAGERCreate, update, and delete monitors and channels. Manage members and API keys
MEMBERView and create monitors, acknowledge and resolve incidents, view channels and groups
READONLYView only. Cannot acknowledge

An account-scoped key resolves to your role on each project it touches, so one key can be OWNER on one project and READONLY on another in the same request sequence.

Next#

REST API overview for auth, scopes, and the two gates. Workspace setup for onboarding members in the dashboard. REST API monitors for the endpoints most automation actually wants.