Skip to content

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.

ParameterTypeRequiredDescription
statusstringOptionalFilter by status: healthy, warning, critical, offline
groupstringOptionalFilter by server group name
pageintegerOptionalPage number (default: 1)
per_pageintegerOptionalResults 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.

ParameterTypeRequiredDescription
metricsstringOptionalComma-separated: cpu, memory, disk, load, network (default: all)
fromISO 8601OptionalStart of time range (default: 1 hour ago)
toISO 8601OptionalEnd of time range (default: now)
intervalstringOptionalAggregation 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.

ParameterTypeRequiredDescription
statusstringOptionalFilter: open, acknowledged, resolved
severitystringOptionalFilter: low, medium, high, critical
server_idstringOptionalFilter by server ID
fromISO 8601OptionalStart of date range
toISO 8601OptionalEnd 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
  }
}
StatusCodeDescription
400invalid_requestThe request body is malformed or missing required fields.
401unauthorizedAPI key is missing, invalid, or expired.
403forbiddenThe API key does not have permission for this action.
404not_foundThe requested resource does not exist.
409conflictThe resource already exists or conflicts with current state.
422unprocessable_entityThe request was valid but contained semantic errors.
429rate_limit_exceededToo many requests. Retry after the Retry-After header value.
500internal_errorAn unexpected server error occurred. Contact support if persistent.

Rate Limits

Limits are per-key and depend on your plan:

PlanRequests / minRequests / day
Solo6010,000
Growth30050,000
Scale1,000200,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 created
  • incident.acknowledged — An incident was acknowledged by a team member
  • incident.resolved — An incident was marked as resolved
  • server.connected — A new server agent connected
  • server.disconnected — A server agent went offline
  • alert.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.