Developer Documentation

Integrating STACKSTER

Reliable, dead-man's-switch telemetry for cron jobs, background workers, and automation workflows.

How STACKSTER Works

STACKSTER operates on an inverted monitoring model: instead of probing your server from the outside, your jobs ping STACKSTER when they start and complete. If STACKSTER doesn't receive a ping within the expected interval and grace period, it immediately triggers an alert.

1
/start Ping

Call /start at the beginning of your job to signal execution and start duration tracking.

2
Completion Ping

Call the root ping URL at successful job completion, optionally including JSON telemetry metrics and payload for assertion checks.

3
/fail Ping

Call /fail in your error handlers to trigger an immediate incident without waiting for timeout grace periods.

cURL & Shell Scripts

Integrate directly into cron scripts or shell wrappers using standard curl commands. Correlate start and end events using the run_id query parameter.

# 1. Start execution (starts duration stopwatch)
curl -fsS -m 10 -X POST "https://api.stackster.dev/ping/YOUR_PING_KEY/start?run_id=job_123"

# Run your actual cron / backup / workflow command
/usr/local/bin/run-backup.sh

# 2. Complete execution (measures runtime duration)
curl -fsS -m 10 -X POST "https://api.stackster.dev/ping/YOUR_PING_KEY?run_id=job_123" \
  -H "Content-Type: application/json" \
  -d '{"status":"success","records_processed":450}'

# 3. Or trigger immediate failure on error
curl -fsS -m 10 -X POST "https://api.stackster.dev/ping/YOUR_PING_KEY/fail?run_id=job_123" \
  -H "Content-Type: application/json" \
  -d '{"error":"Backup disk full"}'

Node.js & Python

Node.js / TypeScript

Wrap asynchronous workflows with native fetch or Axios.

const PING_URL = "https://api.stackster.dev/ping/YOUR_PING_KEY";
const runId = "job_" + Date.now();

try {
  // 1. Signal start
  await fetch(`${PING_URL}/start?run_id=${runId}`, { method: "POST" });

  // Execute task
  const result = await processData();

  // 2. Signal success with telemetry payload
  await fetch(`${PING_URL}?run_id=${runId}`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ count: result.length, status: "completed" }),
  });
} catch (err) {
  // 3. Signal immediate failure
  await fetch(`${PING_URL}/fail?run_id=${runId}`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ error: err instanceof Error ? err.message : String(err) }),
  });
  throw err;
}

Python

Use the standard requests library with error handling blocks.

import time
import requests

PING_URL = "https://api.stackster.dev/ping/YOUR_PING_KEY"
run_id = f"job_{int(time.time())}"

try:
    # 1. Signal start
    requests.post(f"{PING_URL}/start?run_id={run_id}", timeout=10)

    # Perform task
    records = sync_database()

    # 2. Signal completion
    requests.post(
        f"{PING_URL}?run_id={run_id}",
        json={"records_synced": len(records), "status": "ok"},
        timeout=10,
    )
except Exception as e:
    # 3. Signal failure
    requests.post(
        f"{PING_URL}/fail?run_id={run_id}",
        json={"error": str(e)},
        timeout=10,
    )
    raise

Universal Wrapper (Cron Jobs)

For standard cron jobs, scripts, and Docker tasks, the easiest and most robust integration is using the Universal Wrapper one-liner. It automatically signals start, captures the exit code of your command, and signals success or failure accordingly.

Bash One-Liner Wrapper

export PING_URL="https://api.stackster.app/p/YOUR_PING_KEY" && curl -fsS -m 10 -X POST "$PING_URL/start" && {
  <YOUR_COMMAND>;
  STATUS=$?;
  [ $STATUS -eq 0 ] && curl -fsS -m 10 -X POST "$PING_URL" || curl -fsS -m 10 -X POST "$PING_URL/fail";
  exit $STATUS;
}

Docker / Kubernetes CronJob

apiVersion: batch/v1
kind: CronJob
metadata:
  name: nightly-backup
spec:
  schedule: "0 2 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: my-backup-image
            command: ["/bin/sh", "-c"]
            args: 
            - >
              export PING_URL='https://api.stackster.app/p/YOUR_PING_KEY' &&
              curl -fsS -m 10 -X POST "$PING_URL/start" &&
              {
                /usr/local/bin/run-backup.sh;
                STATUS=$?;
                [ $STATUS -eq 0 ] && curl -fsS -m 10 -X POST "$PING_URL" || curl -fsS -m 10 -X POST "$PING_URL/fail";
                exit $STATUS;
              }
          restartPolicy: OnFailure

GitHub Actions

Uses the native GITHUB_RUN_ID to correlate executions in Stackster.

steps:
  - name: Run build script with monitoring
    run: |
      export PING_URL="https://api.stackster.app/p/YOUR_PING_KEY"
      curl -fsS -m 10 -X POST "$PING_URL/start?run_id=${{ github.run_id }}"
      {
        npm run build;
        STATUS=$?;
        [ $STATUS -eq 0 ] && curl -fsS -m 10 -X POST "$PING_URL?run_id=${{ github.run_id }}" || curl -fsS -m 10 -X POST "$PING_URL/fail?run_id=${{ github.run_id }}";
        exit $STATUS;
      }

n8n & Zapier Webhooks

Connect your no-code workflows without any custom plugins. Simply use standard HTTP Request nodes.

n8n Workflow Setup
  1. Add an HTTP Request node at trigger start: POST /start?run_id={{ $execution.id }}
  2. Add an HTTP Request node at successful completion: POST /?run_id={{ $execution.id }}
  3. Wire an Error Trigger node to: POST /fail?run_id={{ $execution.id }}
Zapier Integration
  1. Add a Webhooks by Zapier step (POST) at the beginning of your Zap.
  2. Target URL: https://api.stackster.dev/ping/YOUR_KEY/start
  3. Add a final Webhooks by Zapier (POST) step at the end of the Zap to signal success.

Payload Assertion Rules

STACKSTER supports JSON payload validation on incoming completion pings. If your cron job sends telemetry such as {"items_synced": 0}, you can configure assertion rules (e.g. items_synced > 0 or status == success). If an assertion fails, the check immediately transitions to Down and sends an alert.

Ready to start monitoring?

Create your first dead-man's-switch check in seconds.

Go to Dashboard