REST API monitors
Create, query, and control monitors from code, with the full field reference for every type.
curl "https://api.drumbeats.io/v1/monitors?project_id=<project-id>" \
-H "X-API-Key: dk_live_<key>"curl "https://api.drumbeats.io/v1/monitors?project_id=<project-id>" \
-H "X-API-Key: dk_live_<key>"Writes on this resource need the manage_monitors scope plus the project role listed per operation. Project-scoped keys carry monitor writes already. Account-scoped keys must have been minted with the scope selected. See permission scopes.
List monitors#
GET /v1/monitors?project_id=<project-id>GET /v1/monitors?project_id=<project-id>{
"monitors": [
{
"id": "<monitor-uuid>",
"project_id": "<project-uuid>",
"slug": "daily-backup",
"name": "Daily backup job",
"description": "Nightly database backup",
"tags": ["database", "backup"],
"type": "JOB_CRON",
"schedule": "0 2 * * *",
"timezone": "UTC",
"grace_period_seconds": 300,
"schedule_tolerance": 1,
"failure_tolerance": 1,
"min_duration_seconds": 60,
"max_duration_seconds": 300,
"alert_enabled": true,
"alert_surge_threshold": 10,
"alerts_paused_until": null,
"retention_count": 200,
"notification_group_ids": [],
"status": "UP",
"consecutive_failures": 0,
"consecutive_misses": 0,
"consecutive_alerts": 0,
"last_success_at": "2026-07-31T02:00:00.000Z",
"next_expected_at": "2026-08-01T02:00:00.000Z",
"created_at": "2026-04-15T12:00:00.000Z",
"updated_at": "2026-07-31T02:00:00.000Z"
}
]
}{
"monitors": [
{
"id": "<monitor-uuid>",
"project_id": "<project-uuid>",
"slug": "daily-backup",
"name": "Daily backup job",
"description": "Nightly database backup",
"tags": ["database", "backup"],
"type": "JOB_CRON",
"schedule": "0 2 * * *",
"timezone": "UTC",
"grace_period_seconds": 300,
"schedule_tolerance": 1,
"failure_tolerance": 1,
"min_duration_seconds": 60,
"max_duration_seconds": 300,
"alert_enabled": true,
"alert_surge_threshold": 10,
"alerts_paused_until": null,
"retention_count": 200,
"notification_group_ids": [],
"status": "UP",
"consecutive_failures": 0,
"consecutive_misses": 0,
"consecutive_alerts": 0,
"last_success_at": "2026-07-31T02:00:00.000Z",
"next_expected_at": "2026-08-01T02:00:00.000Z",
"created_at": "2026-04-15T12:00:00.000Z",
"updated_at": "2026-07-31T02:00:00.000Z"
}
]
}alerts_paused_until is set when surge protection kicks in, and holds a timestamp one hour out. next_expected_at is always null on JOB_BASIC monitors, which have no schedule to be late against.
Get one monitor#
GET /v1/monitors/<monitor-id>GET /v1/monitors/<monitor-id>Returns { "monitor": { … } } with the shape above.
Create a monitor#
POST /v1/monitorsPOST /v1/monitorsNeeds the MEMBER role or higher.
| Field | Required | Default | Notes |
|---|---|---|---|
project_id | yes | Project to create it in | |
name | yes | 1 to 100 characters | |
type | yes | JOB_CRON, JOB_HEARTBEAT, JOB_BASIC, or UPTIME_HTTP | |
schedule | yes | Cron expression for JOB_CRON. Interval string for JOB_HEARTBEAT and UPTIME_HTTP. Required but not evaluated for JOB_BASIC | |
timezone | no | UTC | Any IANA zone. Applies to cron schedules |
slug | no | Lowercase letters, digits, and hyphens. Up to 50 characters. Used by the slug ping URL | |
description | no | Up to 500 characters | |
tags | no | [] | Up to 10 tags, 50 characters each |
grace_period_seconds | no | 300 | Wait past next_expected_at before opening a MISSED incident |
schedule_tolerance | no | 1 | Consecutive misses before flipping DOWN. Minimum 1 |
failure_tolerance | no | 1 | Consecutive failures before flipping DOWN. Minimum 1 |
min_duration_seconds | no | Floor for DURATION_LOW. Must be less than max_duration_seconds | |
max_duration_seconds | no | Ceiling for DURATION_HIGH and hung-run detection | |
alert_enabled | no | true | Set false to record incidents without paging |
alert_surge_threshold | no | 10 | Consecutive alerts before paging pauses for an hour |
retention_count | no | 200 | Pings to keep. Between 10 and 1000 |
notification_group_ids | no | [] | Groups to page |
notification_channel_ids | no | [] | Channels to page directly, without a group |
Returns 201 with { "message": …, "monitor": { … } }.
Uptime-only fields#
These are accepted only when type is UPTIME_HTTP and rejected on every other type.
| Field | Required | Default | Notes |
|---|---|---|---|
uptime_url | yes | HTTP or HTTPS. Credentials in the URL are rejected, use headers | |
uptime_method | no | GET | GET, HEAD, or POST |
uptime_expected_status | no | any 2xx | Array of status codes between 100 and 599 |
uptime_keyword | no | Body must contain this string. Up to 1024 characters | |
uptime_keyword_absent | no | false | Invert the keyword check |
uptime_headers | no | JSON object. Hop-by-hop header names are rejected | |
uptime_request_body | no | Up to 10 000 characters | |
uptime_timeout_ms | no | 10000 | Between 1000 and 30 000 |
uptime_follow_redirects | no | true | |
uptime_verify_ssl | no | true | Set false to accept self-signed certificates |
Update a monitor#
Needs MANAGER or higher. Send only the fields you are changing.
Delete a monitor#
Needs MANAGER or higher. This hard-deletes the monitor and its entire ping history. There is no undo and no soft-delete window.
Pause and resume#
A paused monitor still accepts pings but does not evaluate them, so no incidents open and nothing pages. Pings sent while paused return 200 with code: MONITOR_PAUSED, which keeps curl -f in a cron wrapper from failing the job.
Pause before planned maintenance, resume after. This is better than letting a monitor flap and then explaining the noise to your team.
Read ping history#
| Parameter | Default | Notes |
|---|---|---|
page | 1 | |
limit | 20 | Max 100 |
event | START, SUCCESS, FAILURE, or LOG | |
run_id | One execution | |
exit_code | Filter by numeric code | |
duration_assertion | PASS, TOO_FAST, or TOO_SLOW | |
from_date | ISO datetime | |
to_date | ISO datetime |
Fetch a full payload#
truncated: true means the payload exceeded your plan limit when it arrived and the excess was discarded at write time. It cannot be recovered.
Read incidents and warnings#
Incidents here are scoped to one monitor. For cross-monitor queries use the Incidents API.
Warnings are advisory notes about how the monitor is being used, computed over the last 7 days and up to 50 pings:
Worth polling in CI. It catches the wiring mistakes that make a monitor look healthy while it quietly cannot detect anything.
Next#
REST API overview for auth, scopes, and pagination. Monitor types for what each type does. Ping API for the surface that produces these pings.