Integrations

Developer API

Authenticate, list monitors, fetch incidents, and stream check results from Pingara programmatically using the v1 REST Developer API.

8 min readUpdated May 14, 2026
apideveloperrestintegrationautomation

The Pingara Developer API gives you programmatic access to your monitors, incidents, and check results over HTTPS. It's designed for CI/CD pipelines, internal dashboards, ChatOps tools, and any other system that needs to read monitoring state without screen-scraping the UI.

At a glance

  • Base URL (production): https://api.pingara.io/api/v1
  • Base URL (development): https://api-dev.pingara.io/api/v1
  • Auth: Bearer token (Authorization: Bearer pgr_…)
  • Format: JSON, UTF-8
  • Scope: v1 is read-only and scoped to a single organization per key
  • Rate limit: 600 requests per minute, per key
  • Versioning: All endpoints live under /api/v1. Breaking changes ship under /api/v2.

1. Create an API key

  1. Sign in to Pingara and switch to the organization you want to script against.
  2. Open Settings → API.
  3. Click Create key, give it a recognisable name (for example CI deploy or Grafana sync), and submit.
  4. Copy the full key immediately. It is shown exactly once and starts with the prefix pgr_. Pingara only stores a SHA-256 hash, so a lost key cannot be recovered — revoke it and create a new one.

Only owners and admins can create or revoke keys. Each organization can hold up to 25 active keys at a time.

Storing keys safely

  • Treat the key like a password. Anyone with it can read every monitor, incident, and check result in your organization.
  • Store keys in your secrets manager (1Password, Vault, AWS Secrets Manager, GitHub Actions secrets, etc.) — never in source control.
  • Use a dedicated key per integration so you can revoke one without breaking the rest.

2. Authentication

Every request must include an Authorization header:

curl https://api.pingara.io/api/v1/me \
  -H "Authorization: Bearer pgr_abcdef0123456789..."

Successful responses return JSON with HTTP 200. Authentication failures return 401:

{ "error": "Invalid or revoked API key" }

3. Resources

GET /api/v1/me

Returns metadata about the organization the key belongs to.

{
  "organization": {
    "id": "j5k2…",
    "name": "Acme Inc",
    "slug": "acme",
    "plan": "pro"
  },
  "apiKey": {
    "id": "abcd…",
    "scopes": ["read"]
  }
}

Useful as a health-check at the start of a CI job.

GET /api/v1/monitors

List monitors in the organization, most recently updated first.

Query paramTypeDescription
limitinteger (1–200)Maximum monitors to return. Default 50.
statusstringFilter to one of up, down, degraded, pending, paused.

Example response:

{
  "count": 2,
  "data": [
    {
      "id": "m1aa…",
      "name": "Marketing site",
      "url": "https://www.example.com",
      "type": "http",
      "method": "GET",
      "interval": "1m",
      "timeout": 10000,
      "regions": ["us-east-1", "eu-west-1"],
      "expectedStatusCodes": [200, 301, 302],
      "keywordCheck": null,
      "keywordCheckEnabled": false,
      "apdexThreshold": 500,
      "tags": ["public", "marketing"],
      "environment": "production",
      "status": "up",
      "isEnabled": true,
      "isPaused": false,
      "lastCheckedAt": "2026-05-14T16:24:09.123Z",
      "lastStatusChange": "2026-05-12T09:11:02.000Z",
      "createdAt": "2026-01-04T12:00:00.000Z",
      "updatedAt": "2026-05-14T16:24:09.123Z"
    }
  ]
}

GET /api/v1/monitors/{id}

Returns a single monitor. Responds with 404 if the monitor does not exist or belongs to a different organization.

GET /api/v1/monitors/{id}/checks

Most recent check results for a monitor (newest first).

Query paramTypeDescription
limitinteger (1–200)Default 50.

Each result includes the regional probe, the timing breakdown (DNS / TCP / TLS / TTFB / total), response size, status code, and any error type/message.

GET /api/v1/monitors/{id}/incidents

Recent incidents for a single monitor, newest first.

GET /api/v1/incidents

Recent incidents across the whole organization.

Query paramTypeDescription
limitinteger (1–200)Default 50.
statusstringFilter to investigating, identified, monitoring, or resolved.

GET /api/v1/incidents/{id}

Returns a single incident with start/resolve timestamps, the affected regions, error metadata, and the AI-generated root-cause hint (when available).

4. Conventions

Response envelope

List endpoints return:

{ "data": [ ... ], "count": <number> }

Single-resource endpoints return:

{ "data": { ... } }

Timestamps

All timestamps are ISO 8601 strings in UTC, for example "2026-05-14T16:24:09.123Z".

Errors

Errors use standard HTTP status codes plus a JSON body:

StatusMeaning
400Bad request — invalid query parameter
401Missing, malformed, or revoked API key
404Resource not found (or not in your organization)
429Rate limit exceeded — see Retry-After header
5xxServer error — retry with exponential backoff

Rate limiting

Each API key may make up to 600 requests per minute. When you exceed the limit, the API returns 429 Too Many Requests with a Retry-After: 60 header. Build clients that respect both — a small fixed delay or exponential backoff works well.

CORS

The Developer API responds to cross-origin requests from any origin and supports preflight OPTIONS for the Authorization and Content-Type headers, so you can call it directly from browser-based dashboards if you're comfortable exposing the key (in general you should proxy through your backend instead).

5. Examples

curl: list every down monitor

curl -sS "https://api.pingara.io/api/v1/monitors?status=down" \
  -H "Authorization: Bearer $PINGARA_API_KEY" | jq '.data[].name'

Node.js / TypeScript

const base = process.env.PINGARA_API_BASE!; // https://api.pingara.io/api/v1
const key = process.env.PINGARA_API_KEY!;

async function listOpenIncidents() {
  const res = await fetch(`${base}/incidents?status=investigating&limit=100`, {
    headers: { Authorization: `Bearer ${key}` },
  });
  if (!res.ok) throw new Error(`Pingara API ${res.status}: ${await res.text()}`);
  const body = (await res.json()) as { data: Array<{ id: string; monitorId: string; startedAt: string }> };
  return body.data;
}

Python

import os, requests

base = os.environ["PINGARA_API_BASE"]
key = os.environ["PINGARA_API_KEY"]

resp = requests.get(
    f"{base}/monitors",
    headers={"Authorization": f"Bearer {key}"},
    params={"limit": 200},
    timeout=15,
)
resp.raise_for_status()
for m in resp.json()["data"]:
    print(m["status"], m["name"], m["url"])

GitHub Actions deploy gate

- name: Block deploy if any monitor is down
  env:
    PINGARA_API_KEY: ${{ secrets.PINGARA_API_KEY }}
  run: |
    count=$(curl -sS \
      "$PINGARA_API_BASE/monitors?status=down" \
      -H "Authorization: Bearer $PINGARA_API_KEY" | jq '.count')
    if [ "$count" -gt 0 ]; then
      echo "::error::$count monitors currently down — aborting deploy"
      exit 1
    fi

6. Versioning & deprecation policy

  • The v1 surface is stable. We will not remove fields or change types without bumping the major version.
  • Additive changes (new fields on existing responses, new endpoints, new query parameters with safe defaults) ship under v1 and do not constitute a breaking change.
  • When v2 ships, v1 will continue to operate for at least 12 months after the v2 GA announcement.

7. What's next

Roadmap items we're tracking for upcoming releases:

  • Write endpoints (create / pause / resume monitors, acknowledge incidents)
  • Scoped keys (read-only vs. write-only, per-monitor scopes)
  • Webhook event subscriptions (push delivery of incident.opened, incident.resolved, monitor.status_changed)
  • OpenAPI 3.1 spec for code generation
  • SDKs for Node.js, Go, and Python

Have feedback or a use case we haven't covered? Email support@pingara.io — we'd love to hear from you.