Exit Codes
Pass the shell exit code as the ping event. Drumbeats maps 0 to success and any non-zero code to failure while preserving the exact code for debugging.
Exit-code pings are the low-friction way to wire a shell job into Drumbeats. Pass $? (the previous command's exit status) directly as the event suffix; the Drumbeats Ping API maps 0 to success, any value from 1 to 255 to failure, and stores the exact numeric code on the run timeline for debugging.
Basic pattern
The whole integration is one extra line at the end of the job:
your-job
curl -sf https://api.drumbeats.io/v1/ping/<monitor-id>/$?your-job
curl -sf https://api.drumbeats.io/v1/ping/<monitor-id>/$?-sf keeps curl quiet (-s) and makes it exit non-zero on HTTP errors (-f) — important inside crontab, which otherwise mails any curl chatter to the system MTA.
Mapping rules
| Exit code | Stored as | Monitor effect |
|---|---|---|
0 | success event | Resolves any open incident, monitor flips UP. |
1 … 255 | failure event with exit_code metadata | Failure counter +1; monitor flips DOWN once the counter reaches failure_tolerance. |
The exact non-zero code is preserved on the run timeline so you can tell SIGKILL (137) from a custom exit 42 at a glance.
Examples
Inline cron job
0 2 * * * /usr/bin/backup.sh; \
curl -sf https://api.drumbeats.io/v1/ping/<monitor-id>/$?0 2 * * * /usr/bin/backup.sh; \
curl -sf https://api.drumbeats.io/v1/ping/<monitor-id>/$?Use ; rather than && so the ping still runs when the job fails — otherwise the ping is skipped on the very runs you most want to track.
Python script
python sync.py
curl -sf https://api.drumbeats.io/v1/ping/<monitor-id>/$?python sync.py
curl -sf https://api.drumbeats.io/v1/ping/<monitor-id>/$?Capture-then-send (concurrency-safe)
$? reflects only the most recent command. If you run anything else between the job and the ping, capture the code first:
your-job
EXIT=$?
# safe to do other work here — the captured value will not change
curl -sf https://api.drumbeats.io/v1/ping/<monitor-id>/$EXITyour-job
EXIT=$?
# safe to do other work here — the captured value will not change
curl -sf https://api.drumbeats.io/v1/ping/<monitor-id>/$EXITEvent-driven worker with run_id
Exit codes compose with the event-driven pattern. Send start with a run_id at the top, then $? with the same run_id at the end:
RUN_ID="job-$(date +%s)"
curl -sf "https://api.drumbeats.io/v1/ping/<monitor-id>/start?run_id=$RUN_ID"
python worker.py
EXIT=$?
curl -sf "https://api.drumbeats.io/v1/ping/<monitor-id>/${EXIT}?run_id=$RUN_ID"RUN_ID="job-$(date +%s)"
curl -sf "https://api.drumbeats.io/v1/ping/<monitor-id>/start?run_id=$RUN_ID"
python worker.py
EXIT=$?
curl -sf "https://api.drumbeats.io/v1/ping/<monitor-id>/${EXIT}?run_id=$RUN_ID"When to pick exit codes vs named events
| Use exit codes when | Prefer named events when |
|---|---|
| You are wrapping a single shell command | You need start and duration tracking |
| You want the minimum scripting overhead | You need log progress events |
$? is already available | You need to attach a payload from script logic |
| The job has one clear success / failure boundary | The job has multiple stages worth recording |
If the job needs anything beyond binary success/failure, use Status signals — they cost the same in Beats and give you progress logs.
Tips
Related guides
- Ping API reference — events, methods, and response shapes.
- Status signals — when to use exit codes vs named events.
- Scheduled pings — the Cron / Heartbeat patterns most exit-code integrations use.
- Shell integration — production-grade shell patterns with retries and timeouts.