Loading...
Loading...
Everything you need to monitor workflows, track incidents, and maintain rock-solid uptime.
Four steps to go from zero to full observability for any scheduled job, pipeline, or automation.
Sign up or log in to access the platform. Your account is the gateway to all monitoring, alerting, and incident management features.
Projects group related workflows. Create a project, then add a workflow — each workflow gets a unique key used for the ingest API endpoint.
Call the ingest API from your cron job, CI pipeline, or automation tool. Every call records status, duration, and optional metadata.
curl -X POST https://heartbeater.pro/api/ingest/YOUR_WORKFLOW_KEY \
-H "Content-Type: application/json" \
-d '{
"status": "success",
"duration_ms": 842,
"meta_json": { "host": "prod-01" }
}'Head to Channels to connect Email, Slack, Discord, Microsoft Teams, or a custom Webhook. Then set up Monitors to define when alerts fire.
A single endpoint to record every execution event from any environment.
/api/ingest/[workflowKey]Replace [workflowKey] with the unique key shown on your workflow settings page. All fields except status are optional.
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | Yes | "success", "fail", or "start" |
| duration_ms | number | No | Execution duration in milliseconds (integer ≥ 0) |
| payload_size_bytes | number | No | Payload size in bytes (integer ≥ 0) |
| run_id | string | No | Correlate start/success/fail events for the same run (max 200 chars) |
| meta_json | object | No | Arbitrary key-value metadata attached to the event |
201 — Created
{
"ok": true,
"event_id": "a1b2c3d4-...",
"workflow_key": "YOUR_WORKFLOW_KEY"
}400 — Error
{
"error": "invalid request body",
"details": { "status": "Required" }
}cURL
curl -X POST https://heartbeater.pro/api/ingest/YOUR_WORKFLOW_KEY \
-H "Content-Type: application/json" \
-d '{
"status": "success",
"duration_ms": 1200,
"payload_size_bytes": 4096,
"meta_json": { "env": "production" }
}'Node.js
const res = await fetch(
"https://heartbeater.pro/api/ingest/YOUR_WORKFLOW_KEY",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
status: "success",
duration_ms: 1200,
meta_json: { env: "production" },
}),
}
);
const data = await res.json();
console.log(data); // { ok: true, event_id: "...", workflow_key: "..." }Python
import requests, time
start = time.time()
# ... your job logic ...
elapsed = int((time.time() - start) * 1000)
requests.post(
"https://heartbeater.pro/api/ingest/YOUR_WORKFLOW_KEY",
json={
"status": "success",
"duration_ms": elapsed,
"meta_json": {"env": "production"},
},
)GitHub Actions
# .github/workflows/heartbeat.yml
name: Scheduled Heartbeat
on:
schedule:
- cron: "*/5 * * * *"
jobs:
ping:
runs-on: ubuntu-latest
steps:
- name: Send heartbeat
run: |
curl -X POST https://heartbeater.pro/api/ingest/${{ secrets.WORKFLOW_KEY }} \
-H "Content-Type: application/json" \
-d '{"status": "success"}'From dashboards to incidents — every tool you need in one place.
Bird's-eye view with a composite health score, live KPIs (total events, failure rate, p95 latency), and interactive traffic charts over time.
/dashboardHost map overview, uptime heatmap by workflow, environment breakdown (production, staging, dev), and real-time host status indicators.
/infrastructureVisual topology of your entire workflow ecosystem. Project clusters show dependency relationships and real-time health propagation.
/service-mapDeep-dive into latency histograms, event volume trends, payload size distributions, and custom time-range analysis across all workflows.
/metricsStructured log viewer with full-text search, status/workflow filters, and aggregated status breakdowns. Inspect any event's full metadata.
/logsAuto-derived monitors: heartbeat (missing check-in), threshold (latency/failure rate), and volume anomaly detection. Each monitor ties to notification channels.
/monitorsFull incident lifecycle — SEV-1/2/3 classification, MTTR tracking, incident timeline, and resolution workflows with linked alerts and root cause notes.
/incidentsDefine Service Level Objectives with error budget tracking, burn rate visualization, and automatic alerting when budgets are at risk.
/slosPer-project public status page at /status/[projectId]. Share real-time operational status with your users — no login required.
/statusConnect Email, Slack, Discord, Microsoft Teams, or a custom Webhook. Each channel can be toggled on/off and linked to specific monitors.
/channelsDrop-in examples for the most popular automation platforms and CI/CD tools.
Add an HTTP Request node at the end of any n8n workflow. Set method to POST, URL to your ingest endpoint, and send status + duration in the JSON body.
// n8n HTTP Request node config
{
"method": "POST",
"url": "https://heartbeater.pro/api/ingest/YOUR_WORKFLOW_KEY",
"headers": { "Content-Type": "application/json" },
"body": {
"status": "{{ $json.success ? 'success' : 'fail' }}",
"duration_ms": "{{ $json.executionTime }}",
"meta_json": { "workflow": "{{ $workflow.name }}" }
}
}Use a Webhooks by Zapier action (POST) as the last step in your Zap to report execution status back to the platform.
// Zapier Webhook action config
URL: https://heartbeater.pro/api/ingest/YOUR_WORKFLOW_KEY
Method: POST
Data: {
"status": "success",
"meta_json": {
"zap_id": "{{zap_id}}",
"trigger": "{{trigger_name}}"
}
}Wrap your script in a timing function and POST the result. If the script fails, send a 'fail' status so monitors can alert immediately.
#!/bin/bash
START=$(date +%s%N)
# Your actual job
/usr/local/bin/my-backup-script.sh
EXIT_CODE=$?
END=$(date +%s%N)
DURATION=$(( (END - START) / 1000000 ))
if [ $EXIT_CODE -eq 0 ]; then STATUS="success"; else STATUS="fail"; fi
curl -sS -X POST https://heartbeater.pro/api/ingest/YOUR_WORKFLOW_KEY \
-H "Content-Type: application/json" \
-d "{\"status\": \"$STATUS\", \"duration_ms\": $DURATION}"Add a final step to any workflow to report build status. Use if: always() to ensure the heartbeat is sent even on failure.
# Add to any GitHub Actions workflow
- name: Report to Monitor
if: always()
run: |
STATUS="success"
if [ "${{ job.status }}" != "success" ]; then STATUS="fail"; fi
curl -sS -X POST https://heartbeater.pro/api/ingest/${{ secrets.WORKFLOW_KEY }} \
-H "Content-Type: application/json" \
-d "{
\"status\": \"$STATUS\",
\"meta_json\": {
\"repo\": \"${{ github.repository }}\",
\"sha\": \"${{ github.sha }}\",
\"branch\": \"${{ github.ref_name }}\"
}
}"For long-running services, send a 'start' event when a job begins and a 'success' or 'fail' event when it completes, correlated by run_id.
import { randomUUID } from "crypto";
const INGEST = "https://heartbeater.pro/api/ingest/YOUR_WORKFLOW_KEY";
const runId = randomUUID();
async function report(status: string, durationMs?: number) {
await fetch(INGEST, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ status, duration_ms: durationMs, run_id: runId }),
});
}
await report("start");
const t0 = Date.now();
try {
await doWork();
await report("success", Date.now() - t0);
} catch (err) {
await report("fail", Date.now() - t0);
throw err;
}Set up your first heartbeat check in under two minutes and never miss a failed job again.