Cronping

Management API

REST API for programmatic management of heartbeats and integrations.

Overview

The Management API lets you create, update, delete, and query heartbeats programmatically. Use it to automate provisioning from CI/CD pipelines, build custom dashboards, or integrate Cronping into your infrastructure-as-code workflow.

Base URL:

https://cronping.com/api/v1

Authentication

All requests must include an API key in the X-Api-Key header:

GET /api/v1/heartbeats HTTP/1.1
Host: cronping.com
X-Api-Key: cpk_abc123...

Creating API keys

Go to Settings → API Keys in your organization dashboard. Each key is scoped to a single organization.

PermissionDescription
Read-WriteFull CRUD access to heartbeats, plus pause/resume
Read OnlyList and get only. Sensitive fields (token, ping URL) are hidden

Security

The raw API key is shown only once when created. Store it securely — you cannot retrieve it later. Only the first 12 characters are saved for identification.


Rate limiting

Each API key is limited to 100 requests per minute. If you exceed this, the API returns:

{
  "error": "Rate limit exceeded. Max 100 requests per minute."
}

Status: 429 Too Many Requests
Header: Retry-After: <seconds>


Heartbeats

List heartbeats

GET /api/v1/heartbeats

Query parameters:

ParameterTypeDescription
limitnumberMax results (1–100, default 50)
offsetnumberPagination offset (default 0)
querystringFilter by name (case-insensitive substring)
statusstringFilter by status (repeatable: ?status=up&status=down)
tagstringFilter by tag (repeatable: ?tag=prod&tag=db)

Response:

{
  "heartbeats": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Daily DB Backup",
      "status": "up",
      "paused": false,
      "scheduleType": "cron",
      "intervalSeconds": 0,
      "cronExpression": "0 3 * * *",
      "timezone": "America/Sao_Paulo",
      "graceSeconds": 300,
      "tags": "prod db",
      "emailAlertsEnabled": true,
      "reminderIntervalSeconds": 0,
      "lastPingAt": "2026-03-13T03:00:12.000Z",
      "nextExpectedAt": "2026-03-14T03:05:00.000Z",
      "token": "abc123def456...",
      "pingUrl": "https://ping.cronping.com/abc123def456...",
      "createdAt": "2026-01-10T12:00:00.000Z",
      "updatedAt": "2026-03-13T03:00:12.000Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}

Read-only keys omit the token and pingUrl fields from every heartbeat response.


Get heartbeat

GET /api/v1/heartbeats/:id

Returns a single heartbeat with its linked integration IDs.

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Daily DB Backup",
  "integrationIds": ["660e8400-..."]
}

Create heartbeat

POST /api/v1/heartbeats
Content-Type: application/json

Request body:

FieldTypeRequiredDescription
namestringHeartbeat name (1–200 chars)
scheduleTypestring"interval" (default) or "cron"
intervalSecondsnumber✅*Interval in seconds (60–2 592 000). Required for interval type
cronExpressionstring✅*Cron expression. Required for cron type
timezonestringIANA timezone for cron (default "UTC")
graceSecondsnumberGrace period (0–86 400, default 300)
tagsstringSpace-separated tags
emailAlertsEnabledbooleanEnable email alerts (default true)
reminderIntervalSecondsnumberRepeated alert interval in seconds
integrationIdsstring[]Array of integration UUIDs to link
uniquestringUpsert key (see below)

Example:

curl -X POST https://cronping.com/api/v1/heartbeats \
  -H "X-Api-Key: cpk_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Daily DB Backup",
    "scheduleType": "cron",
    "cronExpression": "0 3 * * *",
    "timezone": "America/Sao_Paulo",
    "graceSeconds": 600
  }'

Response: 201 Created with the full heartbeat object (including token and pingUrl).

Idempotent upsert with unique

Pass a unique field to enable upsert behavior. If a heartbeat with a matching name already exists in the organization, it will be updated instead of creating a duplicate. This is perfect for CI/CD pipelines:

curl -X POST https://cronping.com/api/v1/heartbeats \
  -H "X-Api-Key: cpk_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "worker-node-1",
    "unique": "worker-node-1",
    "intervalSeconds": 300,
    "graceSeconds": 60
  }'

If the heartbeat already exists, returns 200 OK with the updated heartbeat. Otherwise, 201 Created.


Update heartbeat

PATCH /api/v1/heartbeats/:id
Content-Type: application/json

Only include the fields you want to change. All fields from the create body are supported (except unique).

curl -X PATCH https://cronping.com/api/v1/heartbeats/550e8400-... \
  -H "X-Api-Key: cpk_abc123..." \
  -H "Content-Type: application/json" \
  -d '{"graceSeconds": 600, "tags": "prod db critical"}'

Response: 200 OK with the updated heartbeat.


Delete heartbeat

DELETE /api/v1/heartbeats/:id

Permanently deletes the heartbeat and all its associated pings, alerts, and flips.

{
  "id": "550e8400-...",
  "deleted": true
}

Pause heartbeat

POST /api/v1/heartbeats/:id/pause

Pauses the heartbeat. No alerts will fire while paused.


Resume heartbeat

POST /api/v1/heartbeats/:id/resume

Resumes the heartbeat. Status resets to new, and the next ping re-establishes the cadence.


Pings

List pings for a heartbeat

GET /api/v1/heartbeats/:id/pings

Query parameters:

ParameterTypeDescription
limitnumberMax results (1–200, default 50)
offsetnumberPagination offset (default 0)

Response:

{
  "pings": [
    {
      "id": "...",
      "heartbeatId": "...",
      "type": "success",
      "receivedAt": "2026-03-13T03:00:12.000Z",
      "ipAddress": "203.0.113.1",
      "userAgent": "curl/8.0",
      "durationMs": 4523,
      "runId": null,
      "exitCode": null
    }
  ],
  "total": 42,
  "limit": 50,
  "offset": 0
}

Integrations

List integrations

GET /api/v1/integrations

Returns all alert integrations configured for the organization.

Response:

{
  "integrations": [
    {
      "id": "660e8400-e29b-41d4-a716-446655440000",
      "channel": "slack",
      "name": "Slack #alerts",
      "enabled": true,
      "createdAt": "2026-01-15T10:00:00.000Z",
      "updatedAt": "2026-02-20T14:30:00.000Z"
    }
  ]
}

Error responses

All errors follow the same format:

{
  "error": "Descriptive error message"
}
StatusMeaning
400Bad request — invalid input
401Unauthorized — missing or invalid API key
403Forbidden — read-only key or plan limit
404Not found — heartbeat doesn't exist
429Rate limit exceeded
500Internal server error

Quick example: provision from CI/CD

# .github/workflows/deploy.yml
- name: Register heartbeat in Cronping
  run: |
    curl -X POST https://cronping.com/api/v1/heartbeats \
      -H "X-Api-Key: ${{ secrets.CRONPING_API_KEY }}" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "deploy-health-${{ github.event.repository.name }}",
        "unique": "deploy-health-${{ github.event.repository.name }}",
        "intervalSeconds": 300,
        "graceSeconds": 60,
        "tags": "ci deploy"
      }'

This creates (or updates) a heartbeat every time you deploy, ensuring your monitoring stays in sync with your infrastructure.

On this page