Output Capture
Send stdout and stderr output alongside your ping. When a job fails, you'll have the logs right in your dashboard – no need to SSH into production to see what went wrong.
Output capture lets your cron jobs send stdout, stderr, exit codes, and execution duration to DeadPing with every ping. When a job fails, you can see exactly what happened in your dashboard without SSH access to production. Storage limits scale by plan: 1KB on Free, 100KB on Pro, 1MB on Business.
How It Works
Send a POST request to your ping URL with the output in the request body. DeadPing stores the body alongside the ping record so you can review it later in the dashboard.
curl -X POST "https://deadping.io/api/ping/YOUR_TOKEN" \
-H "Content-Type: text/plain" \
-d "Backup completed: 42 rows exported"Plan Limits
Body size limits are enforced per plan. Bodies that exceed the limit are truncated using byte-accurate TextEncoder/TextDecoder to avoid splitting multi-byte characters.
| Plan | Max Body Size | Body Retention | Ping History |
|---|---|---|---|
| Free | 1 KB | 1 day | 1 day |
| Pro ($12/mo) | 100 KB | 30 days | 90 days |
| Business ($39/mo) | 1 MB | 60 days | 365 days |
If your output exceeds the size limit, it will be truncated from the end. The first bytes are always preserved so you see the start of the output.
After the body retention period, output text is stripped but ping metadata (exit code, duration, timestamps) is retained for the full history window. This keeps your dashboard useful for trend analysis while managing storage costs.
Exit Codes
Pass the exit code of your script via the exit_code query parameter. This lets you distinguish between successful and failed runs in the dashboard.
# exit_code=0 means success
curl -fsS "https://deadping.io/api/ping/YOUR_TOKEN?exit_code=0"
# exit_code=1 means failure
curl -fsS "https://deadping.io/api/ping/YOUR_TOKEN?exit_code=1"Duration Tracking
Track how long your job takes via the duration_ms query parameter. DeadPing stores this per ping and displays it as a chart in the dashboard, making it easy to spot performance regressions.
START=$(date +%s%3N)
# ... your job here ...
END=$(date +%s%3N)
DURATION=$((END - START))
curl -fsS "https://deadping.io/api/ping/YOUR_TOKEN?duration_ms=$DURATION"Full Example: Bash
Capture output, exit code, and duration in a single ping:
#!/bin/bash
set -euo pipefail
TOKEN="YOUR_TOKEN"
START=$(date +%s%3N)
# Run your job, capture stdout + stderr
OUTPUT=$(my-script.sh 2>&1)
EXIT_CODE=$?
END=$(date +%s%3N)
DURATION=$((END - START))
# Send everything to DeadPing
curl -X POST "https://deadping.io/api/ping/$TOKEN?exit_code=$EXIT_CODE&duration_ms=$DURATION" \
-H "Content-Type: text/plain" \
-d "$OUTPUT"Full Example: Python
import subprocess
import time
import requests
TOKEN = "YOUR_TOKEN"
start = time.time()
result = subprocess.run(
["python", "etl_job.py"],
capture_output=True,
text=True,
)
duration_ms = int((time.time() - start) * 1000)
output = result.stdout + result.stderr
requests.post(
f"https://deadping.io/api/ping/{TOKEN}",
params={
"exit_code": result.returncode,
"duration_ms": duration_ms,
},
headers={"Content-Type": "text/plain"},
data=output[:1048576], # Respect 1MB max
)Full Example: Node.js
const { execSync } = require("child_process");
const TOKEN = "YOUR_TOKEN";
const start = Date.now();
let output = "";
let exitCode = 0;
try {
output = execSync("node etl-job.js", {
encoding: "utf-8",
stdio: ["pipe", "pipe", "pipe"],
});
} catch (err) {
output = err.stdout + err.stderr;
exitCode = err.status || 1;
}
const durationMs = Date.now() - start;
fetch(
`https://deadping.io/api/ping/${TOKEN}?exit_code=${exitCode}&duration_ms=${durationMs}`,
{
method: "POST",
headers: { "Content-Type": "text/plain" },
body: output,
}
);Output Search
On Pro and Business plans, captured output is full-text searchable via the GET /api/pings/search endpoint or the search bar in the dashboard. Search across all your monitors for specific error messages, stack traces, or keywords.
# Search for "connection refused" across all monitors
curl -H "X-API-Key: dp_live_..." \
"https://deadping.io/api/pings/search?q=connection+refused"