Skip to content

Pulse API

A read-only JSON API for pulling devices, compliance posture and device events into a SIEM, GRC or asset tool. Every request is scoped to the organization that owns the token.

On this page

API tokens

In the console, open Settings, then API tokens, and create a token. Owners and admins can create them. Choose what the token can read and when it expires: 30, 90 or 365 days, or never.

ScopeMeaning
devices:readList devices and read each device's controls.
compliance:readRead the organization's compliance summary.
events:readList device events.

Pulse shows the token once. It starts with pls_ followed by eight characters that identify it in the console. Revoke a token there and it stops working at once. An organization can have 20 active tokens.

Back to contents

Authentication

Send the token in the Authorization header over HTTPS. Browser sessions and cookies don't work here.

export PULSE_TOKEN="pls_…"
curl -H "Authorization: Bearer $PULSE_TOKEN" https://pulse.offseq.com/api/public/v1/devices
Back to contents

Pagination

Lists return up to limit items in data. Pass nextCursor back as cursor with the same filters while hasMore is true. To poll for new events later, keep the last nextCursor and start from it next time.

{
  "data": [
    "…"
  ],
  "hasMore": true,
  "nextCursor": "Zxzp7mJtA1kAAUq3"
}
Back to contents

Errors and limits

Errors use one shape, with a stable code to match on:

{
  "error": {
    "code": "insufficient_scope",
    "message": "This token lacks the events:read scope."
  }
}
Status and codeMeaning
400 bad_requestA parameter is invalid. The message names it.
401 unauthorizedThe token is missing, invalid, expired or revoked.
403 insufficient_scopeThe token can't read this endpoint.
403 organization_suspendedThe organization is suspended.
404 not_foundNo such device in this organization.
429 rate_limitedToo many requests. Wait for the seconds in the Retry-After header.

Each token can make 120 requests a minute, and each IP address 300. Poll every few minutes and page with updatedSince or since rather than reading everything each time.

Back to contents

List devices

GET /api/public/v1/devices with scope devices:read. Every enrolled device, including revoked ones, oldest first.

ParameterMeaning
limit1 to 500, default 100.
cursornextCursor from the previous page.
oswindows, macos, linux or unknown.
compliancefailing (a control fails), passing (none fail) or unknown (no results yet).
statusactive or revoked.
updatedSinceISO 8601 time. Only devices that checked in or changed since then.
curl -H "Authorization: Bearer $PULSE_TOKEN" \
  "https://pulse.offseq.com/api/public/v1/devices?compliance=failing&updatedSince=2026-10-25T00:00:00Z"

Compliance counts accepted risks: a control under an active exception is in excepted, not failing. lifecycle is active, in_stock, lost or retired; owner is free text set in the console.

{
  "data": [
    {
      "id": "c1f6a2e0-…",
      "hostname": "lv-rix-lt-014",
      "os": {
        "family": "windows",
        "name": "Windows 11 Pro",
        "version": "10.0.22631"
      },
      "agentVersion": "0.1.13",
      "serialNumber": "PF3XK2LM",
      "status": "active",
      "lifecycle": "active",
      "owner": "Anna Ozola",
      "online": true,
      "enrolledAt": "2026-09-02T08:14:00.000Z",
      "lastSeenAt": "2026-10-26T09:41:12.000Z",
      "revokedAt": null,
      "network": {
        "publicIp": "203.0.113.24",
        "localIps": [
          "10.20.0.31"
        ]
      },
      "compliance": {
        "status": "failing",
        "score": 82,
        "failing": [
          "screen_lock"
        ],
        "excepted": []
      },
      "updatedAt": "2026-10-26T09:41:12.000Z"
    }
  ],
  "hasMore": false,
  "nextCursor": "Zxzp7mJtA1kAAUq3"
}
Back to contents

Get a device

GET /api/public/v1/devices/{id} with scope devices:read. The device as in the list, plus every control with its status on that device: pass, fail, excepted, unknown or not_applicable.

curl -H "Authorization: Bearer $PULSE_TOKEN" https://pulse.offseq.com/api/public/v1/devices/DEVICE_ID
{
  "id": "c1f6a2e0-…",
  "hostname": "lv-rix-lt-014",
  "os": {
    "family": "windows",
    "name": "Windows 11 Pro",
    "version": "10.0.22631"
  },
  "agentVersion": "0.1.13",
  "serialNumber": "PF3XK2LM",
  "status": "active",
  "lifecycle": "active",
  "owner": "Anna Ozola",
  "online": true,
  "enrolledAt": "2026-09-02T08:14:00.000Z",
  "lastSeenAt": "2026-10-26T09:41:12.000Z",
  "revokedAt": null,
  "network": {
    "publicIp": "203.0.113.24",
    "localIps": [
      "10.20.0.31"
    ]
  },
  "compliance": {
    "status": "failing",
    "score": 82,
    "failing": [
      "screen_lock"
    ],
    "excepted": []
  },
  "updatedAt": "2026-10-26T09:41:12.000Z",
  "controls": [
    {
      "id": "disk_encryption",
      "title": "Disk encryption enabled",
      "severity": "critical",
      "status": "excepted",
      "detail": "Not configured",
      "frameworks": [
        {
          "framework": "nis2",
          "ref": "Art. 21(2)(h)"
        },
        {
          "framework": "cis",
          "ref": "3.6"
        },
        {
          "framework": "lv_mk397",
          "ref": "§81.2"
        }
      ],
      "exception": {
        "id": "6718…",
        "justification": "Kiosk in a locked room, no sensitive data stored.",
        "compensatingControl": null,
        "approvedAt": "2026-10-01T10:00:00.000Z",
        "expiresAt": "2027-01-31T23:59:59.999Z"
      }
    }
  ]
}
Back to contents

Compliance summary

GET /api/public/v1/compliance/summary with scope compliance:read. The organization score across active devices (lost and retired devices are left out), device counts by control, and a score per framework (NIS2, CIS Controls v8.1, Cabinet Reg. 397). Scores weigh controls by severity and leave out excepted, unknown and not-applicable results. The summary is recomputed at most once a minute.

curl -H "Authorization: Bearer $PULSE_TOKEN" https://pulse.offseq.com/api/public/v1/compliance/summary
{
  "generatedAt": "2026-10-26T09:45:00.000Z",
  "score": 87,
  "devices": {
    "total": 42,
    "evaluated": 41,
    "compliant": 30
  },
  "controls": [
    {
      "id": "disk_encryption",
      "title": "Disk encryption enabled",
      "severity": "critical",
      "frameworks": [
        {
          "framework": "nis2",
          "ref": "Art. 21(2)(h)"
        }
      ],
      "pass": 38,
      "fail": 2,
      "excepted": 1,
      "unknown": 0,
      "notApplicable": 0
    }
  ],
  "frameworks": [
    {
      "framework": "nis2",
      "label": "NIS2",
      "score": 88,
      "pass": 290,
      "fail": 39
    }
  ]
}
Back to contents

List events

GET /api/public/v1/events with scope events:read. Device events in the order Pulse received them, oldest first. Events from the last few seconds appear on the next call, so following nextCursor never skips one. deviceId is null for organization-wide events, such as a refused enrollment.

ParameterMeaning
limit1 to 1000, default 100.
cursornextCursor from the previous call.
sinceISO 8601 time. Events received since then. Default: the last 24 hours.
deviceIdOnly this device's events.
curl -H "Authorization: Bearer $PULSE_TOKEN" "https://pulse.offseq.com/api/public/v1/events?since=2026-10-26T00:00:00Z&limit=500"
{
  "data": [
    {
      "id": "671c9e0a5b2f4c0012ab34cd",
      "deviceId": "c1f6a2e0-…",
      "category": "usb_storage",
      "type": "usb_inserted",
      "severity": "warning",
      "occurredAt": "2026-10-26T09:12:03.000Z",
      "receivedAt": "2026-10-26T09:12:05.000Z",
      "summary": "USB storage device connected: SanDisk Ultra",
      "data": {
        "vendor": "SanDisk"
      }
    }
  ],
  "hasMore": false,
  "nextCursor": "Zxzp7mJtA1kAAUq3"
}
Back to contents