Skip to main content

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 ..."
}
FieldTypeDescription
errorMessagestringHuman-readable error message. Shown in alerts and on the run detail page. Max 500 chars.
metaobjectNumeric metadata stored on the run record.
logOutputstringFull 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

StatusMeaning
401Missing or invalid API key
404Monitor not found or does not belong to this API key's account
429Rate 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