API v1Preview

Servbyte REST API

The Servbyte REST API is rolling out in preview. Request an API key from your dashboard or via Contact to get early access.

Introduction

The Servbyte API speaks JSON over HTTPS. Every request and response uses UTF-8 encoded JSON, and every timestamp is UTC in ISO 8601 format.

  • Base URL: https://api.servbyte.io/v1
  • Content type: application/json
  • Versioning: the version is included in the URL path (/v1). Breaking changes ship under a new version; additive fields may appear in v1 without notice.
bash
curl https://api.servbyte.io/v1/hosts \
  -H "Authorization: Bearer sbk_live_wksp_9f2a...c81b"

Authentication

All requests must include a workspace-scoped API key as a bearer token in the Authorization header. Keys are created from Dashboard → Settings → API Keys and belong to a single workspace — a key issued in one workspace cannot read data from another.

Each key can be scoped at creation time to read or read_write. Only Owners and Admins may create or revoke keys. Keys are shown once at creation — store them in your secret manager, not in source control.

http
GET /v1/hosts HTTP/1.1
Host: api.servbyte.io
Authorization: Bearer sbk_live_wksp_9f2a...c81b
Accept: application/json

Preview keys are prefixed sbk_live_. Requests without a valid bearer token return 401.

Rate limits

During preview, each API key is limited to 120 requests per minute on a rolling window. Every response includes the current window state so clients can self-throttle.

http
HTTP/1.1 200 OK
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 1753788420

When the limit is exceeded, Servbyte returns 429 Too Many Requests with a Retry-After header (seconds). Retry after that delay with jittered backoff.

http
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json

{
  "error": {
    "type": "rate_limited",
    "message": "Too many requests. Retry after 12 seconds."
  }
}

Hosts

A host is a machine running the Servbyte agent — a VPS, a bare-metal server, or a VM. Hosts belong to a workspace and can be grouped with tags.

List monitored hosts

GET/v1/hosts

Returns hosts visible to the API key's workspace. Supports status (healthy | warning | critical | offline) and tag query filters, plus limit and cursor for pagination.

http
GET /v1/hosts?status=healthy&limit=25
Authorization: Bearer sbk_live_wksp_9f2a...c81b
json
{
  "data": [
    {
      "id": "host_01HZY3K8T7QV4R",
      "hostname": "prod-api-01",
      "status": "healthy",
      "os": "Ubuntu 24.04 LTS",
      "arch": "x86_64",
      "tags": ["prod", "api"],
      "last_seen_at": "2026-07-29T08:52:11Z"
    },
    {
      "id": "host_01HZY3M2G1FS9D",
      "hostname": "prod-worker-02",
      "status": "warning",
      "os": "Debian 12",
      "arch": "aarch64",
      "tags": ["prod", "workers"],
      "last_seen_at": "2026-07-29T08:52:07Z"
    }
  ],
  "next_cursor": null
}

Get host detail + latest metrics

GET/v1/hosts/{id}

Returns the host record and the most recent metric sample. Resolution follows the workspace plan — 5 min on Hobby, 30 s on Pro, 10 s on Team.

json
{
  "data": {
    "id": "host_01HZY3K8T7QV4R",
    "hostname": "prod-api-01",
    "status": "healthy",
    "os": "Ubuntu 24.04 LTS",
    "arch": "x86_64",
    "tags": ["prod", "api"],
    "agent_version": "1.4.2",
    "last_seen_at": "2026-07-29T08:52:11Z",
    "metrics": {
      "sampled_at": "2026-07-29T08:52:10Z",
      "cpu_percent": 34.2,
      "memory_percent": 61.7,
      "disk_percent": 42.0,
      "load_1m": 0.87,
      "network_rx_kbps": 812.4,
      "network_tx_kbps": 305.1
    }
  }
}

Incidents

Incidents are opened automatically when an alert rule trips or the anomaly detector flags divergence. Related alerts are grouped into a single incident.

List incidents

GET/v1/incidents

Filters: host_id, severity (info | warning | critical), status (open | acknowledged | resolved), since (ISO 8601).

http
GET /v1/incidents?severity=critical&status=open
Authorization: Bearer sbk_live_wksp_9f2a...c81b
json
{
  "data": [
    {
      "id": "INC-2148",
      "title": "Sustained CPU saturation on prod-api-01",
      "severity": "critical",
      "status": "open",
      "host_id": "host_01HZY3K8T7QV4R",
      "hostname": "prod-api-01",
      "started_at": "2026-07-29T08:44:02Z",
      "acknowledged_at": null,
      "resolved_at": null
    }
  ],
  "next_cursor": null
}

Get incident detail (with AI summary)

GET/v1/incidents/{id}

Returns the incident, the event timeline, and — on Pro and Team plans — an AI-drafted summary. The ai_summary block is assistive: verify with your own logs and dashboards before acting.

json
{
  "data": {
    "id": "INC-2148",
    "title": "Sustained CPU saturation on prod-api-01",
    "severity": "critical",
    "status": "open",
    "host_id": "host_01HZY3K8T7QV4R",
    "hostname": "prod-api-01",
    "started_at": "2026-07-29T08:44:02Z",
    "acknowledged_at": null,
    "resolved_at": null,
    "timeline": [
      { "at": "2026-07-29T08:44:02Z", "kind": "trigger",
        "text": "cpu_percent > 85 for 3m" },
      { "at": "2026-07-29T08:44:06Z", "kind": "alert",
        "text": "Routed to #ops (Slack) and PagerDuty" },
      { "at": "2026-07-29T08:45:12Z", "kind": "note",
        "text": "Anomaly detector: memory diverging from baseline" }
    ],
    "ai_summary": {
      "assistive": true,
      "what": "Sustained CPU saturation on prod-api-01.",
      "started": "2026-07-29T08:44:02Z",
      "affected": ["prod-api-01", "nginx.service"],
      "likely_cause": "Memory pressure preceded CPU spike; a deploy marker arrived 90s prior.",
      "suggested_next_steps": [
        "Review recent deploy diff",
        "journalctl -u nginx -n 200",
        "Check worker restart counts"
      ]
    }
  }
}

Note: AI fields are assistive. Servbyte drafts a hypothesis from infrastructure signals only — never application code, request bodies, or end-user data.

Alert rules

Alert rules describe the condition that opens an incident, and where to route the notification. Rules are workspace-scoped and can target one host, a tag, or all hosts.

Create an alert rule

POST/v1/alert-rules

Body fields:

  • metric — one of cpu_percent, memory_percent, disk_percent, load_1m.
  • operator gt | gte | lt | lte.
  • threshold — numeric value.
  • duration_seconds — how long the condition must hold before opening an incident (min 30).
  • channels — array of channel IDs (Email/Slack/Discord/webhook).
  • target{ type: "host", host_id }, { type: "tag", tag }, or { type: "workspace" }.
http
POST /v1/alert-rules
Authorization: Bearer sbk_live_wksp_9f2a...c81b
Content-Type: application/json

{
  "name": "High CPU on prod API",
  "metric": "cpu_percent",
  "operator": "gt",
  "threshold": 85,
  "duration_seconds": 180,
  "severity": "critical",
  "target": { "type": "tag", "tag": "api" },
  "channels": ["chn_slack_ops", "chn_pagerduty_prod"]
}
json
{
  "data": {
    "id": "rule_01HZY42N7QVXCP",
    "name": "High CPU on prod API",
    "metric": "cpu_percent",
    "operator": "gt",
    "threshold": 85,
    "duration_seconds": 180,
    "severity": "critical",
    "target": { "type": "tag", "tag": "api" },
    "channels": ["chn_slack_ops", "chn_pagerduty_prod"],
    "created_at": "2026-07-29T09:01:33Z"
  }
}

List alert rules

GET/v1/alert-rules
json
{
  "data": [
    {
      "id": "rule_01HZY42N7QVXCP",
      "name": "High CPU on prod API",
      "metric": "cpu_percent",
      "operator": "gt",
      "threshold": 85,
      "duration_seconds": 180,
      "severity": "critical",
      "target": { "type": "tag", "tag": "api" },
      "channels": ["chn_slack_ops", "chn_pagerduty_prod"]
    },
    {
      "id": "rule_01HZY49R3K8VN2",
      "name": "Disk pressure on workers",
      "metric": "disk_percent",
      "operator": "gt",
      "threshold": 90,
      "duration_seconds": 300,
      "severity": "warning",
      "target": { "type": "tag", "tag": "workers" },
      "channels": ["chn_email_ops"]
    }
  ],
  "next_cursor": null
}

Delete an alert rule

DELETE/v1/alert-rules/{id}
http
DELETE /v1/alert-rules/rule_01HZY42N7QVXCP
Authorization: Bearer sbk_live_wksp_9f2a...c81b
http
HTTP/1.1 204 No Content

Errors

Servbyte uses conventional HTTP status codes. Every error response has the same JSON shape so clients can log and branch on error.type reliably.

json
{
  "error": {
    "type": "invalid_request",
    "message": "threshold must be a number between 0 and 100",
    "param": "threshold",
    "request_id": "req_01HZY4B9F2N7QR"
  }
}
CodeTypeMeaning
400invalid_requestMalformed JSON or a validation error on a field.
401unauthenticatedMissing or invalid bearer token.
403forbiddenKey lacks the required scope for this endpoint.
404not_foundThe requested resource does not exist in this workspace.
429rate_limitedPer-key rate limit exceeded. Honor Retry-After.
500server_errorSomething went wrong on our side. Retry with backoff.

Every error includes a request_id. Include it when contacting support so we can trace the request end-to-end.

Get an API key

The API is in preview. Request early access from your dashboard, or reach out and we'll enable it on your workspace.