Skip to main content

Ping API

Pings are how your jobs communicate with Saturn. Each ping provides context about job execution.

Ping Types

Start Ping

Signals that a job has begun execution.

POST /api/ping/YOUR_MONITOR_ID/start

When to use:

  • Long-running jobs (> 5 minutes)
  • Jobs where "started but didn't finish" is meaningful
  • To track in-progress status in dashboard

Optional:

  • You can skip start pings for simple jobs
  • Saturn infers start time from success/fail ping arrival

Example:

curl -X POST https://api.saturnmonitor.com/api/ping/YOUR_MONITOR_ID/start \
-H "Authorization: Bearer YOUR_TOKEN"

Success Ping

Signals that a job completed successfully.

POST /api/ping/YOUR_MONITOR_ID/success

Required:

  • Always send this for successful job completion

Includes:

  • Duration (milliseconds)
  • Output (optional, if capture enabled)

Example with duration:

curl -X POST https://api.saturnmonitor.com/api/ping/YOUR_MONITOR_ID/success \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"durationMs": 12456}'

Example with output:

curl -X POST https://api.saturnmonitor.com/api/ping/YOUR_MONITOR_ID/success \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"durationMs": 12456,
"output": "Backup completed\n5000 files processed\n2.3 GB total"
}'

Fail Ping

Signals that a job failed.

POST /api/ping/YOUR_MONITOR_ID/fail

Required:

  • Send this for job failures

Includes:

  • Exit code (optional but recommended)
  • Error output (optional)
  • Duration (optional)

Example:

curl -X POST https://api.saturnmonitor.com/api/ping/YOUR_MONITOR_ID/fail \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"exitCode": 1,
"durationMs": 3200,
"output": "ERROR: Database connection failed\nTimeout after 30s"
}'

Ping Flow Patterns

Pattern 1: Simple (Success or Fail)

Simplest approach — just ping at the end:

#!/bin/bash
MONITOR_ID="mon_abc123"
TOKEN="YOUR_TOKEN"

# Run job
if ./backup.sh; then
curl -X POST https://api.saturnmonitor.com/api/ping/YOUR_MONITOR_ID/success \
-H "Authorization: Bearer YOUR_TOKEN"
else
curl -X POST https://api.saturnmonitor.com/api/ping/YOUR_MONITOR_ID/fail \
-H "Authorization: Bearer YOUR_TOKEN"
fi

Pattern 2: Start → Success/Fail

For long jobs where in-progress status matters:

#!/bin/bash
MONITOR_ID="mon_abc123"
TOKEN="YOUR_TOKEN"
API_URL="https://api.saturnmonitor.com/api/ping/YOUR_MONITOR_ID"

# Start ping
curl -X POST "$API_URL/start" -H "Authorization: Bearer YOUR_TOKEN"

# Run job
if ./backup.sh; then
curl -X POST "$API_URL/success" -H "Authorization: Bearer YOUR_TOKEN"
else
curl -X POST "$API_URL/fail" -H "Authorization: Bearer YOUR_TOKEN"
fi

Pattern 3: Full Context (Duration + Output)

Track everything for maximum visibility:

#!/bin/bash
MONITOR_ID="mon_abc123"
TOKEN="YOUR_TOKEN"
API_URL="https://api.saturnmonitor.com/api/ping/YOUR_MONITOR_ID"

# Start ping
curl -X POST "$API_URL/start" -H "Authorization: Bearer YOUR_TOKEN"

# Track duration
START=$(date +%s)

# Run and capture output
if OUTPUT=$(./backup.sh 2>&1); then
END=$(date +%s)
DURATION=$(( (END - START) * 1000 ))

curl -X POST "$API_URL/success" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"durationMs\": $DURATION, \"output\": $(echo "$OUTPUT" | jq -Rs .)}"
else
EXIT_CODE=$?
END=$(date +%s)
DURATION=$(( (END - START) * 1000 ))

curl -X POST "$API_URL/fail" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"exitCode\": $EXIT_CODE, \"durationMs\": $DURATION, \"output\": $(echo "$OUTPUT" | jq -Rs .)}"
fi

Request Format

Headers

Authorization: Bearer YOUR_TOKEN
Content-Type: application/json (for JSON body)

Success Ping Body

{
"durationMs": 12456, // Optional: milliseconds
"output": "Job output..." // Optional: stdout/stderr
}

Fail Ping Body

{
"exitCode": 1, // Optional: process exit code
"durationMs": 3200, // Optional: milliseconds
"output": "Error details..." // Optional: error output
}

Duration Calculation

Duration should be in milliseconds:

# Bash
START=$(date +%s)
# ... job runs ...
END=$(date +%s)
DURATION_MS=$(( (END - START) * 1000 ))

# Python
import time
start = time.time()
# ... job runs ...
duration_ms = int((time.time() - start) * 1000)

# Node.js
const start = Date.now();
// ... job runs ...
const durationMs = Date.now() - start;
Automatic duration with CLI

Use saturn run to automatically track duration:

saturn run --monitor YOUR_MONITOR_ID -- ./backup.sh

Exit Code Conventions

Saturn follows standard Unix exit code conventions:

Exit CodeMeaningAction
0SuccessSend success ping
1General errorSend fail ping
2Misuse of commandSend fail ping
126Command not executableSend fail ping
127Command not foundSend fail ping
130Terminated by Ctrl+CSend fail ping
143Terminated by SIGTERMSend fail ping

Capture the actual exit code for debugging:

./backup.sh
EXIT_CODE=$?

if [ $EXIT_CODE -eq 0 ]; then
# success ping
else
curl ... -d "{\"exitCode\": $EXIT_CODE}"
fi

Output Capture

Output is stored in MinIO/S3 and displayed in the dashboard.

Size Limits

Default: 10 KB per ping

Configure per monitor in settings or during creation:

{
"name": "Large Output Job",
"maxOutputSizeKb": 50
}

Redaction

Saturn automatically redacts sensitive patterns:

  • Passwords: password=secret123password=***REDACTED***
  • API keys: api_key: abc123def456api_key: ***REDACTED***
  • Bearer tokens: Bearer eyJ0eXAi...Bearer ***REDACTED***
  • AWS credentials: AWS_SECRET_ACCESS_KEY=...AWS_SECRET_ACCESS_KEY=***REDACTED***
  • Private keys: -----BEGIN PRIVATE KEY-----***REDACTED***

See Security/Redaction for full list.

Best Practices

Do:

  • Include relevant context (file counts, sizes, errors)
  • Keep output concise (summary, not full logs)
  • Use structured output (JSON) for parsing

Don't:

  • Send binary data
  • Include full stack traces (summarize instead)
  • Log sensitive data without redaction

Authentication

curl -X POST https://api.saturnmonitor.com/api/ping/YOUR_MONITOR_ID/success \
-H "Authorization: Bearer YOUR_TOKEN"

Method 2: Query Parameter

curl -X POST "https://api.saturnmonitor.com/api/ping/YOUR_MONITOR_ID/success?token=YOUR_TOKEN"
Security

Use Authorization header in production. Query parameters are logged by proxies and servers.

Rate Limiting

Limit: 60 requests per minute per monitor

If exceeded, you'll receive:

HTTP/1.1 429 Too Many Requests
Retry-After: 30

{"error": "Rate limit exceeded"}

Mitigation:

  • Don't send pings more frequently than your monitor's schedule
  • Use start ping only for long-running jobs
  • Batch multiple job runs if possible

Response Codes

CodeMeaningAction
200Ping acceptedContinue
401Invalid tokenCheck authorization
404Monitor not foundVerify monitor ID
422Invalid payloadCheck JSON format
429Rate limit exceededWait and retry
500Server errorRetry with exponential backoff

Idempotency

Pings are not idempotent — each ping creates a new run record.

If you accidentally send duplicate pings:

  • Multiple success pings → Creates multiple "successful runs"
  • Multiple start pings → Ignored (only first counts)

Next Steps