Browse docs

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.

https://watchcat.io/api/v1

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.

read Read-only. Only GET requests are allowed; any write returns 403.
read_write Full read and write access.

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: 200 read/update/action, 201 create, 204 delete, 4xx for 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.