API reference
REST over HTTPS with JSON. Authenticate with an API key from Settings → API keys.
Authentication
Create a key in Settings → API keys. Keys start with cr_live_ and are shown once. Send the key in one of three ways:
Scopes
Read & write keys can do everything below. Read only keys can make GET and HEAD requests; anything else returns 403 with {"error": "This API key is read-only"}.
Requests and responses
Send JSON bodies with Content-Type: application/json. Single resources come back as {"data": {…}}, lists as {"data": […], "meta": {"total", "page", "per_page"}}. Errors are {"error": "…"}; validation errors add "errors": {"field": "message"} with status 422.
Resources are addressed by their token. Creating beyond your plan’s limit returns 403.
curl https://app.cronly.net/api/v1/heartbeats \
-H "Authorization: Bearer $CRONLY_API_KEY"List heartbeats
A heartbeat expects a ping from your job. If no ping arrives on schedule plus the grace period, it alerts.
curl https://app.cronly.net/api/v1/heartbeats \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"data": [
{
"id": 42,
"token": "Xq3n8LmA2pTz",
"name": "nightly-backup",
"interval_minutes": null,
"cron_expression": "0 3 * * *",
"timezone": "Europe/Berlin",
"grace_period_minutes": 15,
"status": "ok",
"last_ping_at": null,
"created_at": "2026-11-10 08:00:00"
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 20
}
}Create a heartbeat
A heartbeat expects a ping from your job. If no ping arrives on schedule plus the grace period, it alerts.
curl -X POST https://app.cronly.net/api/v1/heartbeats \
-H "Authorization: Bearer $CRONLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"nightly-backup","cron_expression":"0 3 * * *","timezone":"Europe/Berlin","grace_period_minutes":15}'{
"data": {
"id": 42,
"token": "Xq3n8LmA2pTz",
"name": "nightly-backup",
"interval_minutes": null,
"cron_expression": "0 3 * * *",
"timezone": "Europe/Berlin",
"grace_period_minutes": 15,
"status": "ok",
"last_ping_at": null,
"created_at": "2026-11-10 08:00:00"
}
}Get a heartbeat with its last 10 pings
curl https://app.cronly.net/api/v1/heartbeats/Xq3n8LmA2pTz \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"data": {
"id": 42,
"token": "Xq3n8LmA2pTz",
"name": "nightly-backup",
"interval_minutes": null,
"cron_expression": "0 3 * * *",
"timezone": "Europe/Berlin",
"grace_period_minutes": 15,
"status": "ok",
"last_ping_at": null,
"created_at": "2026-11-10 08:00:00",
"recent_pings": [
{
"id": 9012,
"heartbeat_id": 42,
"ip": "203.0.113.7",
"user_agent": "curl/8.5.0",
"payload": null,
"late_seconds": 0,
"created_at": "2026-11-10 03:00:04"
}
]
}
}Update a heartbeat
Send only the fields you want to change.
curl -X PUT https://app.cronly.net/api/v1/heartbeats/Xq3n8LmA2pTz \
-H "Authorization: Bearer $CRONLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"nightly-backup"}'{
"data": {
"id": 42,
"token": "Xq3n8LmA2pTz",
"name": "nightly-backup",
"interval_minutes": null,
"cron_expression": "0 3 * * *",
"timezone": "Europe/Berlin",
"grace_period_minutes": 15,
"status": "ok",
"last_ping_at": null,
"created_at": "2026-11-10 08:00:00"
}
}Delete a heartbeat and its pings
curl -X DELETE https://app.cronly.net/api/v1/heartbeats/Xq3n8LmA2pTz \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"message": "Deleted successfully"
}List webhook inboxes
An inbox captures every request sent to its URL and can forward each one to your own endpoint.
curl https://app.cronly.net/api/v1/webhooks \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"data": [
{
"id": 7,
"token": "KO3p1FluZcrQ",
"name": "stripe-events",
"forward_url": "https://api.example.com/stripe",
"auto_retry": 1,
"retry_count": 3,
"is_paused": 0,
"created_at": "2026-11-10 08:00:00"
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 20
}
}Create a webhook inbox
An inbox captures every request sent to its URL and can forward each one to your own endpoint.
curl -X POST https://app.cronly.net/api/v1/webhooks \
-H "Authorization: Bearer $CRONLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"stripe-events","forward_url":"https://api.example.com/stripe","auto_retry":true,"retry_count":3}'{
"data": {
"id": 7,
"token": "KO3p1FluZcrQ",
"name": "stripe-events",
"forward_url": "https://api.example.com/stripe",
"auto_retry": 1,
"retry_count": 3,
"is_paused": 0,
"created_at": "2026-11-10 08:00:00"
}
}Get a webhook inbox
curl https://app.cronly.net/api/v1/webhooks/KO3p1FluZcrQ \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"data": {
"id": 7,
"token": "KO3p1FluZcrQ",
"name": "stripe-events",
"forward_url": "https://api.example.com/stripe",
"auto_retry": 1,
"retry_count": 3,
"is_paused": 0,
"created_at": "2026-11-10 08:00:00"
}
}Update a webhook inbox
Send only the fields you want to change.
curl -X PUT https://app.cronly.net/api/v1/webhooks/KO3p1FluZcrQ \
-H "Authorization: Bearer $CRONLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"stripe-events"}'{
"data": {
"id": 7,
"token": "KO3p1FluZcrQ",
"name": "stripe-events",
"forward_url": "https://api.example.com/stripe",
"auto_retry": 1,
"retry_count": 3,
"is_paused": 0,
"created_at": "2026-11-10 08:00:00"
}
}Delete a webhook inbox
curl -X DELETE https://app.cronly.net/api/v1/webhooks/KO3p1FluZcrQ \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"message": "Deleted successfully"
}List captured requests, newest first
curl https://app.cronly.net/api/v1/webhooks/KO3p1FluZcrQ/logs \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"data": [
{
"id": 1203,
"method": "POST",
"headers": "{\"content-type\":\"application/json\"}",
"body": "{\"type\":\"invoice.paid\"}",
"query_params": "{}",
"source_ip": "3.18.12.63",
"forward_status": "success",
"forward_status_code": 200,
"forward_latency_ms": 184,
"created_at": "2026-11-10 08:02:11"
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 20
}
}List uptime monitors
HTTP, TCP, Ping and SMTP checks. A failure is re-checked before the monitor is marked down.
curl https://app.cronly.net/api/v1/uptime-monitors \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"data": [
{
"id": 19,
"token": "Cb8rmCq08bTw",
"name": "api",
"type": "http",
"target": "https://api.example.com/health",
"port": null,
"interval_minutes": 1,
"timeout_seconds": 10,
"expected_code": "200",
"keyword": null,
"status": "up",
"is_active": 1,
"last_check_at": "2026-11-10 08:04:00",
"uptime": {
"24h": 100,
"7d": 99.98,
"30d": 99.95
}
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 20
}
}Create an uptime monitor
HTTP, TCP, Ping and SMTP checks. A failure is re-checked before the monitor is marked down.
curl -X POST https://app.cronly.net/api/v1/uptime-monitors \
-H "Authorization: Bearer $CRONLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"api","type":"http","target":"https://api.example.com/health","interval_minutes":1,"expected_code":"200"}'{
"data": {
"id": 19,
"token": "Cb8rmCq08bTw",
"name": "api",
"type": "http",
"target": "https://api.example.com/health",
"port": null,
"interval_minutes": 1,
"timeout_seconds": 10,
"expected_code": "200",
"keyword": null,
"status": "up",
"is_active": 1,
"last_check_at": "2026-11-10 08:04:00",
"uptime": {
"24h": 100,
"7d": 99.98,
"30d": 99.95
}
}
}Get an uptime monitor with 24 h / 7 d / 30 d uptime
curl https://app.cronly.net/api/v1/uptime-monitors/Cb8rmCq08bTw \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"data": {
"id": 19,
"token": "Cb8rmCq08bTw",
"name": "api",
"type": "http",
"target": "https://api.example.com/health",
"port": null,
"interval_minutes": 1,
"timeout_seconds": 10,
"expected_code": "200",
"keyword": null,
"status": "up",
"is_active": 1,
"last_check_at": "2026-11-10 08:04:00",
"uptime": {
"24h": 100,
"7d": 99.98,
"30d": 99.95
}
}
}Update an uptime monitor
Send only the fields you want to change.
curl -X PUT https://app.cronly.net/api/v1/uptime-monitors/Cb8rmCq08bTw \
-H "Authorization: Bearer $CRONLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"api"}'{
"data": {
"id": 19,
"token": "Cb8rmCq08bTw",
"name": "api",
"type": "http",
"target": "https://api.example.com/health",
"port": null,
"interval_minutes": 1,
"timeout_seconds": 10,
"expected_code": "200",
"keyword": null,
"status": "up",
"is_active": 1,
"last_check_at": "2026-11-10 08:04:00",
"uptime": {
"24h": 100,
"7d": 99.98,
"30d": 99.95
}
}
}Delete an uptime monitor
curl -X DELETE https://app.cronly.net/api/v1/uptime-monitors/Cb8rmCq08bTw \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"message": "Deleted successfully"
}List SSL certificate monitors
Checked once a day. Reminders go out 30, 14, 7 and 1 days before expiry.
curl https://app.cronly.net/api/v1/ssl-monitors \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"data": [
{
"id": 11,
"token": "Tu9ru71XFzt4",
"name": "shop",
"domain": "shop.example.com",
"port": 443,
"status": "ok",
"is_valid": 1,
"issuer": "R11",
"expires_at": "2027-01-28 23:59:59",
"last_check_at": "2026-11-10 06:00:00"
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 20
}
}Create an SSL certificate monitor
Checked once a day. Reminders go out 30, 14, 7 and 1 days before expiry.
curl -X POST https://app.cronly.net/api/v1/ssl-monitors \
-H "Authorization: Bearer $CRONLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"shop","domain":"shop.example.com","port":443}'{
"data": {
"id": 11,
"token": "Tu9ru71XFzt4",
"name": "shop",
"domain": "shop.example.com",
"port": 443,
"status": "ok",
"is_valid": 1,
"issuer": "R11",
"expires_at": "2027-01-28 23:59:59",
"last_check_at": "2026-11-10 06:00:00"
}
}Get an SSL certificate monitor
curl https://app.cronly.net/api/v1/ssl-monitors/Tu9ru71XFzt4 \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"data": {
"id": 11,
"token": "Tu9ru71XFzt4",
"name": "shop",
"domain": "shop.example.com",
"port": 443,
"status": "ok",
"is_valid": 1,
"issuer": "R11",
"expires_at": "2027-01-28 23:59:59",
"last_check_at": "2026-11-10 06:00:00"
}
}Update an SSL certificate monitor
Send only the fields you want to change.
curl -X PUT https://app.cronly.net/api/v1/ssl-monitors/Tu9ru71XFzt4 \
-H "Authorization: Bearer $CRONLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"shop"}'{
"data": {
"id": 11,
"token": "Tu9ru71XFzt4",
"name": "shop",
"domain": "shop.example.com",
"port": 443,
"status": "ok",
"is_valid": 1,
"issuer": "R11",
"expires_at": "2027-01-28 23:59:59",
"last_check_at": "2026-11-10 06:00:00"
}
}Delete an SSL certificate monitor
curl -X DELETE https://app.cronly.net/api/v1/ssl-monitors/Tu9ru71XFzt4 \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"message": "Deleted successfully"
}List domain monitors
WHOIS is checked once a day. Reminders go out 30, 14, 7 and 1 days before the registration expires.
curl https://app.cronly.net/api/v1/domain-monitors \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"data": [
{
"id": 13,
"token": "8QMtCcBl3vV6",
"name": "example.com",
"domain": "example.com",
"status": "ok",
"registrar": "Example Registrar, Inc.",
"expires_at": "2027-08-13 04:00:00",
"last_check_at": "2026-11-10 06:00:00"
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 20
}
}Create a domain monitor
WHOIS is checked once a day. Reminders go out 30, 14, 7 and 1 days before the registration expires.
curl -X POST https://app.cronly.net/api/v1/domain-monitors \
-H "Authorization: Bearer $CRONLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"example.com","domain":"example.com"}'{
"data": {
"id": 13,
"token": "8QMtCcBl3vV6",
"name": "example.com",
"domain": "example.com",
"status": "ok",
"registrar": "Example Registrar, Inc.",
"expires_at": "2027-08-13 04:00:00",
"last_check_at": "2026-11-10 06:00:00"
}
}Get a domain monitor
curl https://app.cronly.net/api/v1/domain-monitors/8QMtCcBl3vV6 \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"data": {
"id": 13,
"token": "8QMtCcBl3vV6",
"name": "example.com",
"domain": "example.com",
"status": "ok",
"registrar": "Example Registrar, Inc.",
"expires_at": "2027-08-13 04:00:00",
"last_check_at": "2026-11-10 06:00:00"
}
}Update a domain monitor
Send only the fields you want to change.
curl -X PUT https://app.cronly.net/api/v1/domain-monitors/8QMtCcBl3vV6 \
-H "Authorization: Bearer $CRONLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"example.com"}'{
"data": {
"id": 13,
"token": "8QMtCcBl3vV6",
"name": "example.com",
"domain": "example.com",
"status": "ok",
"registrar": "Example Registrar, Inc.",
"expires_at": "2027-08-13 04:00:00",
"last_check_at": "2026-11-10 06:00:00"
}
}Delete a domain monitor
curl -X DELETE https://app.cronly.net/api/v1/domain-monitors/8QMtCcBl3vV6 \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"message": "Deleted successfully"
}List web crons
Cronly calls your URL on a schedule and checks the response.
curl https://app.cronly.net/api/v1/web-crons \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"data": [
{
"id": 5,
"token": "wQ2dE4rT6yU8",
"name": "warm-cache",
"url": "https://example.com/cron/warm",
"method": "POST",
"cron_expression": "*/15 * * * *",
"timezone": "UTC",
"status": "ok",
"is_active": 1,
"last_run_at": "2026-11-10 08:00:00",
"next_run_at": "2026-11-10 08:15:00"
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 20
}
}Create a web cron
Cronly calls your URL on a schedule and checks the response.
curl -X POST https://app.cronly.net/api/v1/web-crons \
-H "Authorization: Bearer $CRONLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"warm-cache","url":"https://example.com/cron/warm","method":"POST","cron_expression":"*/15 * * * *","success_http_codes":"200-299"}'{
"data": {
"id": 5,
"token": "wQ2dE4rT6yU8",
"name": "warm-cache",
"url": "https://example.com/cron/warm",
"method": "POST",
"cron_expression": "*/15 * * * *",
"timezone": "UTC",
"status": "ok",
"is_active": 1,
"last_run_at": "2026-11-10 08:00:00",
"next_run_at": "2026-11-10 08:15:00"
}
}Get a web cron
curl https://app.cronly.net/api/v1/web-crons/wQ2dE4rT6yU8 \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"data": {
"id": 5,
"token": "wQ2dE4rT6yU8",
"name": "warm-cache",
"url": "https://example.com/cron/warm",
"method": "POST",
"cron_expression": "*/15 * * * *",
"timezone": "UTC",
"status": "ok",
"is_active": 1,
"last_run_at": "2026-11-10 08:00:00",
"next_run_at": "2026-11-10 08:15:00"
}
}Update a web cron
Send only the fields you want to change.
curl -X PUT https://app.cronly.net/api/v1/web-crons/wQ2dE4rT6yU8 \
-H "Authorization: Bearer $CRONLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"warm-cache"}'{
"data": {
"id": 5,
"token": "wQ2dE4rT6yU8",
"name": "warm-cache",
"url": "https://example.com/cron/warm",
"method": "POST",
"cron_expression": "*/15 * * * *",
"timezone": "UTC",
"status": "ok",
"is_active": 1,
"last_run_at": "2026-11-10 08:00:00",
"next_run_at": "2026-11-10 08:15:00"
}
}Delete a web cron
curl -X DELETE https://app.cronly.net/api/v1/web-crons/wQ2dE4rT6yU8 \
-H "Authorization: Bearer $CRONLY_API_KEY"{
"message": "Deleted successfully"
}Service health. No API key needed.
curl https://app.cronly.net/api/health{
"status": "ok",
"timestamp": 1762761600
}