Docs

List incidents

GET /api/v1/incidents

Incidents of your team, newest first. Only confirmed incidents are returned: a failed check that a second location did not confirm is a suspicion, not an outage, and never appears here (see how outages are detected).

Parameters

All parameters are optional and go in the query string.

Parameter Meaning
from, to The period. An incident is included if it overlaps the period, so an outage that started on the last evening of the previous month and ended after midnight is in this month's report. Without from, as far back as your plan allows; without to, until now.
monitor Only incidents of one monitor (its ID from List monitors).
client Only incidents on the monitors of one client (its ID, the client.id of a monitor).
status open or resolved.
severity critical, warning or info.
per_page 1 to 100, default 50.
cursor The next page: the next_cursor from the previous answer.

Example

All incidents of one client in September, in the client's time zone:

cURL

curl -G http://pulsekeeper.io/api/v1/incidents \
  -H "Authorization: Bearer $PULSEKEEPER_TOKEN" \
  --data-urlencode "client=c4e0b9a17d2f6385" \
  --data-urlencode "from=2026-09-01T00:00:00+02:00" \
  --data-urlencode "to=2026-10-01T00:00:00+02:00"

PHP

<?php

// composer require guzzlehttp/guzzle
$client = new GuzzleHttp\Client([
    'base_uri' => 'http://pulsekeeper.io/api/v1/',
    'headers' => ['Authorization' => 'Bearer '.getenv('PULSEKEEPER_TOKEN')],
]);

$query = [
    'client' => 'c4e0b9a17d2f6385',
    'from' => '2026-09-01T00:00:00+02:00',
    'to' => '2026-10-01T00:00:00+02:00',
];
$incidents = [];

do {
    $page = json_decode($client->get('incidents', ['query' => $query])->getBody(), true);
    $incidents = array_merge($incidents, $page['data']);
    $query['cursor'] = $page['next_cursor'];
} while ($page['next_cursor'] !== null);

JavaScript

const query = new URLSearchParams({
  client: 'c4e0b9a17d2f6385',
  from: '2026-09-01T00:00:00+02:00',
  to: '2026-10-01T00:00:00+02:00',
});
const incidents = [];

do {
  const response = await fetch(`http://pulsekeeper.io/api/v1/incidents?${query}`, {
    headers: { Authorization: `Bearer ${process.env.PULSEKEEPER_TOKEN}` },
  });
  const page = await response.json();
  incidents.push(...page.data);
  query.set('cursor', page.next_cursor ?? '');
} while (query.get('cursor'));

Go

query := url.Values{}
query.Set("client", "c4e0b9a17d2f6385")
query.Set("from", "2026-09-01T00:00:00+02:00")
query.Set("to", "2026-10-01T00:00:00+02:00")

var incidents []map[string]any

for {
	req, _ := http.NewRequest("GET", "http://pulsekeeper.io/api/v1/incidents?"+query.Encode(), nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("PULSEKEEPER_TOKEN"))

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}

	var page struct {
		Data       []map[string]any `json:"data"`
		NextCursor *string          `json:"next_cursor"`
	}
	json.NewDecoder(res.Body).Decode(&page)
	res.Body.Close()

	incidents = append(incidents, page.Data...)
	if page.NextCursor == nil {
		break
	}
	query.Set("cursor", *page.NextCursor)
}

Response

{
  "data": [
    {
      "id": "3f9a1c0e7b2d4a58",
      "type": "downtime",
      "title": "Site unreachable",
      "severity": "critical",
      "state": "resolved",
      "monitor": { "id": "a81c27e05f3d9b64", "type": "http", "name": "HTTP", "target": "shop.example.com" },
      "client": { "id": "c4e0b9a17d2f6385", "name": "Example Shop" },
      "started_at": "2026-09-30T21:14:05Z",
      "confirmed_at": "2026-09-30T21:14:41Z",
      "acknowledged_at": null,
      "resolved_at": "2026-09-30T21:42:10Z",
      "duration_seconds": 1685,
      "excluded_from_sla": false,
      "affected_locations": ["fra", "lon"],
      "error": { "code": "http_5xx", "detail": "HTTP 502" },
      "cause": { "text": "Outage at the hosting provider", "in_report": true }
    }
  ],
  "next_cursor": "eyJzdGFydGVkX2F0Ijo…"
}

next_cursor is null on the last page. The fields of an incident are described under Get an incident.