REST API

Manage monitors, incidents, projects, and routing from code, and understand the two gates every request passes.

bash
curl "https://api.drumbeats.io/v1/monitors?project_id=<project-id>" \
  -H "X-API-Key: dk_live_<26-char-random>"
curl "https://api.drumbeats.io/v1/monitors?project_id=<project-id>" \
  -H "X-API-Key: dk_live_<26-char-random>"

One header, one base URL. The REST API manages monitors, incidents, projects, and notification routing.

SurfaceBase URLAuth
REST APIhttps://api.drumbeats.io/v1/X-API-Key header
Ping APIhttps://api.drumbeats.io/v1/ping/… and /v1/s-ping/…None

Every endpoint on this page sits under that one origin. The interactive OpenAPI explorer, where you can browse the schema and try requests against your own account, is at api.drumbeats.io/beats/api-docs/public.

Choose a key type#

Project-scopedAccount-scoped
ReachesOne projectEvery project you own or belong to
RoleInherits the creator's role on that projectYour role on each project, resolved per request
PermissionsRead plus monitor writes, fixedThe scopes you pick when minting it
Limit3 active per user per project3 active per user, a separate budget
Created inSettings → Project Settings → API KeysAccount → API Keys
Who can createOwners and Managers on the projectAnyone who owns at least one project

Both use the format dk_<env>_<26-char-random>, so dk_live_… in production and dk_test_… in staging. Both expire between 1 and 365 days from creation, and both can be revoked immediately.

Pick the shortest expiry that fits. A key minted for a one-off migration script should not outlive the migration.

Mint one#

  1. Open Settings → Project Settings → API Keys for a project key, or Account → API Keys for an account key.
  2. Click Create API Key.
  3. Enter a name and an expiry between 1 and 365 days. On an account key, select the permission scopes.
  4. Copy the key now. It is shown once and never again.

Pick the scopes#

Account-scoped keys carry explicit scopes. A scope decides what kind of action the key may take. The key's project role decides where.

ScopeGrants
readRead every resource its projects expose
manage_monitorsCreate, update, delete, and pause monitors. Manage status pages. Acknowledge and resolve incidents
manage_projectsCreate, update, and delete projects
manage_notificationsCreate, update, and delete notification channels and groups
destroyRequired, together with the OWNER role, to delete a project, a notification channel, or a group

Any write scope implies read, so you never need to select both. A key minted with no scopes at all is read-only, which is a reasonable default for reporting scripts and AI agents.

Project-scoped keys have no scope picker. They behave as read plus monitor writes, and they can never reach project, notification, or destructive operations regardless of the role they inherit. Those are account-key territory.

Pass both gates#

Every request is checked twice:

  1. Scope. Does the key hold the scope this operation requires?
  2. Role. Is the key's role on the target project high enough?

Creating a monitor needs manage_monitors and at least MEMBER on that project. A key with manage_monitors but only READONLY on the project is rejected. So is a key that is OWNER on the project but was minted without manage_monitors.

RoleCan do
OWNEREverything, including deleting the project. Required, with destroy, for destructive deletes
MANAGERCreate, update, and delete monitors. Update the project, manage members, manage API keys
MEMBERView and create monitors, acknowledge and resolve incidents, view channels and groups
READONLYView only

Target a project#

A project-scoped key is bound to one project, so most endpoints need no project_id. An account-scoped key spans projects, so pass project_id to pick one. That is the same parameter the list endpoints already take, such as GET /v1/monitors?project_id=….

GET /v1/projects takes no parameter and returns everything the key can see.

Handle the errors#

json
{ "error": "Description of what went wrong" }
{ "error": "Description of what went wrong" }
StatusMeaningWhat to do
200Success
201Created
400Invalid request. Missing fields, bad values, or a constraint violationRead the body. It names the specific problem
401Missing or invalid authenticationCheck the X-API-Key header and whether the key expired
403Authenticated but not permittedEither the role is too low or the key lacks the scope. The scope case carries "code": "INSUFFICIENT_API_KEY_SCOPE"
404Not foundAlso returned when the resource exists but belongs to a project this key cannot see
429Rate limitedBack off and retry. The limit is per key

Paginate#

ParameterDefaultMax
page1none
limit20200
json
{
  "data": [],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 42,
    "total_pages": 3,
    "has_next": true,
    "has_prev": false
  }
}
{
  "data": [],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 42,
    "total_pages": 3,
    "has_next": true,
    "has_prev": false
  }
}

Defaults suit a dashboard. Raise limit to 200 for batch scripts and walk has_next.

Endpoint reference#

ResourceCovers
MonitorsCreate, update, delete, pause, and query monitors and their pings
IncidentsList, acknowledge, and resolve incidents
ProjectsProjects and their membership
Notification channelsChannels and their types
Notification groupsGroups and the channels they fan out to

Next#

Ping API for the unauthenticated surface your jobs call. Incidents for the lifecycle these endpoints act on. Notifications for how routing maps to the channels and groups these endpoints return.