API Documentation
CronMonitor provides a RESTful API for programmatic access to your monitors.
Base URL #
https://cronmonitor.io/api/v1
Authentication #
All API requests require authentication using an API token.
Getting Your API Token #
- Log in to your dashboard
- Go to Settings β API Tokens
- Click "Generate New Token"
- Copy and store the token securely
β οΈ Warning: Treat your API token like a password. Never commit it to version control.
Authentication Methods #
Bearer Token (Recommended) #
curl -H "Authorization: Bearer your-api-token" \
https://cronmonitor.io/api/v1/monitors
API Key Header #
curl -H "X-API-Key: your-api-token" \
https://cronmonitor.io/api/v1/monitors
Rate Limiting #
- Free Plan: 100 requests per hour
- Pro Plan: 1,000 requests per hour
- Business Plan: 10,000 requests per hour
Rate limit headers in responses:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1638360000
Endpoints #
List Monitors #
Get all monitors for your account.
GET /api/v1/monitors
Response:
{
"data": [
{
"id": "mon_abc123",
"name": "Daily Backup",
"schedule": "0 2 * * *",
"timezone": "Europe/Warsaw",
"grace_period": 300,
"status": "up",
"last_ping_at": "2025-12-01T02:00:15Z",
"next_expected_at": "2025-12-02T02:00:00Z",
"created_at": "2025-11-01T10:00:00Z"
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 50
}
}
Example:
curl -H "Authorization: Bearer your-api-token" \
https://cronmonitor.io/api/v1/monitors
Get Monitor Details #
GET /api/v1/monitors/{monitorId}
Response:
{
"data": {
"id": "mon_abc123",
"name": "Daily Backup",
"schedule": "0 2 * * *",
"timezone": "Europe/Warsaw",
"grace_period": 300,
"status": "up",
"ping_url": "https://cronmonitor.io/ping/abc123def456",
"last_ping_at": "2025-12-01T02:00:15Z",
"next_expected_at": "2025-12-02T02:00:00Z",
"ping_count": 30,
"failure_count": 0,
"created_at": "2025-11-01T10:00:00Z"
}
}
Example:
curl -H "Authorization: Bearer your-api-token" \
https://cronmonitor.io/api/v1/monitors/mon_abc123
Create Monitor #
POST /api/v1/monitors
Request Body:
{
"name": "Daily Backup",
"schedule": "0 2 * * *",
"timezone": "Europe/Warsaw",
"grace_period": 300,
"enabled": true
}
Response: 201 Created
{
"data": {
"id": "mon_abc123",
"name": "Daily Backup",
"schedule": "0 2 * * *",
"timezone": "Europe/Warsaw",
"grace_period": 300,
"status": "pending",
"ping_url": "https://cronmonitor.io/ping/abc123def456",
"created_at": "2025-12-01T22:00:00Z"
}
}
Examples:
cURL:
curl -X POST \
-H "Authorization: Bearer your-api-token" \
-H "Content-Type: application/json" \
-d '{
"name": "Daily Backup",
"schedule": "0 2 * * *",
"timezone": "Europe/Warsaw",
"grace_period": 300
}' \
https://cronmonitor.io/api/v1/monitors
PHP:
<?php
$ch = curl_init('https://cronmonitor.io/api/v1/monitors');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer your-api-token',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Daily Backup',
'schedule' => '0 2 * * *',
'timezone' => 'Europe/Warsaw',
'grace_period' => 300,
]),
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);
Python:
import requests
response = requests.post(
'https://cronmonitor.io/api/v1/monitors',
headers={'Authorization': 'Bearer your-api-token'},
json={
'name': 'Daily Backup',
'schedule': '0 2 * * *',
'timezone': 'Europe/Warsaw',
'grace_period': 300
}
)
data = response.json()
Update Monitor #
PATCH /api/v1/monitors/{monitorId}
Request Body:
{
"name": "Daily Backup (Updated)",
"grace_period": 600
}
Response: 200 OK
{
"data": {
"id": "mon_abc123",
"name": "Daily Backup (Updated)",
"schedule": "0 2 * * *",
"timezone": "Europe/Warsaw",
"grace_period": 600,
"updated_at": "2025-12-01T22:00:00Z"
}
}
Delete Monitor #
DELETE /api/v1/monitors/{monitorId}
Response: 204 No Content
Example:
curl -X DELETE \
-H "Authorization: Bearer your-api-token" \
https://cronmonitor.io/api/v1/monitors/mon_abc123
Pause Monitor #
POST /api/v1/monitors/{monitorId}/pause
Response: 200 OK
{
"data": {
"id": "mon_abc123",
"status": "paused",
"paused_at": "2025-12-01T22:00:00Z"
}
}
Resume Monitor #
POST /api/v1/monitors/{monitorId}/resume
Response: 200 OK
{
"data": {
"id": "mon_abc123",
"status": "up",
"resumed_at": "2025-12-01T22:00:00Z"
}
}
Get Ping History #
GET /api/v1/monitors/{monitorId}/pings
Query Parameters:
limit(optional): Number of pings to return (default: 50, max: 100)from(optional): Start date (ISO 8601)to(optional): End date (ISO 8601)
Response:
{
"data": [
{
"id": "ping_xyz789",
"pinged_at": "2025-12-01T02:00:15Z",
"status": "success",
"duration": 2.5,
"message": "Backup completed: 1.2GB",
"ip_address": "192.168.1.1"
}
],
"meta": {
"total": 100,
"page": 1,
"per_page": 50
}
}
Error Responses #
All errors follow this format:
{
"error": {
"code": "validation_error",
"message": "Invalid schedule format",
"details": {
"schedule": ["Must be a valid cron expression"]
}
}
}
Common Error Codes #
| Code | HTTP Status | Description |
|---|---|---|
unauthorized |
401 | Invalid or missing API token |
forbidden |
403 | Access denied |
not_found |
404 | Resource not found |
validation_error |
422 | Invalid input data |
rate_limit_exceeded |
429 | Too many requests |
server_error |
500 | Internal server error |
Webhooks #
Configure webhooks to receive notifications about monitor events.
Webhook Payload #
When a monitor fails:
{
"event": "monitor.failed",
"monitor": {
"id": "mon_abc123",
"name": "Daily Backup",
"schedule": "0 2 * * *",
"status": "down"
},
"last_ping_at": "2025-11-30T02:00:15Z",
"expected_at": "2025-12-01T02:00:00Z",
"failed_at": "2025-12-01T02:05:00Z",
"grace_period": 300
}
When a monitor recovers:
{
"event": "monitor.recovered",
"monitor": {
"id": "mon_abc123",
"name": "Daily Backup",
"status": "up"
},
"recovered_at": "2025-12-01T02:00:15Z",
"downtime_duration": 86400
}
Verifying Webhooks #
All webhooks include a signature header:
X-CronMonitor-Signature: sha256=abc123def456...
PHP Verification:
<?php
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_CRONMONITOR_SIGNATURE'];
$secret = 'your-webhook-secret';
$expectedSignature = 'sha256=' . hash_hmac('sha256', $payload, $secret);
if (!hash_equals($expectedSignature, $signature)) {
http_response_code(401);
exit('Invalid signature');
}
$data = json_decode($payload, true);
// Process webhook...
Complete SDK Example #
PHP SDK Wrapper #
<?php
class CronMonitorAPI
{
private string $apiToken;
private string $baseUrl = 'https://cronmonitor.io/api/v1';
public function __construct(string $apiToken)
{
$this->apiToken = $apiToken;
}
public function listMonitors(): array
{
return $this->request('GET', '/monitors');
}
public function getMonitor(string $id): array
{
return $this->request('GET', "/monitors/{$id}");
}
public function createMonitor(array $data): array
{
return $this->request('POST', '/monitors', $data);
}
public function updateMonitor(string $id, array $data): array
{
return $this->request('PATCH', "/monitors/{$id}", $data);
}
public function deleteMonitor(string $id): void
{
$this->request('DELETE', "/monitors/{$id}");
}
public function pauseMonitor(string $id): array
{
return $this->request('POST', "/monitors/{$id}/pause");
}
public function resumeMonitor(string $id): array
{
return $this->request('POST', "/monitors/{$id}/resume");
}
private function request(string $method, string $endpoint, ?array $data = null): array
{
$ch = curl_init($this->baseUrl . $endpoint);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $this->apiToken,
'Content-Type: application/json',
'Accept: application/json',
],
]);
if ($data !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 400) {
throw new Exception("API Error: {$response}");
}
return json_decode($response, true);
}
}
// Usage
$api = new CronMonitorAPI('your-api-token');
// List all monitors
$monitors = $api->listMonitors();
// Create new monitor
$monitor = $api->createMonitor([
'name' => 'Daily Backup',
'schedule' => '0 2 * * *',
'timezone' => 'Europe/Warsaw',
'grace_period' => 300,
]);
// Pause monitor
$api->pauseMonitor($monitor['data']['id']);
Video Tutorial #
πΊ Watch: "Using the CronMonitor API" (10 minutes)
API Tutorial
Video coming soon