HTTP Integration
If you're not using the Node.js SDK — for example, from a shell script, Python job, or any other language — you can send pings directly over HTTP.
Base URL: https://api.crontify.com/api/v1
All ping endpoints require an X-API-Key header with your API key.
POST /ping/:monitorId/start
Signal that a job has started.
Headers
X-API-Key: ck_live_...
Response 200
{
"success": true,
"data": {
"received": true,
"monitorId": "clxxx...",
"runId": "clyyy...",
"status": "running",
"timestamp": "2025-01-01T09:00:00.000Z"
}
}
POST /ping/:monitorId/success
Signal that a job completed successfully.
Headers
X-API-Key: ck_live_...
Content-Type: application/json
Body (optional)
{
"meta": {
"rows_processed": 1523,
"emails_sent": 48
}
}
meta is a free-form object of numeric values. Fields are stored on the run record and evaluated against any alert rules you have configured. If a rule matches, a silent_failure alert fires even though the job succeeded.
Response 200
{
"success": true,
"data": {
"received": true,
"monitorId": "clxxx...",
"runId": "clyyy...",
"status": "success",
"timestamp": "2025-01-01T09:02:15.000Z"
}
}
POST /ping/:monitorId/fail
Signal that a job failed.
Headers
X-API-Key: ck_live_...
Content-Type: application/json
Body (optional)
{
"errorMessage": "Database connection timeout after 30s",
"meta": { "exit_code": 1 },
"logOutput": "Traceback (most recent call last):\n ..."
}
| Field | Type | Description |
|---|---|---|
errorMessage | string | Human-readable error message. Shown in alerts and on the run detail page. Max 500 chars. |
meta | object | Numeric metadata stored on the run record. |
logOutput | string | Full log output (stdout/stderr). Stored separately and never fetched in list queries. Truncated to 10,000 chars server-side. |
Response 200
{
"success": true,
"data": {
"received": true,
"monitorId": "clxxx...",
"runId": "clyyy...",
"status": "failed",
"timestamp": "2025-01-01T09:01:05.000Z"
}
}
GET /monitors/:monitorId/runs/:runId/log
Retrieve the log output attached to a specific run. Requires a user JWT (not an API key).
Response 200 — log present
{
"hasLog": true,
"content": "Error: Connection refused\n at ..."
}
Response 200 — no log
{
"hasLog": false,
"content": null
}
Error responses
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
404 | Monitor not found or does not belong to this API key's account |
429 | Rate limit exceeded — see your plan's minimum ping interval |
Rate limiting
Ping endpoints are rate-limited based on your plan's minimum interval. The free plan allows one ping per minute per monitor; paid plans allow more frequent pings. If you exceed the limit, you'll receive a 429 response with a message indicating how many seconds to wait.
Shell script example
#!/bin/bash
API_KEY="ck_live_..."
MONITOR_ID="clxxx..."
BASE_URL="https://api.crontify.com/api/v1"
# Signal start
curl -s -X POST "$BASE_URL/ping/$MONITOR_ID/start" \
-H "X-API-Key: $API_KEY"
# Run the job and capture output
JOB_OUTPUT=$(python3 /path/to/job.py 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
# Signal success with metadata
curl -s -X POST "$BASE_URL/ping/$MONITOR_ID/success" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d "{\"meta\": {\"exit_code\": 0}}"
else
# Signal failure with log output
ESCAPED_OUTPUT=$(echo "$JOB_OUTPUT" | python3 -c "import json,sys; print(json.dumps(sys.stdin.read()))")
curl -s -X POST "$BASE_URL/ping/$MONITOR_ID/fail" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d "{\"errorMessage\": \"Job exited with code $EXIT_CODE\", \"logOutput\": $ESCAPED_OUTPUT}"
fi