API Reference
Everything in Zharp is an HTTP API: monitors, incidents, status pages, alerting, on-call, logs, traces and your team. This page covers what every request shares; each area has its own page with every endpoint.
Create and manage monitors, read checks and uptime, cron heartbeats, push monitors, groups.
crisis_alertReport, acknowledge, resolve and comment on incidents; page people; schedule maintenance.
stacked_line_chartPages, status reports, subscribers — and public pages as JSON.
notifications_activeAlert connections, escalation policies, severities, on-call schedules, team groups.
descriptionSend and search logs, log sources and drains, agents.
groupPlan usage, members and invitations, API keys.
Quick start
- 1Create a key
In the dashboard, open Integrations & API → Main API keys → Create API key. Pick its scopes and expiry, optionally the addresses it may be used from, and copy it — it's shown once. Keys are on every plan.
- 2Call the API
Every path is relative to
https://api.zharp.io/api/v1, and the key goes in anAuthorizationheader:export ZHARP_API_KEY=zh_live_… curl "https://api.zharp.io/api/v1/monitors?status=DOWN" \ -H "Authorization: Bearer $ZHARP_API_KEY"
Authentication
Send the key as a bearer token: Authorization: Bearer zh_live_…. The ingestion endpoints that agents and SDKs post data to take it as X-API-KEY instead (see Logs).
- A key belongs to one workspace and only ever acts on it — no
X-Workspace-Idneeded, and one sent is ignored. Another workspace's ids answer404; another workspace's/workspaces/:idanswers403. - A key acts as the person who created it. Their role in the workspace limits what it can do (see Roles), and the key's scope narrows that further. If they leave, their keys stop working.
- Some routes are for people, not keys: signing in, profiles, the list of your workspaces, accepting invitations, personal notification settings, billing, and deleting a workspace. Keys get
401there. - On a key's page you can limit it to Allowed IPs, change its expiry, Roll key or Revoke it, and see its last day of requests — or do it all through the API.
Scopes
A key holds one or more scopes. The strongest counts: admin includes write, and write includes read.
| Scope | Allows |
|---|---|
| Read | Every GET — except alert connections and API keys, which hold secrets. |
| Write | Read, plus running incidents — report, acknowledge, resolve, reopen, comment, escalate — and posting status reports and their updates. |
| Admin | Everything: creating and changing monitors, status pages, maintenance, escalation, on-call, log sources and team; every request to alert connections and API keys. |
| Ingest only | Sending data and nothing else: the agent, the SDKs, log ingestion. Every other request gets 403. It can't be combined with another scope — the safe key to put in a server's config or an app. |
Each endpoint shows the scope it needs.
Roles and permissions
Each endpoint also shows the permission it needs from the key's owner, when it needs one. Which role holds which:
| Permission | Owner | Manager | Member | Read-only |
|---|---|---|---|---|
monitors:view | ✓ | ✓ | ✓ | ✓ |
monitors:create, :edit, :delete | ✓ | ✓ | ✓ | — |
resources:manage | ✓ | ✓ | ✓ | — |
logs:view, team:view, workspace:view | ✓ | ✓ | ✓ | ✓ |
escalation:view, on-call:view | ✓ | ✓ | ✓ | ✓ |
escalation:manage, on-call:manage, team:manage_members, team:invite | ✓ | ✓ | — | — |
api-keys:view, api-keys:manage | ✓ | ✓ | ✓ | — |
team:manage_roles | ✓ | — | — | — |
resources:manage covers incidents, maintenance, status pages, alert connections and monitor groups. A permission the key's owner lacks answers 403, whatever the key's scope.
Requests and responses
- Send JSON with
Content-Type: application/json; uploads aremultipart/form-data. Bodies can be up to 10 MB. - Times are ISO 8601 in UTC,
2026-10-26T09:14:32.041Z; send them the same way. A few chart fields are epoch seconds and say so. - Uptime is always a percentage from 0 to 100, such as
99.95;-1in a chart means no checks in that hour or day. :idin a path is a number.PUTchanges only the fields you send, except where a page says it replaces the whole thing.- Credentials stored in Zharp — monitor passwords, auth headers, connection secrets — come back as
••••••••. Send that value back unchanged and the stored one is kept.
A success wraps the result in data:
{
"message": "Monitors retrieved successfully",
"data": [ … ]
}Lists that page add meta; send page and limit to move through them. Others take limit and offset, as each page says.
{
"message": "Incidents retrieved successfully",
"data": [ … ],
"meta": { "total": 60, "page": 1, "limit": 50, "totalPages": 2 }
}Errors
An error has a message for people and an errorCode for code:
{
"message": "This API key lacks the \"admin\" scope required for POST /monitors",
"errorCode": "accessDenied"
}| Status | errorCode | Why |
|---|---|---|
| 400 | validationError | A field or parameter is missing or wrong. The message names it. |
| 401 | authenticationError | No key, or one that's invalid, disabled, expired or revoked — or a route that's for people, not keys. |
| 403 | accessDenied | The key's scope is too low, its allowed addresses don't include you, or it's another workspace's. |
| 403 | authenticationError | The key's owner lacks the permission the endpoint needs. |
| 403 | limitExceeded | The plan's limit: monitors, status pages, the fastest check interval… |
| 404 | resourceNotFound | No such thing in this workspace. |
| 409 | validationError | Taken — a slug, a domain, a name — or in conflict with something. |
| 413 | — | The request is too large. |
| 429 | rateLimitExceeded | Over the key's rate limit — wait for the next minute. |
| 429 | limitExceeded | The workspace has sent its log allowance for the month. |
| 500 | serverError | Something failed on our side; it's safe to retry. |
Rate limits
Each key can make 1,000 requests per minute, counted in calendar minutes (UTC) across all our servers. Past that, requests get 429 until the minute turns. Sending data — logs, traces, heartbeats, pushes — doesn't count against it; logs have the monthly allowance instead.
Endpoints that need no key
| Endpoint | Authenticated by |
|---|---|
GET|POST /ping/:token | The cron monitor's token — see Heartbeats |
POST /push/:token | The push monitor's token |
GET /status-pages/public/:slug | Nothing — a public page as JSON. More |
POST /ingest/:provider/:token | The log source's token |
POST /public/incidents/report/:token | The workspace's report link |
Examples
# Is anything down?
curl "https://api.zharp.io/api/v1/monitors?status=DOWN" -H "Authorization: Bearer $ZHARP_API_KEY"
# Acknowledge an incident, then resolve it (write key)
curl -X POST "https://api.zharp.io/api/v1/incidents/481/acknowledge" -H "Authorization: Bearer $ZHARP_API_KEY"
curl -X POST "https://api.zharp.io/api/v1/incidents/481/resolve" -H "Authorization: Bearer $ZHARP_API_KEY"
# Tell visitors on your status page (write key)
curl -X POST "https://api.zharp.io/api/v1/status-pages/12/announcements" \
-H "Authorization: Bearer $ZHARP_API_KEY" -H "Content-Type: application/json" \
-d '{ "title": "API latency", "content": "We are investigating.", "status": "INVESTIGATING", "affectedMonitorIds": [57] }'
# Create a monitor (admin key)
curl -X POST "https://api.zharp.io/api/v1/monitors" \
-H "Authorization: Bearer $ZHARP_API_KEY" -H "Content-Type: application/json" \
-d '{ "type": "HTTP", "name": "Homepage", "url": "https://acme.io", "interval": 300 }'Rather not poll?
A webhook pushes every monitor and incident event to you as it happens. For logs and traces, the SDKs handle batching and retries. And the MCP server lets an AI assistant read your monitors and incidents.