Public API
Use organization-owned API keys to manage monitors, incidents, status pages, maintenance windows and webhook subscriptions from your own systems.
Quick start
Create a key
Open Dashboard → API & webhooks. Give the key a clear name, choose read-only or full access, and set an expiry.
Copy it once
The key starts with
moon_and is shown only once. Store it in a secrets manager, never in browser code or source control.Make a request
curl https://www.moonitor.dev/api/v1/monitors \ -H "X-API-Key: moon_YOUR_KEY"
Note
Authorization: Bearer moon_YOUR_KEY is also accepted. Use one authentication header, not both.
Interactive reference
The complete OpenAPI 3.1 contract, request builder, schemas, examples and responses live in the Scalar API reference. The raw document is available at /openapi.json.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/monitors | List monitors |
POST | /api/v1/monitors | Create a monitor |
GET | /api/v1/monitors/{monitorId} | Get a monitor |
PATCH | /api/v1/monitors/{monitorId} | Update a monitor |
DELETE | /api/v1/monitors/{monitorId} | Delete a monitor |
POST | /api/v1/monitors/{monitorId}/pause | Pause a monitor |
POST | /api/v1/monitors/{monitorId}/resume | Resume a monitor |
POST | /api/v1/monitors/{monitorId}/check | Run a monitor now |
GET | /api/v1/incidents | List incidents |
GET | /api/v1/incidents/{incidentId} | Get an incident |
POST | /api/v1/incidents/{incidentId}/acknowledge | Acknowledge an incident |
GET | /api/v1/status-pages | List status pages |
POST | /api/v1/status-pages | Create a status page |
GET | /api/v1/status-pages/{statusPageId} | Get a status page |
PATCH | /api/v1/status-pages/{statusPageId} | Update a status page |
DELETE | /api/v1/status-pages/{statusPageId} | Delete a status page |
GET | /api/v1/maintenance-windows | List maintenance windows |
POST | /api/v1/maintenance-windows | Create a maintenance window |
GET | /api/v1/maintenance-windows/{maintenanceId} | Get a maintenance window |
PATCH | /api/v1/maintenance-windows/{maintenanceId} | Update a maintenance window |
DELETE | /api/v1/maintenance-windows/{maintenanceId} | Delete a maintenance window |
GET | /api/v1/webhook-endpoints | List webhook endpoints |
POST | /api/v1/webhook-endpoints | Create a webhook endpoint |
GET | /api/v1/webhook-endpoints/{endpointId} | Get a webhook endpoint |
PATCH | /api/v1/webhook-endpoints/{endpointId} | Update a webhook endpoint |
DELETE | /api/v1/webhook-endpoints/{endpointId} | Delete a webhook endpoint |
POST | /api/v1/webhook-endpoints/{endpointId}/rotate-secret | Rotate a signing secret |
POST | /api/v1/webhook-endpoints/{endpointId}/test | Send a test event |
GET | /api/v1/webhook-deliveries | List webhook deliveries |
GET | /api/v1/webhook-deliveries/{deliveryId} | Get a delivery and its attempts |
POST | /api/v1/webhook-deliveries/{deliveryId}/retry | Retry a delivery |
Permissions and limits
- Read-only keys can list and fetch every resource, but cannot mutate anything.
- Full-access keys can read and write all documented resources. Revoke or replace a key at any time from the dashboard.
- Keys are scoped to one organization. A key can never select another tenant through a query or request body.
- Each key allows 120 requests per minute. Responses include
X-RateLimit-LimitandX-RateLimit-Remaining.
Pagination
List endpoints accept limit (1–100, default 25) and offset (default 0). Every list response includes the exact values and total count:
{
"data": [],
"pagination": { "limit": 25, "offset": 0, "total": 0 }
}Safe mutation retries
Add an Idempotency-Key header to POST, PATCH and DELETE requests that your client may retry. Moonitor binds the key to the method, path and validated body, then replays the same successful response for 24 hours instead of running the mutation twice.
curl -X POST https://www.moonitor.dev/api/v1/monitors \
-H "X-API-Key: moon_YOUR_KEY" \
-H "Idempotency-Key: deploy-2026-07-15-monitor-1" \
-H "Content-Type: application/json" \
-d '{"name":"Website","type":"HTTP","url":"https://example.com"}'A replay includes Idempotency-Replayed: true. Reusing the key for different input returns 409 idempotency_conflict.
Errors and request tracing
Errors always use one envelope. Keep the requestId when contacting support; it is also returned in the X-Request-ID header.
{
"error": {
"code": "validation_error",
"message": "The request is invalid",
"requestId": "…",
"details": [{ "path": "url", "message": "url is required for HTTP monitors" }]
}
}| Status | Meaning |
|---|---|
| 400 | Invalid JSON, content type, query, path or body |
| 401 | Missing, expired, disabled or invalid key |
| 403 | The key lacks the required permission |
| 404 | The endpoint or tenant-scoped resource does not exist |
| 409 | The request conflicts with current state |
| 422 | A subscription or plan rule prevents the mutation |
| 429 | Per-key rate limit reached |
| 500 | Unexpected server failure |