Skip to content
GDPR compliant. Hosted in DE.
14-day free trial →

Heartbeats & API monitoring

Cron jobs, backup scripts and data pipelines fail silently — until a customer calls. Heartbeats let your scripts ping “I'm alive” every X minutes; if the ping is missed, you get an alert. In parallel, API monitoring tests your endpoints with JSON-schema validation and latency limits.

# Heartbeats for cron jobs

Heartbeat schedule (live)
View in demo account →

Setup in 30 seconds

Per heartbeat you get a unique URL — add a curl call at the end of your script/cron. Missed ping within the grace window = alert.

# In your crontab — ping after a successful run
0 3 * * * /usr/local/bin/backup.sh && curl -fsS \
  https://api.xictraq.com/api/heartbeat/db-backup-3f9a2c/ping

# Or inside the script (Bash) — ping only on exit code 0
set -e
/usr/local/bin/backup.sh
curl -fsS https://api.xictraq.com/api/heartbeat/db-backup-3f9a2c/ping

Schedule + grace window

Two expectation models: a fixed interval (expected_interval_seconds, 60s to 24h, default 300s) OR a full cron expression (schedule, e.g. “0 3 * * *”) with its own timezone (timezone). Cron expressions are validated server-side; a timezone, if set, must be a valid IANA zone. On top sits a grace window (grace_period_seconds, 0 to 3600s, default 60s) as tolerance. If the ping is missing by deadline = next due time + grace, an alert fires. With a cron schedule the next due time is computed from the cron expression in the monitor timezone, otherwise from last ping + interval.

Status & auto-cleanup

A monitor moves through the states active, missed, failed and paused. The last ping is stored with a timestamp; if it is missing by the deadline, the monitor is set to “missed” and a heartbeat_missed alert fires. Paused monitors raise no alerts. If a monitor stays “missed” for more than 7 days (long-term down without any reaction), a cleanup routine automatically sets it to “paused” and resolves stale heartbeat alerts — keeping the alert feed clean.

# Duration & output signals

A ping alone only says “the job ran” — not “the job did the right thing”. Pass optional metrics with the ping and XICTRAQ additionally detects empty runs (ran but did nothing), runtime outliers and error exit codes.

Optional ping query parameters

You can append metrics to the ping URL: items (records processed, alias: processed), exit_code (0 = ok, anything else = failure), duration_ms (runtime in milliseconds), output or msg (a short plain-text note) and status=ok|fail. All parameters are optional and stored per run.

# Export job: send the exported rows, append the exit code
# exit_code first: in bash, $(wc …) resets the value of $?
/usr/local/bin/export.sh
curl -fsS "https://api.xictraq.com/api/heartbeat/db-backup-3f9a2c/ping?exit_code=$?&items=$(wc -l < export.csv)"

# With runtime + plain-text note
curl -fsS "https://api.xictraq.com/api/heartbeat/db-backup-3f9a2c/ping?duration_ms=8421&output=42%20tables%20backed%20up"

# Report a failure actively (instead of just letting the ping go missing)
curl -fsS "https://api.xictraq.com/api/heartbeat/db-backup-3f9a2c/ping?status=fail&exit_code=17"

Measure runtime with /start + /ping

You don't have to compute the duration yourself: ping /start at the job's beginning and /ping at the end — XICTRAQ takes the difference as runtime. Alternatively, pass duration_ms directly. The latest runtime shows up as last_duration_ms in the monitor overview.

# /start at the beginning, /ping at the end — runtime is computed server-side
curl -fsS https://api.xictraq.com/api/heartbeat/db-backup-3f9a2c/start
/usr/local/bin/backup.sh
curl -fsS "https://api.xictraq.com/api/heartbeat/db-backup-3f9a2c/ping?exit_code=$?&items=$(wc -l < export.csv)"

Actively report failure with /fail

Instead of just letting the ping go missing, your script can report a failure right away: a GET on /fail sets the monitor to status “failed” and fires a heartbeat_failed alert immediately — you do not have to wait out the grace window. Optionally append ?msg=… as the failure reason, ?exit_code=… and ?items=…. The next healthy /ping auto-recovers the monitor.

# If the script aborts, report an explicit failure with a reason
set -e
trap 'curl -fsS "https://api.xictraq.com/api/heartbeat/db-backup-3f9a2c/fail?msg=Backup%20aborted&exit_code=$?"' ERR
/usr/local/bin/backup.sh
curl -fsS https://api.xictraq.com/api/heartbeat/db-backup-3f9a2c/ping

Adaptive anomaly mode (runtime)

With duration_anomaly_auto, XICTRAQ learns your job's normal runtime per hour-of-week (mean + 3σ over a rolling window) and alerts when a run falls clearly outside the band — e.g. “ran 4× longer than usual on Mondays at 03:00”. Opt-in per heartbeat. Independently of it, the static threshold duration_threshold_ms (in milliseconds) always applies: if you do not set it yourself, a default of 60000 ms (60 seconds) is used, above which a run is alerted as slow; 0 switches the static threshold off. This avoids rigid thresholds for jobs with fluctuating load.

“Ran but did nothing” — expect_output & min_items

Enable expect_output when a run must produce output or items. Optionally set min_items as a minimum count. If the job then pings with items=0 (or below the minimum), XICTRAQ treats the run as an empty run and alerts — even when the exit code was 0. Exactly the “backup completed but saved 0 files” case.

Alert types at a glance
On top of the classic missed ping (no ping arrives), the module detects four signals: heartbeat_no_output (ran but did nothing — items=0 or below min_items when expect_output is set), heartbeat_duration_anomaly (ran clearly longer than normal, adaptive via duration_anomaly_auto), heartbeat_slow (exceeds the static threshold duration_threshold_ms, default 60000 ms) and heartbeat_failed (exit_code not equal to 0). The monitor auto-recovers on the next healthy ping — no manual reset required.

Fetch run history via API

GET /api/heartbeat/{id}/history returns the latest runs as JSON — per run kind (ping | start | fail), duration_ms, exit_code, items and created_at. Handy for pulling runtime trends or item counts into your own dashboards. In the overview these are mirrored by the monitor fields last_duration_ms, last_items, last_exit_code, last_anomaly_at and last_anomaly_reason.

GET /api/heartbeat/42/history

{
  "monitor_id": 42,
  "runs": [
    { "kind": "ping",  "duration_ms": 8421, "exit_code": 0, "items": 1284, "created_at": "2026-06-10 03:00:08" },
    { "kind": "start", "duration_ms": null, "exit_code": null, "items": null, "created_at": "2026-06-10 03:00:00" },
    { "kind": "fail",  "duration_ms": 142,  "exit_code": 17,   "items": 0,    "created_at": "2026-06-09 03:00:01" }
  ]
}

# API monitoring

More than plain up/down checks: define expectations per endpoint — status code, JSON schema, body match, response-time threshold. XICTRAQ calls the endpoint at the configured interval and alerts when two consecutive checks deviate.

API response time trend (live)
View in demo account →

Status code + JSON schema + body match

Freely combinable per endpoint. JSON schema can be defined in the UI or filtered via JSONPath selector (“response.users[*].email”). Regex matches in the body possible.

Auth via custom headers

Per endpoint you can set arbitrary HTTP headers — e.g. Authorization: Bearer eyJ..., X-API-Key: ... or basic-auth values. Headers are stored server-side and sent with every request. Static tokens work directly. For OAuth flows with short-lived tokens, combine API monitoring with a browser monitor (login flow + assert).

Run now (fast recovery check)

Each endpoint has a Run-now button (POST /api-endpoints/{id}/run) that triggers an immediate check independent of the cron. Useful after a deploy or while an alert is open to verify whether the issue is fixed — without waiting for the next interval.

Multi-step chains (login → token → call)

Instead of a single request you can chain up to 10 steps. Each step can extract values from its response (JSON path, header or regex) and reuse them via {{variable}} in the URL, headers or body of the next step — e.g. a token from the login step. Conditional execution (run_if) skips steps when a variable is missing; stop_on_fail halts the chain on the first failure. This monitors real auth-protected workflows, not just open health endpoints.

Contract drift (response schema)

Store a JSON schema per endpoint and XICTRAQ additionally validates the response body against this contract — catching silent schema changes (“contract drift”): HTTP 200, but a required field is missing, a type changed or a value leaves its allowed range. If the body violates the schema, the run counts as failed and is treated like a down for alerting: if the next check fails too, the same alert goes out. A JSON-schema subset is supported: type, required, properties, items (recursive), enum, minimum/maximum, minLength/maxLength and format (email, uri, date-time). If no schema is stored or the response is not valid JSON, the contract check is skipped — so it never degrades a run by mistake.

Interval, timeout & methods

Per endpoint you pick the method (GET, POST, PUT, PATCH, DELETE, HEAD), request body, check interval and timeout (1–30s, default 10s). The minimum interval depends on the plan: 300s on Starter, 60s on Business, 30s on Agency — a shorter value is automatically raised to the plan minimum. A cron checks every 30 seconds which endpoints are due and runs up to 200 checks per pass. The last 500 check results per endpoint are kept as history (HTTP code, response time, assertion results), retrievable via GET /api-endpoints/{id}/history.

Hardened against SSRF — and auth headers encrypted
Since you store arbitrary URLs and headers, every check is SSRF-hardened: target URLs that resolve to private/internal addresses are blocked, each redirect hop is individually checked against a public IP (no blind redirect-following, no DNS rebinding). The custom headers — your access secrets such as bearer tokens or API keys — are stored encrypted with the application key and only decrypted for the actual request or the editor view.

Frequently asked questions

An alert immediately via all channels enabled in your notification configuration (email, Slack, Discord, Teams, Telegram, webhook, browser push). With an escalation policy (from Business) further stages follow with a delay as long as nobody acknowledges via the ack link — each stage with its own delay in minutes, its own channels and its own recipient (a fixed address, the on-call contact on duty or a team role). You define the stage intervals yourself; an acknowledge stops further escalation.
Availability by plan
Heartbeats are included from the Free plan — Free 2, Starter 10, Business 100, Agency unlimited. API monitoring starts with the Starter plan (10 endpoints), Business 25, Agency 100; the minimum check interval shrinks with the plan (Starter 300s, Business 60s, Agency 30s). Multi-stage on-call escalation policies for the alerts are available from Business. If a creation exceeds your limit, the API responds with a plan-limit notice instead of silently overshooting.
Start in 60 seconds

Let XICTRAQ watch your website.

Permanent free plan available. No credit card, no installation, no hidden fees.