REST API
Manage monitors, incidents, projects, and routing from code, and understand the two gates every request passes.
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.
| Surface | Base URL | Auth |
|---|---|---|
| REST API | https://api.drumbeats.io/v1/ | X-API-Key header |
| Ping API | https://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-scoped | Account-scoped | |
|---|---|---|
| Reaches | One project | Every project you own or belong to |
| Role | Inherits the creator's role on that project | Your role on each project, resolved per request |
| Permissions | Read plus monitor writes, fixed | The scopes you pick when minting it |
| Limit | 3 active per user per project | 3 active per user, a separate budget |
| Created in | Settings → Project Settings → API Keys | Account → API Keys |
| Who can create | Owners and Managers on the project | Anyone 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#
- Open Settings → Project Settings → API Keys for a project key, or Account → API Keys for an account key.
- Click Create API Key.
- Enter a name and an expiry between 1 and 365 days. On an account key, select the permission scopes.
- 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.
| Scope | Grants |
|---|---|
read | Read every resource its projects expose |
manage_monitors | Create, update, delete, and pause monitors. Manage status pages. Acknowledge and resolve incidents |
manage_projects | Create, update, and delete projects |
manage_notifications | Create, update, and delete notification channels and groups |
destroy | Required, 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:
- Scope. Does the key hold the scope this operation requires?
- 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.
| Role | Can do |
|---|---|
OWNER | Everything, including deleting the project. Required, with destroy, for destructive deletes |
MANAGER | Create, update, and delete monitors. Update the project, manage members, manage API keys |
MEMBER | View and create monitors, acknowledge and resolve incidents, view channels and groups |
READONLY | View 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#
{ "error": "Description of what went wrong" }{ "error": "Description of what went wrong" }| Status | Meaning | What to do |
|---|---|---|
200 | Success | |
201 | Created | |
400 | Invalid request. Missing fields, bad values, or a constraint violation | Read the body. It names the specific problem |
401 | Missing or invalid authentication | Check the X-API-Key header and whether the key expired |
403 | Authenticated but not permitted | Either the role is too low or the key lacks the scope. The scope case carries "code": "INSUFFICIENT_API_KEY_SCOPE" |
404 | Not found | Also returned when the resource exists but belongs to a project this key cannot see |
429 | Rate limited | Back off and retry. The limit is per key |
Paginate#
| Parameter | Default | Max |
|---|---|---|
page | 1 | none |
limit | 20 | 200 |
{
"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#
| Resource | Covers |
|---|---|
| Monitors | Create, update, delete, pause, and query monitors and their pings |
| Incidents | List, acknowledge, and resolve incidents |
| Projects | Projects and their membership |
| Notification channels | Channels and their types |
| Notification groups | Groups 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.