Manage your monitors, groups, alert contacts, and incidents programmatically over a simple REST API — or connect an AI agent (Claude Desktop, Cursor, …) to the UptimeDesk MCP server and set everything up conversationally. Both use the same API keys and respect the same plan limits as the dashboard.
Every request is authenticated with an API key. Create one in Settings → API & MCP. The full key (it starts with udk_) is shown once at creation — copy it then; only a hash is stored, so it can’t be shown again. Treat a key like a password: it acts as your account.
Send it as a Bearer token in the Authorization header:
Authorization: Bearer udk_your_key_hereScopes. Each key is either Read & write or Read-only. A read-only key can call any GET endpoint but is rejected with 403 on any create/update/delete. Revoke a key any time from Settings — it stops working immediately.
Keeping keys secure
All REST endpoints live under the /api/v1 prefix:
https://uptimedesk.io/api/v1Requests with a body must send Content-Type: application/json. Every response is JSON. Success responses wrap the payload in a data field; errors return an error message and a stable code:
// success
{ "data": { "id": "clx...", "name": "My site", ... } }
// error
{ "error": "This API key is read-only. Use a read-write key to make changes.",
"code": "FORBIDDEN" }Requests are limited per API key. Exceeding the limit returns 429 with a Retry-After header (seconds).
/api/v1): 120 requests / minute per key./api/mcp): 240 requests / minute per key.Every failure carries an HTTP status and a machine-readable code:
| HTTP | code | Meaning |
|---|---|---|
400 | VALIDATION | The request body failed validation (missing/invalid field). The message names the problem. |
401 | UNAUTHORIZED | Missing, malformed, invalid, or revoked API key. |
403 | FORBIDDEN | The key is read-only but the operation writes, or API access is not enabled for the account. |
403 | PLAN | The action requires a higher plan (e.g. creating a group, or a Slack contact, needs Pro). |
403 | LIMIT | A plan resource cap was reached (e.g. the monitor limit). Upgrade to add more. |
404 | NOT_FOUND | The referenced resource does not exist in your workspace. |
429 | RATE_LIMITED | Too many requests — retry after the Retry-After header. |
500 | INTERNAL | Unexpected server error. Safe to retry. |
/api/v1/monitorsList all monitors in your workspace.
/api/v1/monitorsCreate a monitor. Requires a read-write key.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | 1–100 characters. |
url | string | Yes | Public http/https URL to check. https:// is assumed if the scheme is omitted. |
type | "HTTP" | "PING" | "PORT" | No | Check type. Default "HTTP". |
method | string | No | HTTP method: GET, HEAD, POST, PUT, PATCH, DELETE. Default GET. |
expectedStatus | number | No | Expected HTTP status 100–599. Default 200. |
keyword | string | No | Optional. Text that must appear in the response body (≤500 chars). |
requestHeaders | object | No | Optional. Map of header name → value sent with the check. |
requestBody | string | No | Optional request body (≤10000 chars). |
checkSsl | boolean | No | Check SSL certificate validity/expiry. Default true. |
clientId | string | No | Optional group id to attach the monitor to (must be yours). |
The check interval is set by your plan (Free: 5 min, paid: 1 min) and can’t be passed in. New alert contacts are attached automatically (the group’s defaults, or all account contacts). Creating beyond your plan’s monitor cap returns 403 LIMIT.
/api/v1/monitors/:idFetch a single monitor, including its group and incident count.
/api/v1/monitors/:idUpdate a monitor. Any subset of the fields below (read-write key).
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No | 1–100 characters. |
paused | boolean | No | Pause (true) or resume (false) checks. |
keyword | string | null | No | Response keyword, or null to clear. |
method | string | No | HTTP method. |
expectedStatus | number | No | Expected HTTP status 100–599. |
requestHeaders | object | null | No | Request headers, or null to clear. |
requestBody | string | null | No | Request body, or null to clear. |
checkSsl | boolean | No | Toggle SSL checking. |
clientId | string | null | No | Move to a group, or null to detach. |
/api/v1/monitors/:idPermanently delete a monitor and its history. Read-write key.
Example
curl -X POST https://uptimedesk.io/api/v1/monitors \
-H "Authorization: Bearer udk_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "name": "Marketing site", "url": "https://example.com", "keyword": "Welcome" }'Groups (called “clients” internally) organize monitors and power status pages. Creating a group requires the Pro plan.
/api/v1/groupsList groups with monitor counts and status.
/api/v1/groupsCreate a group (Pro, read-write key).
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | 1–100 characters. |
email | string | No | Optional contact email. |
website | string | No | Optional website URL. |
statusPageSlug | string | No | Optional public status-page slug (lowercase letters, numbers, hyphens). |
statusPageTitle | string | No | Optional status-page title. |
statusPagePublic | boolean | No | Whether the status page is public. Default true. |
statusPagePassword | string | No | Optional password to protect the status page (≥4 chars). |
alertContactIds | string[] | No | Default alert contacts for monitors in this group (must be yours). |
/api/v1/groups/:idDelete a group (read-write key). Monitors in the group are kept but detached from it.
/api/v1/alert-contactsList alert contacts (email/Slack destinations for down & up alerts).
/api/v1/alert-contactsCreate an alert contact (read-write key).
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | 1–100 characters. |
type | "EMAIL" | "SLACK" | Yes | Contact type. SLACK requires the Pro plan. |
value | string | Yes | Email address (EMAIL) or a https://hooks.slack.com/… webhook URL (SLACK). |
/api/v1/alert-contacts/:idDelete an alert contact (read-write key). It is removed from any monitors and groups it was attached to. The account owner’s own email contact can’t be deleted (returns 403 FORBIDDEN) — it keeps the owner on every alert.
Incidents are read-only over the API.
/api/v1/incidentsList recent incidents across your monitors.
| Parameter | Type | Required | Description |
|---|---|---|---|
status | "open" | "resolved" | No | Query param. Filter by state. |
monitorId | string | No | Query param. Only incidents for this monitor. |
limit | number | No | Query param. Max results 1–200. Default 50. |
/api/v1/incidents/:idFetch one incident, including AI triage details when available.
/api/v1/accountReturn your plan, limits, and current usage — handy before bulk-creating monitors.
{
"data": {
"plan": "PRO",
"scope": "READ_WRITE",
"limits": { "maxMonitors": 25, "checkIntervalMinutes": 1, "maxClients": 10,
"statusPages": true, "slackAlerts": true },
"usage": { "monitors": 8, "groups": 2, "alertContacts": 3 }
}
}The MCP server exposes the same operations as tools that any MCP-capable AI agent can call, so you can say “add a monitor for example.com and alert #ops” and the agent does it. UptimeDesk doesn’t run any AI itself here — your agent supplies the model; we just expose and execute the tools.
Endpoint (JSON-RPC 2.0 over HTTP POST, authenticated with the same API key):
https://uptimedesk.io/api/mcpAdd it to your agent’s MCP config, replacing the key with one of yours:
{
"mcpServers": {
"uptimedesk": {
"url": "https://uptimedesk.io/api/mcp",
"headers": { "Authorization": "Bearer udk_your_key_here" }
}
}
}Available tools
list_monitors, create_monitor, update_monitor, pause_monitor, delete_monitorlist_groups, create_group, delete_grouplist_alert_contacts, create_alert_contact, delete_alert_contactlist_incidents, get_account_usageWrite tools require a read-write key. When a tool can’t run (plan limit reached, read-only key, validation), the agent receives the reason as a tool error so it can tell you what happened.
Good to know
requestHeaders values and requestBody are redacted in API and MCP responses — a connected agent never sees secrets you stored in a monitor’s custom headers. (They’re still used when the check runs.)