REST API
Manage the same resources you manage in the app — uptime and cron monitors, groups, notification channels, integrations, status pages, and incidents — over a JSON HTTP API.
Every endpoint lives under the /api/v1 prefix and is authenticated by an organization-scoped API key. The
MCP server
uses the same keys and runs the same operations, so anything you can do here you can also do from an AI assistant.
Authentication
An organization owner creates an API key under Administration → API keys. The full token (it starts with wc_) is shown once, at creation time — store it securely, it cannot be displayed again. Send it as a bearer token on every request:
curl https://watchcat.io/api/v1/service_monitors \ -H "Authorization: Bearer wc_your_token_here"
A missing, unknown, or revoked token returns 401. Keys only ever see their own organization's data; a resource that belongs to another organization responds as if it does not exist.
Scopes
Each key has one of two scopes, chosen when it is created.
GET requests are allowed; any write returns 403.
Conventions
Requests and responses are JSON — send Content-Type: application/json on any request with a body. A successful response wraps its payload in a data key (an array for lists); errors wrap a message in an error key, with a fields map on validation errors.
{ "data": { "id": 1, "name": "Marketing site", "status": "up" } } { "error": { "message": "Url can't be blank", "fields": { "url": ["can't be blank"] } } }
Other conventions:
- Status codes:
200read/update/action,201create,204delete,4xxfor auth, scope, plan, validation, and not-found errors. - On
PATCH, only the fields you send are changed. - Timestamps are ISO 8601 in UTC. Secrets are never returned.
- Plan limits are enforced exactly as in the app — exceeding one returns
403. - The API is not paginated; list endpoints return the full set.
Example — create a monitor
curl -X POST https://watchcat.io/api/v1/service_monitors \ -H "Authorization: Bearer wc_your_token_here" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com", "interval_seconds": 300, "group_name": "Public sites" }'
Endpoints
All paths are relative to /api/v1.
Uptime monitors
| GET | /api/v1/service_monitors | List monitors |
| POST | /api/v1/service_monitors | Create a monitor |
| GET | /api/v1/service_monitors/:id | Show a monitor |
| PATCH | /api/v1/service_monitors/:id | Update a monitor |
| DELETE | /api/v1/service_monitors/:id | Delete a monitor |
| POST | /api/v1/service_monitors/:id/pause | Pause |
| POST | /api/v1/service_monitors/:id/resume | Resume |
Writable fields: name, url, interval_seconds, http_method, request_body, timeout_seconds, check_ssl, follow_redirects, expected_status_codes, body_must_contain, body_must_not_contain, confirmation_period_seconds, recovery_period_seconds, headers, request_cookies.
name defaults to the URL when omitted. headers is a JSON object, and request_cookies is a JSON object of cookie names and values sent as a Cookie header. http_method accepts GET, HEAD, POST, PUT and PATCH; request_body is sent with the three that carry a body and is assumed to be JSON unless a Content-Type header says otherwise. Optional group_name assigns a group by name (created if it does not exist); notification_channel_ids sets the channels — omit it on create to use the organization's auto-assign channels.
Cron monitors
| GET | /api/v1/cron_monitors | List monitors |
| POST | /api/v1/cron_monitors | Create a monitor |
| GET | /api/v1/cron_monitors/:id | Show a monitor |
| PATCH | /api/v1/cron_monitors/:id | Update a monitor |
| DELETE | /api/v1/cron_monitors/:id | Delete a monitor |
| POST | /api/v1/cron_monitors/:id/pause | Pause |
| POST | /api/v1/cron_monitors/:id/resume | Resume |
| POST | /api/v1/cron_monitors/:id/regenerate_token | Issue a new ping token |
Writable fields: name, interval_seconds, grace_seconds, max_runtime_seconds, check_type, allow_overlapping_runs.
interval_seconds has a minimum of 60 (plan minimums apply). check_type is heartbeat or start_end. The same group_name and notification_channel_ids options apply; responses include the ping_token and its ping_path.
Monitor groups
| GET | /api/v1/groups | List groups |
| POST | /api/v1/groups | Create a group |
| PATCH | /api/v1/groups/:id | Rename a group |
| DELETE | /api/v1/groups/:id | Delete a group |
Writable fields: kind, name.
Service and cron groups share these endpoints and are told apart by kind (service or cron). kind is required on writes (as a query or body parameter) because the two id ranges are independent; on the list it is optional. Deleting a group leaves its monitors ungrouped.
Notification channels
| GET | /api/v1/notification_channels | List channels |
| POST | /api/v1/notification_channels | Create a channel |
| GET | /api/v1/notification_channels/:id | Show a channel |
| PATCH | /api/v1/notification_channels/:id | Update a channel |
| DELETE | /api/v1/notification_channels/:id | Delete a channel |
| POST | /api/v1/notification_channels/:id/pause | Pause |
| POST | /api/v1/notification_channels/:id/resume | Resume |
Writable fields: name, email_all_users, send_recovery_alert, auto_assign_to_new_monitors.
Recipients are set with user_ids (organization user ids) and integration_ids. When email_all_users is true, specific users are cleared.
Integrations
| GET | /api/v1/integrations | List integrations |
| POST | /api/v1/integrations | Create an integration |
| GET | /api/v1/integrations/:id | Show an integration |
| PATCH | /api/v1/integrations/:id | Update an integration |
| DELETE | /api/v1/integrations/:id | Delete an integration |
Writable fields: name, provider, webhook_url, bot_token, chat_id, integration_key, headers, enabled.
provider is one of slack, google_chat, discord, telegram, webhook, ilert and is fixed once set. Webhook-style providers take webhook_url; telegram takes bot_token and chat_id; ilert takes integration_key. The webhook provider also takes headers, a JSON object of request headers sent with every alert. Responses list configured setting names under configured_settings and never include the secret values.
Status pages
| GET | /api/v1/status_pages | List status pages |
| POST | /api/v1/status_pages | Create a status page |
| GET | /api/v1/status_pages/:id | Show a status page |
| PATCH | /api/v1/status_pages/:id | Update a status page |
| DELETE | /api/v1/status_pages/:id | Delete a status page |
Writable fields: name, slug, headline, description, logo, remove_logo, logo_url, favicon, remove_favicon, brand_link_url, theme, accent_color, background_color, font, hide_branding, uptime_days, show_uptime_percentage, show_response_times, access, password, regenerate_access_token, sections.
name and headline are required on create; the public slug is derived from the name. sections sets the layout — an ordered list of sections, each with an optional title, collapsible and collapsed, and monitors given as uptime monitor ids or { id, type, display_name } with type uptime or cron — and replaces the existing layout. service_monitor_ids is shorthand for a single untitled section. Branding fields: theme (light or dark), accent_color, background_color, font (sans, serif or mono), uptime_days (7–90), show_uptime_percentage, show_response_times, and logo and favicon as a base64 data URI or multipart file. hide_branding removes the "Powered by" footer (Pro and Team). access is public, unlisted or password (the last two on Pro and Team); a password page needs password, which is never returned, and regenerate_access_token gives an unlisted page a new key. Responses add access, share_path (with the key for unlisted pages) and subscribers_count. Each page also serves a public status JSON at /status/:slug.json, a badge at /status/:slug/badge and a widget at /status/:slug/embed; see Customize your status page.
Status page incidents
| GET | /api/v1/status_pages/:status_page_id/incidents | List incidents |
| GET | /api/v1/status_pages/:status_page_id/incidents/:id | Show an incident |
| POST | /api/v1/status_pages/:status_page_id/incidents | Report an incident |
| PATCH | /api/v1/status_pages/:status_page_id/incidents/:id | Edit an incident |
| DELETE | /api/v1/status_pages/:status_page_id/incidents/:id | Delete an incident |
| POST | /api/v1/status_pages/:status_page_id/incidents/:incident_id/updates | Post a timeline update |
| PATCH | /api/v1/status_pages/:status_page_id/incidents/:incident_id/updates/:id | Correct an update |
| DELETE | /api/v1/status_pages/:status_page_id/incidents/:incident_id/updates/:id | Delete an update |
Writable fields: title, description, status, started_at, visible, monitors.
Incidents you post on a status page, distinct from automatic monitor incidents. Each has a timeline of updates; the incident's status (investigating, identified, monitoring or resolved) follows the latest one. monitors lists the affected monitors. On create, status and description become the first update; on update they post a new one.
Incidents
| GET | /api/v1/incidents | List incidents, newest first |
| GET | /api/v1/incidents/:id | Show an incident |
| POST | /api/v1/incidents/:id/resolve | Resolve an open incident |
Automatic downtime and cron alerts. Filter the list with status (open or resolved) and monitor_type (ServiceMonitor or CronMonitor). Incidents normally resolve themselves when the monitor recovers; resolve closes one by hand.
Maintenance windows
| GET | /api/v1/maintenance_windows | List maintenance windows |
| GET | /api/v1/maintenance_windows/:id | Show a maintenance window |
| POST | /api/v1/maintenance_windows | Schedule maintenance |
| PATCH | /api/v1/maintenance_windows/:id | Update a maintenance window |
| DELETE | /api/v1/maintenance_windows/:id | Delete a maintenance window |
| POST | /api/v1/maintenance_windows/:maintenance_window_id/updates | Post a timeline update |
| PATCH | /api/v1/maintenance_windows/:maintenance_window_id/updates/:id | Correct an update |
| DELETE | /api/v1/maintenance_windows/:maintenance_window_id/updates/:id | Delete an update |
Writable fields: title, description, starts_at, ends_at, show_on_status_pages, monitors, status.
Planned work on monitors. During a window, incidents that start on the affected monitors send no alerts and don't count as downtime on status pages. With show_on_status_pages the window is announced on every status page that shows one of those monitors. phase (scheduled, in_progress, completed) follows the clock; a completed update ends the window early.
Usage
| GET | /api/v1/usage | Plan, limits, and current usage |
A read-only summary of the organization's plan, its limits, and how many monitors and status pages are in use.
What the API does not cover
- It manages resources and reports incidents and usage. It does not expose individual uptime check results or response-time history.
- It mirrors the app's capabilities and adds nothing beyond them — for example, there is no request-body monitoring.
- There is no pagination yet.
Related
Start monitoring in minutes
Free plan available. No credit card required.