API Documentation

The MyUpMonitor API lets you programmatically manage monitors, incidents, status pages, and notifications. Available on Business and Enterprise plans.

Base URL

https://myupmonitor.com/api

Rate Limits

PlanLimit
Free30 req/min
Pro100 req/min
Business1,000 req/min
Enterprise1,000 req/min

Rate limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After

Authentication

Create an API key in Dashboard → Settings → API Keys. Include it as a Bearer token:

Authorization: Bearer mum_your_api_key_here
AUTH All API endpoints
curl -H "Authorization: Bearer mum_your_key" \
  https://myupmonitor.com/api/monitors

API Key Scopes

API keys can be scoped to limit access. Keys with no scopes have full access (backwards compatible). Create scoped keys via POST /api/keys with a scopes array.

Available Scopes

ScopeGrants Access To
monitors:readList and view monitors
monitors:writeCreate, update, delete monitors
incidents:readList and view incidents
incidents:writeCreate, update, delete incidents
notifications:readList notification channels
notifications:writeCreate, update, delete channels
account:readView account info
status-pages:readList and view status pages
status-pages:writeCreate, update status pages
reports:readView SLA and weekly reports
POST/api/keysCreate a scoped API key
{
  "name": "CI/CD Read-Only",
  "scopes": ["monitors:read", "incidents:read"]
}

// Response (raw key shown once):
{
  "key": { "id": "uuid", "name": "CI/CD Read-Only", "scopes": ["monitors:read", "incidents:read"] },
  "rawKey": "mum_..."
}

Keys with empty scopes: [] or no scopes field have full access. A scoped key trying to access an endpoint outside its scopes receives 403 Forbidden.

Monitors

GET /api/monitors List all monitors
// Response
[
  {
    "id": "uuid",
    "website": "https://example.com",
    "check_type": "http",
    "interval_seconds": 60,
    "active": true,
    "last_status": 200,
    "uptime_24h": 99.95,
    "avg_response_ms": 245
  }
]
POST /api/monitors Create a monitor
curl -X POST /api/monitors \
  -H "Authorization: Bearer mum_key" \
  -H "Content-Type: application/json" \
  -d '{"website":"https://example.com","check_type":"http","interval_seconds":60}'
GET/api/monitors/:idGet monitor details
PUT/api/monitors/:idUpdate a monitor
DELETE/api/monitors/:idDelete a monitor
GET /api/monitors/:id/status?period=24h Status history
// Response
{
  "uptime_percent": 99.95,
  "avg_response_ms": 245,
  "total_checks": 1440,
  "incidents": 1,
  "history": [
    { "timestamp": "2026-03-25T10:00:00Z", "status": 200, "response_ms": 230, "region": "us-east" }
  ]
}

Periods: 24h, 7d, 30d

Monitor Check Types

When creating a monitor, set check_type to one of the following. Each type accepts different parameters.

TypeDescriptionExtra Fields
httpHTTP(S) status checkhttp_keyword, http_keyword_negate, response_time_threshold_ms
sslSSL certificate expiryAlerts at 30/14/7/1 days before expiry
tcpTCP port connectivitytcp_port (required, 1-65535)
dnsDNS record monitoringdns_record_type (A/AAAA/MX/TXT/CNAME), dns_expected_value
heartbeatDead man's switchReturns heartbeat_token — ping /api/heartbeat/:token to report health
apiMulti-step API checksapi_check_steps (JSON array of steps)
POST/api/monitorsDNS monitor example
{
  "url": "example.com",
  "check_type": "dns",
  "dns_record_type": "A",
  "dns_expected_value": "93.184.216.34",
  "interval_seconds": 600
}
POST/api/monitorsHTTP with keyword assertion
{
  "url": "https://example.com",
  "check_type": "http",
  "http_keyword": "Welcome",
  "http_keyword_negate": false,
  "response_time_threshold_ms": 2000,
  "interval_seconds": 300
}
POST/api/monitorsMulti-step API check
// api_check_steps is a JSON string containing an array of steps:
// Each step: name, method, url, headers, body, assertions, extract
//
// Step fields:
//   assertions: [{type: "status", value: "200"},
//                {type: "body_contains", value: "ok"},
//                {type: "json_path", path: "data.id", value: "123"}]
//   extract: {"token": "data.access_token"} (dot-notation JSON path)
//
// Variables from extract are available in later steps as {{token}}

Steps run sequentially with fail-fast. SSRF protection on all step URLs.

Escalation Policies

Define multi-step alert escalation chains. If nobody acknowledges an alert, it escalates to the next tier of channels.

GET/api/escalation-policiesList escalation policies
POST/api/escalation-policiesCreate escalation policy
{
  "name": "Production Alerts",
  "steps": [
    { "delayMinutes": 0, "channelIds": ["slack-channel-id"] },
    { "delayMinutes": 5, "channelIds": ["pagerduty-channel-id"] },
    { "delayMinutes": 15, "channelIds": ["email-channel-id"] }
  ]
}

Step 1 fires immediately. Subsequent steps fire if no acknowledgment within the delay.

POST/api/alerts/:id/acknowledgeAcknowledge an active escalation

Stops further escalation for this alert. Recovery auto-acknowledges.

DELETE/api/escalation-policies/:idDelete policy (unlinks from monitors)

Incidents

GET/api/incidentsList incidents

Query params: monitor_id, active=true

POST/api/incidentsCreate manual incident
{
  "monitor_id": "uuid",
  "title": "API degradation",
  "status": "investigating"
}
GET/api/incidents/:idGet incident with timeline
POST/api/incidents/:id/updatesAdd status update
{
  "status": "identified",  // investigating | identified | monitoring | resolved
  "message": "Root cause identified — deploying fix"
}
DELETE/api/incidents/:idDelete incident

Status Pages

GET/api/status-pagesList status pages
POST/api/status-pagesCreate status page
{
  "name": "Acme Status",
  "slug": "acme",
  "custom_domain": "status.acme.com"  // optional, Business+ plans
}
POST/api/status-pages/:id/monitorsLink monitors
POST/api/status-pages/:id/domain/verifyVerify custom domain

Notification Channels

GET/api/notificationsList channels
POST/api/notificationsCreate channel
// Slack
{ "name": "Ops Slack", "type": "slack", "config": { "webhook_url": "https://hooks.slack.com/..." } }

// Discord
{ "name": "Alerts", "type": "discord", "config": { "webhook_url": "https://discord.com/api/webhooks/..." } }

// Webhook
{ "name": "Custom", "type": "webhook", "config": { "url": "https://example.com/hook", "secret": "hmac_secret" } }
POST/api/notifications/:id/testSend test notification
PUT/api/monitors/:id/notificationsLink channels to monitor

Heartbeat Pings

Heartbeat monitors work like a dead man's switch. Create a heartbeat monitor to get a unique ping URL. Your cron job or service should hit this URL on a schedule. If we don't receive a ping within the expected interval + grace period, we alert.

POST/api/heartbeat/:tokenSend heartbeat ping (no auth required)
# Add to your crontab:
*/5 * * * * curl -fsS -o /dev/null https://myupmonitor.com/api/heartbeat/your_token_here

# Or from a script:
curl -X POST https://myupmonitor.com/api/heartbeat/your_token_here

Also accepts GET for simplicity. Returns { "ok": true } on success.

POST/api/monitorsCreate heartbeat monitor
{
  "url": "Nightly Backup Job",
  "check_type": "heartbeat",
  "interval_seconds": 86400,
  "heartbeat_grace_minutes": 30
}

// Response includes heartbeat_token:
{
  "monitor": {
    "id": "uuid",
    "heartbeat_token": "a1b2c3..."  // Use this in your ping URL
  }
}

Webhook Verification

When using webhook notification channels with a secret, we sign the payload with HMAC-SHA256. Verify like this:

HMACSignature Verification
const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return `sha256=${expected}` === signature;
}

// In your handler:
const sig = req.headers['x-signature-256'];
if (!verifyWebhook(rawBody, sig, 'your_secret')) {
  return res.status(401).send('Invalid signature');
}

Webhook Payload

{
  "event": "monitor.down",
  "monitor": {
    "id": "uuid",
    "website": "https://example.com",
    "check_type": "http"
  },
  "status": {
    "http_status": 503,
    "response_ms": 5000,
    "error": "timeout",
    "region": "us-east"
  },
  "timestamp": "2026-03-25T10:00:00Z"
}

Events: monitor.down, monitor.up, ssl.expiring

Tags

Organize monitors with free-form tags for multi-dimensional filtering.

GET/api/tagsList all tags for your account
// Response
{ "tags": ["production", "api", "web", "database", "us-east"] }

Tags are set via the tags field on monitor create/update. Comma-separated, lowercase, auto-deduplicated.

Health Score

Composite reliability score (0-100) per monitor based on uptime, response time stability, incidents, and SSL health.

GET/api/monitors/:id/health-scoreGet health score + 30-day trend
// Response
{
  "score": 87,
  "label": "Good",
  "components": {
    "uptime": 38,        // max 40
    "responseTime": 25,  // max 30
    "incidents": 16,     // max 20
    "ssl": 8             // max 10
  },
  "trend": [
    { "date": "2026-03-08", "score": 82 },
    { "date": "2026-03-09", "score": 85 }
  ]
}

Labels: Excellent (90+), Good (75+), Fair (50+), Poor (25+), Critical (<25)

Region Latency

Per-region response time stats from our multi-region check infrastructure.

GET/api/monitors/:id/region-latencyGet per-region latency stats
// Response
{
  "regions": [
    {
      "region": "eu",
      "avg_ms": 245, "min_ms": 120, "max_ms": 890,
      "p95_ms": 520, "check_count": 1440
    },
    {
      "region": "us-east",
      "avg_ms": 180, "min_ms": 95, "max_ms": 650,
      "p95_ms": 380, "check_count": 1440
    }
  ],
  "hourly": [
    { "hour": "2026-04-07T10:00:00Z", "region": "eu", "avg_ms": 240 }
  ]
}

Dependencies

View the monitor dependency graph — parent/child relationships used for alert suppression.

GET/api/monitors/dependency-graphGet full dependency graph
// Response
{
  "nodes": [
    { "id": "uuid", "label": "api.example.com", "checkType": "http", "status": "up", "dependsOn": null },
    { "id": "uuid2", "label": "web.example.com", "checkType": "http", "status": "up", "dependsOn": "uuid" }
  ],
  "edges": [
    { "from": "uuid", "to": "uuid2" }
  ]
}

Bulk Import

Import multiple monitors at once. Max 500 per request.

POST/api/monitors/importBulk import monitors from JSON
// Request
{
  "monitors": [
    { "url": "https://api.example.com", "check_type": "http", "interval_seconds": 60 },
    { "url": "https://web.example.com", "check_type": "ssl", "group_name": "Production" }
  ]
}

// Response
{
  "total": 2, "created": 2, "skipped": 0,
  "results": [
    { "url": "https://api.example.com", "status": "created" },
    { "url": "https://web.example.com", "status": "created" }
  ]
}

Skipped reasons: duplicate, invalid_url, plan_limit. Rate limited: 1 import per 5 minutes.

Alert Deliveries

Track whether alert notifications were successfully delivered to each channel.

GET/api/notifications/:id/deliveriesRecent delivery attempts for a channel
// Response
{
  "deliveries": [
    {
      "id": "uuid",
      "monitorName": "api.example.com",
      "alertType": "down",
      "status": "delivered",
      "attempts": 1,
      "lastError": null,
      "createdAt": "2026-04-07T10:00:00Z"
    },
    {
      "id": "uuid2",
      "monitorName": "db.example.com",
      "alertType": "down",
      "status": "failed",
      "attempts": 3,
      "lastError": "slack returned status 500",
      "createdAt": "2026-04-07T09:30:00Z"
    }
  ]
}

Statuses: pending (retrying), delivered, failed (all retries exhausted). Retry: 3 attempts with 10s/30s/90s exponential backoff.

Event Webhooks

Receive real-time HTTP callbacks when account events occur. HMAC-SHA256 signed.

GET/api/settings/event-webhooksList event webhooks
POST/api/settings/event-webhooksCreate event webhook
// Request
{
  "url": "https://your-server.com/webhooks/mum",
  "events_filter": ["monitor.created", "incident.opened"]  // null = all events
}

// Response — secret auto-generated for HMAC signing
{
  "webhook": {
    "id": "uuid",
    "url": "https://your-server.com/webhooks/mum",
    "secret": "a1b2c3...",
    "active": true,
    "eventsFilter": ["monitor.created", "incident.opened"]
  }
}
PUT/api/settings/event-webhooks/:idUpdate webhook
DELETE/api/settings/event-webhooks/:idDelete webhook
POST/api/settings/event-webhooks/:idSend test ping

Event Types

EventWhen
monitor.createdNew monitor added
monitor.updatedMonitor settings changed
monitor.deletedMonitor removed
incident.openedNew incident created
incident.updatedIncident status changed
incident.closedIncident resolved
team.member_joinedTeam member added
team.member_removedTeam member removed
status_page.updatedStatus page modified
maintenance.startedMaintenance window begins
maintenance.endedMaintenance window ends
test.pingManual test via API

Payload Format

// POST to your URL with X-Signature-256 header
{
  "event": "monitor.created",
  "timestamp": "2026-04-07T12:00:00Z",
  "account_id": "uuid",
  "data": {
    "resource_type": "monitor",
    "resource_id": "uuid",
    "action": "created",
    "details": { "website": "https://example.com" }
  }
}

Verify: X-Signature-256: sha256=HMAC(secret, body). Retries: 3 attempts with 10s/30s/90s backoff on 5xx.

Account & Data

GET/api/account/exportExport all account data (GDPR)
// Downloads JSON archive with:
// monitors, incidents, notification channels (secrets redacted),
// status pages, teams, API keys, daily stats,
// check history (30 days), audit log
// Rate limited: 1 per 10 minutes
GET/api/account/api-usage?days=30API key usage analytics
// Response
{
  "requestsByKey": [
    { "keyId": "uuid", "keyName": "CI/CD", "totalRequests": 1234, "rateLimitHits": 2 }
  ],
  "requestsOverTime": [
    { "date": "2026-04-06", "requests": 450, "rateLimitHits": 0 }
  ],
  "topEndpoints": [
    { "endpoint": "/api/monitors", "method": "GET", "count": 800 }
  ]
}

Query param days: 7, 30, or 90. Default 30.

Deploy Markers

Annotate monitors with deploy events, incidents, or custom markers for correlation.

POST/api/annotationsCreate annotation
{ "label": "deployed v2.3", "monitor_ids": ["uuid1", "uuid2"], "source": "api" }
// monitor_ids: null = all monitors. source: "manual", "api", "cli"
GET/api/monitors/:id/annotations?from=&to=Get annotations for a monitor
DELETE/api/annotationsDelete annotation by ID

Certificates

SSL certificate inventory across all HTTP/SSL monitors.

GET/api/certificatesList all SSL certificates
// Response — sorted by days remaining (most urgent first)
{ "certificates": [
  { "domain": "api.example.com", "issuer": "Let's Encrypt", "validUntil": "2026-07-15",
    "daysRemaining": 45, "status": "ok" }
] }

Statuses: ok (>30d), warning (7-30d), critical (<7d), expired

Broken Links Crawler

Crawl sites for 404s, dead external links, and mixed content. Monitor type: crawler.

GET/api/monitors/:id/crawl-resultsLatest crawl results
{ "runs": [{ "id": "uuid", "pagesCrawled": 87, "issuesFound": 3, "status": "completed" }],
  "issues": [
    { "sourceUrl": "https://example.com/about", "targetUrl": "https://example.com/old-page",
      "statusCode": 404, "issueType": "broken" }
  ] }

Issue types: broken (4xx/5xx), mixed_content (HTTP on HTTPS). Crawl depth: 3 levels, max 100 pages.

Domain Expiry

WHOIS-based domain registration expiry tracking. Alerts at 30/14/7/1 days.

Automatic Detection

Domain expiry is checked daily for all HTTP/SSL monitors automatically. No separate configuration needed. Results appear on the Certificates dashboard alongside SSL cert data.

Data includes: registrar, registration date, expiry date, days remaining.

SLA Error Budget

Track remaining error budget against SLA targets. Set sla_target_pct on a monitor.

GET/api/monitors/:id/error-budgetGet current error budget
{
  "slaTarget": 99.9, "period": "monthly",
  "allowedDowntimeMinutes": 43.2, "usedDowntimeMinutes": 30.1,
  "remainingMinutes": 13.1, "consumptionPercent": 69.7,
  "status": "healthy"
}

Statuses: healthy (<70%), warning (70-90%), critical (90-100%), breached (>100%)

On-Call Schedules

Manage on-call rotations for escalation routing.

GET/api/settings/on-call?current=trueGet who's currently on call
{ "schedules": [
  { "id": "uuid", "name": "Primary", "currentOnCall": "alice@co.com",
    "overrideActive": false }
] }
POST/api/settings/on-callCreate schedule, rotation, or override

Changelog

Access the public changelog feed programmatically.

GET/api/changelog/entriesLatest changelog entries (public, cached 5min)
// Response
{
  "entries": [
    {
      "id": "uuid",
      "title": "Percentile alerting (p95/p99)",
      "description": "Catch tail latency that averages hide.",
      "category": "feature",
      "publishedAt": "2026-04-07T12:00:00Z"
    }
  ]
}

Categories: feature, improvement, fix. RSS feed at /changelog/rss.