REST API monitors

Create, query, and control monitors from code, with the full field reference for every type.

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

http
GET /v1/monitors?project_id=<project-id>
GET /v1/monitors?project_id=<project-id>
json
{
  "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#

http
GET /v1/monitors/<monitor-id>
GET /v1/monitors/<monitor-id>

Returns { "monitor": { … } } with the shape above.

Create a monitor#

http
POST /v1/monitors
POST /v1/monitors

Needs the MEMBER role or higher.

FieldRequiredDefaultNotes
project_idyesProject to create it in
nameyes1 to 100 characters
typeyesJOB_CRON, JOB_HEARTBEAT, JOB_BASIC, or UPTIME_HTTP
scheduleyesCron expression for JOB_CRON. Interval string for JOB_HEARTBEAT and UPTIME_HTTP. Required but not evaluated for JOB_BASIC
timezonenoUTCAny IANA zone. Applies to cron schedules
slugnoLowercase letters, digits, and hyphens. Up to 50 characters. Used by the slug ping URL
descriptionnoUp to 500 characters
tagsno[]Up to 10 tags, 50 characters each
grace_period_secondsno300Wait past next_expected_at before opening a MISSED incident
schedule_toleranceno1Consecutive misses before flipping DOWN. Minimum 1
failure_toleranceno1Consecutive failures before flipping DOWN. Minimum 1
min_duration_secondsnoFloor for DURATION_LOW. Must be less than max_duration_seconds
max_duration_secondsnoCeiling for DURATION_HIGH and hung-run detection
alert_enablednotrueSet false to record incidents without paging
alert_surge_thresholdno10Consecutive alerts before paging pauses for an hour
retention_countno200Pings to keep. Between 10 and 1000
notification_group_idsno[]Groups to page
notification_channel_idsno[]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.

FieldRequiredDefaultNotes
uptime_urlyesHTTP or HTTPS. Credentials in the URL are rejected, use headers
uptime_methodnoGETGET, HEAD, or POST
uptime_expected_statusnoany 2xxArray of status codes between 100 and 599
uptime_keywordnoBody must contain this string. Up to 1024 characters
uptime_keyword_absentnofalseInvert the keyword check
uptime_headersnoJSON object. Hop-by-hop header names are rejected
uptime_request_bodynoUp to 10 000 characters
uptime_timeout_msno10000Between 1000 and 30 000
uptime_follow_redirectsnotrue
uptime_verify_sslnotrueSet 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#

ParameterDefaultNotes
page1
limit20Max 100
eventSTART, SUCCESS, FAILURE, or LOG
run_idOne execution
exit_codeFilter by numeric code
duration_assertionPASS, TOO_FAST, or TOO_SLOW
from_dateISO datetime
to_dateISO 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.