API
API Reference
A clean, predictable REST API. Query servers, pull incidents, manage alert rules, and wire Pulsewise into anything you already run.
https://api.pulsewise.io/v1
Overview
The Pulsewise API is JSON over HTTPS. No SDK required, no GraphQL, no surprises — just predictable REST that maps cleanly to what you see in the dashboard.
Conventions
Every endpoint sits under /v1. Timestamps come back as ISO 8601 in UTC. List endpoints paginate with page and per_page (default 25, max 100).
Content type
Send Content-Type: application/json on any request with a body. Responses are always JSON.
Authentication
Every request needs a Bearer token in the Authorization header. Keys are scoped per workspace — generate them in Settings → API Keys.
GET /v1/servers HTTP/1.1
Host: api.pulsewise.io
Authorization: Bearer sk_live_your_api_key_here
Content-Type: application/json
Two key types
Pick the right one for the job:
- Live keys (
sk_live_) — touch real production data. Treat like a password. - Test keys (
sk_test_) — return sandbox data. Safe for CI and local dev.
Never put live keys in client-side code, public repos, or browser requests. Server-side only.
Servers
GET /v1/servers
List every monitored server in the workspace with its current health.
| Parameter | Type | Required | Description |
|---|---|---|---|
| status | string | Optional | Filter by status: healthy, warning, critical, offline |
| group | string | Optional | Filter by server group name |
| page | integer | Optional | Page number (default: 1) |
| per_page | integer | Optional | Results per page (default: 25, max: 100) |
// Response 200 OK
{
"data": [
{
"id": "srv_8f3k2m1n",
"hostname": "prod-api-01",
"ip_address": "167.71.42.18",
"status": "healthy",
"os": "Ubuntu 22.04 LTS",
"uptime_seconds": 2847291,
"agent_version": "1.4.2",
"last_check_in": "2026-04-15T10:23:41Z",
"group": "production",
"labels": { "env": "production", "team": "backend" },
"created_at": "2026-01-10T08:00:00Z"
}
],
"meta": { "page": 1, "per_page": 25, "total": 12 }
}
GET /v1/servers/:id
Fetch full detail on a single server.
curl https://api.pulsewise.io/v1/servers/srv_8f3k2m1n \
-H "Authorization: Bearer sk_live_your_api_key"
GET /v1/servers/:id/metrics
Pull time-series metrics for one server over a given window.
| Parameter | Type | Required | Description |
|---|---|---|---|
| metrics | string | Optional | Comma-separated: cpu, memory, disk, load, network (default: all) |
| from | ISO 8601 | Optional | Start of time range (default: 1 hour ago) |
| to | ISO 8601 | Optional | End of time range (default: now) |
| interval | string | Optional | Aggregation interval: 1m, 5m, 15m, 1h (default: auto) |
// Response 200 OK
{
"server_id": "srv_8f3k2m1n",
"from": "2026-04-15T09:00:00Z",
"to": "2026-04-15T10:00:00Z",
"interval": "5m",
"metrics": {
"cpu": [
{ "timestamp": "2026-04-15T09:00:00Z", "value": 23.4 },
{ "timestamp": "2026-04-15T09:05:00Z", "value": 31.8 }
],
"memory": [
{ "timestamp": "2026-04-15T09:00:00Z", "value": 67.2 },
{ "timestamp": "2026-04-15T09:05:00Z", "value": 68.1 }
]
}
}
DELETE /v1/servers/:id
Detach a server from your workspace. The agent stays installed on the box — this only deletes the record and history on our side.
Incidents
GET /v1/incidents
List incidents across the workspace, newest first.
| Parameter | Type | Required | Description |
|---|---|---|---|
| status | string | Optional | Filter: open, acknowledged, resolved |
| severity | string | Optional | Filter: low, medium, high, critical |
| server_id | string | Optional | Filter by server ID |
| from | ISO 8601 | Optional | Start of date range |
| to | ISO 8601 | Optional | End of date range |
// Response 200 OK
{
"data": [
{
"id": "inc_a7b3c9d2",
"server_id": "srv_8f3k2m1n",
"server_hostname": "prod-api-01",
"severity": "critical",
"status": "open",
"title": "CPU usage sustained above 95% for 10 minutes",
"triggered_at": "2026-04-15T10:13:00Z",
"resolved_at": null,
"alert_rule_id": "rule_x4k2m1",
"ai_summary_available": true
}
],
"meta": { "page": 1, "per_page": 25, "total": 47 }
}
GET /v1/incidents/:id
One incident, fully expanded — timeline, metrics context, and the AI diagnostic summary.
// Response 200 OK
{
"id": "inc_a7b3c9d2",
"server_id": "srv_8f3k2m1n",
"severity": "critical",
"status": "open",
"title": "CPU usage sustained above 95% for 10 minutes",
"triggered_at": "2026-04-15T10:13:00Z",
"timeline": [
{ "time": "2026-04-15T10:13:00Z", "event": "Alert triggered: CPU > 95%" },
{ "time": "2026-04-15T10:13:02Z", "event": "AI analysis initiated" },
{ "time": "2026-04-15T10:13:08Z", "event": "Notifications sent: Slack, Email" }
],
"ai_summary": {
"what_happened": "CPU utilization spiked to 98.4% on prod-api-01.",
"likely_cause": "The node process (PID 4821) consumed 89% CPU, likely due to a runaway loop or unoptimized query handler.",
"suggested_steps": [
"Inspect the node process: top -p 4821",
"Check recent deployments for changes to request handlers",
"Review application logs for error loops"
]
}
}
PATCH /v1/incidents/:id
Acknowledge or resolve an incident.
curl -X PATCH https://api.pulsewise.io/v1/incidents/inc_a7b3c9d2 \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "status": "acknowledged" }'
Alerts
GET /v1/alerts/rules
List every alert rule in the workspace.
POST /v1/alerts/rules
Create a new alert rule with thresholds, sustain duration, and notification channels.
// Request body
{
"name": "High CPU Alert",
"metric": "cpu_usage",
"operator": "gt",
"threshold": 90,
"duration": "5m",
"severity": "critical",
"servers": ["srv_8f3k2m1n"],
"channels": ["slack", "email"],
"enabled": true
}
// Response 201 Created
{
"id": "rule_x4k2m1",
"name": "High CPU Alert",
"metric": "cpu_usage",
"operator": "gt",
"threshold": 90,
"duration": "5m",
"severity": "critical",
"servers": ["srv_8f3k2m1n"],
"channels": ["slack", "email"],
"enabled": true,
"created_at": "2026-04-15T10:30:00Z"
}
PUT /v1/alerts/rules/:id
Replace an alert rule. All fields are overwritten.
DELETE /v1/alerts/rules/:id
Delete an alert rule. Already-firing alerts from this rule are not auto-resolved.
Account & Workspace
GET /v1/workspace
Workspace info — plan, server usage, and member count.
// Response 200 OK
{
"id": "ws_k8m2n4p1",
"name": "Acme Corp",
"plan": "growth",
"server_count": 14,
"server_limit": 20,
"team_members": 5,
"created_at": "2026-01-10T08:00:00Z"
}
GET /v1/workspace/members
List all team members in the workspace with their roles.
POST /v1/workspace/members
Invite a new team member by email address.
curl -X POST https://api.pulsewise.io/v1/workspace/members \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{ "email": "dev@example.com", "role": "member" }'
Error Codes
Standard HTTP status codes. Errors come back as JSON with a machine-friendly code and a human-friendly message.
// Example error response
{
"error": {
"code": "rate_limit_exceeded",
"message": "You have exceeded the rate limit of 100 requests per minute.",
"status": 429
}
}
| Status | Code | Description |
|---|---|---|
| 400 | invalid_request | The request body is malformed or missing required fields. |
| 401 | unauthorized | API key is missing, invalid, or expired. |
| 403 | forbidden | The API key does not have permission for this action. |
| 404 | not_found | The requested resource does not exist. |
| 409 | conflict | The resource already exists or conflicts with current state. |
| 422 | unprocessable_entity | The request was valid but contained semantic errors. |
| 429 | rate_limit_exceeded | Too many requests. Retry after the Retry-After header value. |
| 500 | internal_error | An unexpected server error occurred. Contact support if persistent. |
Rate Limits
Limits are per-key and depend on your plan:
| Plan | Requests / min | Requests / day |
|---|---|---|
| Solo | 60 | 10,000 |
| Growth | 300 | 50,000 |
| Scale | 1,000 | 200,000 |
Hit the limit and you’ll get a 429 with a Retry-After header telling you how long to back off.
Webhooks
Push real-time events to any HTTP endpoint you control. Use them to fan out to PagerDuty, Opsgenie, custom on-call bots, or your own internal tooling.
Supported events
incident.triggered— A new incident was createdincident.acknowledged— An incident was acknowledged by a team memberincident.resolved— An incident was marked as resolvedserver.connected— A new server agent connectedserver.disconnected— A server agent went offlinealert.triggered— An alert rule condition was met
Webhook payload
// POST to your endpoint
{
"event": "incident.triggered",
"timestamp": "2026-04-15T10:13:00Z",
"data": {
"incident_id": "inc_a7b3c9d2",
"server_id": "srv_8f3k2m1n",
"server_hostname": "prod-api-01",
"severity": "critical",
"title": "CPU usage sustained above 95% for 10 minutes",
"dashboard_url": "https://app.pulsewise.io/incidents/inc_a7b3c9d2"
}
}
Verifying signatures
Every webhook ships with an X-Pulsewise-Signature header — an HMAC-SHA256 of the raw body, signed with your webhook secret. Always verify it before trusting the payload.
# Verify the signature
echo -n "$BODY" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | awk '{print $2}'
API Key Management
Manage API keys from your workspace dashboard under Settings → API Keys, or programmatically via the API.
GET /v1/api-keys
List all API keys in the workspace (keys are partially redacted in responses).
POST /v1/api-keys
Create a new API key. The full key is returned only once in the creation response — store it securely.
// Request body
{
"name": "CI/CD Pipeline",
"type": "live",
"permissions": ["servers:read", "incidents:read"]
}
// Response 201 Created
{
"id": "key_m4n8p2q1",
"name": "CI/CD Pipeline",
"type": "live",
"key": "sk_live_4f8a2b1c9d3e7f6a8b2c1d9e3f7a6b8c",
"permissions": ["servers:read", "incidents:read"],
"created_at": "2026-04-15T10:30:00Z",
"last_used_at": null
}
DELETE /v1/api-keys/:id
Revoke a key instantly. Any request using it after revocation returns 401.