Bulk Sync API
Pre-register multiple monitors at once with the sync endpoint. Essential for framework integrations that auto-discover recurring jobs (Hangfire, Laravel, Celery).
What is Sync?
The sync endpoint allows you to register multiple monitors in a single API call. This is used by:
- Framework integrations: Hangfire, Quartz.NET, Laravel, Celery auto-discover jobs and sync them on app startup
- CI/CD pipelines: Register all scheduled jobs during deployment
- Dynamic job systems: Programmatically manage monitors based on configuration
Why Use Sync? Instead of waiting for jobs to execute and ping individually, sync makes all monitors visible in your dashboard immediately. Great UX for users expecting to see their jobs listed.
Endpoint
POST /api/sync
Content-Type: application/json
Authentication
Use any of the supported authentication methods (see Authentication docs). Basic Auth recommended:
curl -X POST -u YOUR_API_KEY: \
-H "Content-Type: application/json" \
https://cron.life/api/sync \
-d @monitors.json
Request Format
{
"source": "hangfire",
"monitors": [
{
"key": "daily-backup",
"name": "Daily Database Backup",
"schedule": "0 2 * * *",
"gracePeriod": 300
},
{
"key": "hourly-sync",
"name": "Hourly Data Sync",
"schedule": "0 * * * *",
"gracePeriod": 60
},
{
"key": "process-payments",
"name": "Process Payment Queue",
"schedule": "*/15 * * * *",
"gracePeriod": 120
}
]
}
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
source | string | Yes | Source identifier (e.g., "hangfire", "laravel", "celery", "manual") |
monitors | array | Yes | Array of monitor objects (max 100 per request) |
Monitor Object Fields
| Field | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Monitor key (lowercase, alphanumeric, hyphens, underscores) |
name | string | No | Human-readable name (auto-generated from key if not provided) |
schedule | string | Yes | Cron expression (5 or 6 fields, or special strings like @hourly) |
gracePeriod | integer | No | Grace period in seconds (default: 60) |
Response
Success Response (200 OK)
{
"status": "success",
"synced": 3,
"created": 2,
"updated": 1,
"errors": []
}
Response Fields
| Field | Description |
|---|---|
synced | Total monitors successfully synced |
created | Number of new monitors created |
updated | Number of existing monitors updated |
errors | Array of error objects for failed monitors |
Partial Success Response
If some monitors fail validation, sync continues for valid ones:
{
"status": "partial",
"synced": 2,
"created": 2,
"updated": 0,
"errors": [
{
"key": "invalid-job",
"error": "Invalid cron expression: '0 25 * * *' (hour must be 0-23)"
}
]
}
Code Examples
curl -X POST -u YOUR_API_KEY: \
-H "Content-Type: application/json" \
https://cron.life/api/sync \
-d '{
"source": "manual",
"monitors": [
{
"key": "backup-prod",
"name": "Production Backup",
"schedule": "0 2 * * *",
"gracePeriod": 300
}
]
}'
Idempotency
Sync is fully idempotent - safe to call multiple times:
- First call: Creates all monitors (e.g., 5 created, 0 updated)
- Subsequent calls: Updates existing monitors (e.g., 0 created, 5 updated)
- Changed schedules: Updates take effect immediately
- Removed monitors: Not deleted (manual deletion only)
Safe for App Startup: Framework integrations call sync on every app startup. This ensures monitors are always up-to-date with your job definitions, even after deploys or config changes.
Rate Limits
- Sync endpoint: 10 requests per minute per API key
- Max monitors per request: 100
- Recommended frequency: Once per app startup (not in a loop)
Need higher limits? Contact support@cronradar.com.
Best Practices
1. Use Descriptive Source IDs
Source IDs help you filter monitors in the dashboard:
"source": "hangfire-production" ✓ Good
"source": "hangfire-staging" ✓ Good
"source": "manual" ✓ Good
"source": "app" ✗ Too vague
2. Normalize Keys
Always convert job IDs to lowercase, replace spaces with hyphens:
// Good normalization
"Send Welcome Email" → "send-welcome-email"
"Backup_DB" → "backup-db"
"ProcessPayments" → "process-payments"
3. Generate Readable Names
If keys are machine-readable, provide human-friendly names:
{
"key": "send-welcome-email",
"name": "Send Welcome Email",
...
}
4. Call on App Startup
Framework integrations should call sync during application initialization:
// .NET Hangfire example
services.AddHangfire(config =>
{
config.UseStorage(...);
config.MonitorAll("api_key"); // Calls sync internally
});