POST /api/crons
Create a recurring HTTP cron job. The job fires on the given cron expression and is immediately active unless you pass is_active: false.
Endpoint
POST /api/cronsAuthentication
Pass your API token as a Bearer token. Generate one from Settings > API.
Authorization: Bearer YOUR_API_TOKENRequest body
{ "name": "Health Check", "url": "https://api.yourapp.com/health", "method": "GET", "cron_expression": "*/5 * * * *", "timeout_seconds": 30, "alert_threshold": 3, "success_assertions": [ { "type": "status_code_equals", "value": "200" } ]}Parameters
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name for the cron job. Max 255 characters. |
url | string | Yes | The URL to send the HTTP request to. Must be a valid URL. Max 2,048 characters. |
cron_expression | string | Yes | Standard 5-field cron expression (e.g. */5 * * * *). Max 255 characters. Must be a valid cron expression. |
method | string | No | HTTP method: GET, POST, PUT, PATCH, DELETE. Defaults to POST. |
headers | object | No | Key-value pairs sent as request headers. |
payload | string | No | Raw string body sent with the request. |
callback_url | string | No | URL to receive a POST after each execution completes. Must be a valid URL. Max 2,048 characters. |
timeout_seconds | integer | No | Request timeout in seconds (1-300). Defaults to 30. |
alert_threshold | integer | No | Consecutive failures before a failure alert fires: 1, 2, or 3. |
success_assertions | array | No | Response conditions that must pass for the execution to be considered successful. Max 10 assertions. See Assertions. |
is_active | boolean | No | Whether the cron starts active. Defaults to true. |
Response
201 Created
{ "id": 42, "name": "Health Check", "cron_expression": "*/5 * * * *", "next_run_at": "2026-04-10T12:15:00+00:00", "is_active": true}| Field | Type | Description |
|---|---|---|
id | integer | ID of the created cron job |
name | string | Display name |
cron_expression | string | The cron expression |
next_run_at | string | null | ISO 8601 timestamp of the next scheduled run |
is_active | boolean | Whether the cron is currently active |
Error responses
401 Unauthorized — missing or invalid token
{ "error": "Missing authorization token" }422 Unprocessable Entity — validation error
{ "message": "A cron expression is required.", "errors": { "cron_expression": ["A cron expression is required."] }}Code examples
curl
curl -X POST https://app.recurohq.com/api/crons \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "API Health Check", "url": "https://api.yourapp.com/health", "method": "GET", "cron_expression": "*/5 * * * *", "alert_threshold": 3, "success_assertions": [ { "type": "status_code_equals", "value": "200" } ] }'PHP
$response = Http::withToken('YOUR_API_TOKEN') ->post('https://app.recurohq.com/api/crons', [ 'name' => 'API Health Check', 'url' => 'https://api.yourapp.com/health', 'method' => 'GET', 'cron_expression' => '*/5 * * * *', 'alert_threshold' => 3, 'success_assertions' => [ ['type' => 'status_code_equals', 'value' => '200'], ], ]);
$cron = $response->json();// $cron['id'], $cron['next_run_at'], $cron['is_active']Node.js
const response = await fetch('https://app.recurohq.com/api/crons', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'API Health Check', url: 'https://api.yourapp.com/health', method: 'GET', cron_expression: '*/5 * * * *', alert_threshold: 3, success_assertions: [ { type: 'status_code_equals', value: '200' }, ], }),});
const cron = await response.json();// cron.id, cron.next_run_at, cron.is_activePython
import requests
response = requests.post( 'https://app.recurohq.com/api/crons', headers={'Authorization': 'Bearer YOUR_API_TOKEN'}, json={ 'name': 'API Health Check', 'url': 'https://api.yourapp.com/health', 'method': 'GET', 'cron_expression': '*/5 * * * *', 'alert_threshold': 3, 'success_assertions': [ {'type': 'status_code_equals', 'value': '200'}, ], },)
cron = response.json()# cron['id'], cron['next_run_at'], cron['is_active']More examples
Nightly data sync with custom header
curl -X POST https://app.recurohq.com/api/crons \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Nightly Sync", "url": "https://warehouse.internal/sync", "method": "POST", "cron_expression": "0 2 * * *", "headers": { "X-Sync-Source": "recuro" }, "timeout_seconds": 120 }'Create inactive (paused) cron
curl -X POST https://app.recurohq.com/api/crons \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Weekly Report", "url": "https://reports.internal/generate", "cron_expression": "0 8 * * 1", "is_active": false }'With completion callback
curl -X POST https://app.recurohq.com/api/crons \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Payment Processor", "url": "https://api.yourapp.com/process-payments", "method": "POST", "cron_expression": "0 */6 * * *", "callback_url": "https://api.yourapp.com/recuro-callback", "timeout_seconds": 120 }'With multiple assertions
curl -X POST https://app.recurohq.com/api/crons \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Health Check with Assertions", "url": "https://api.yourapp.com/health", "method": "GET", "cron_expression": "*/5 * * * *", "alert_threshold": 3, "success_assertions": [ { "type": "status_code_equals", "value": "200" }, { "type": "body_contains", "value": "ok" }, { "type": "response_time_under_ms", "value": "5000" } ] }'Assertions
Success assertions let you define conditions that the HTTP response must satisfy for an execution to be considered successful. If any assertion fails, the execution is marked as failed with the reason assertion_failed.
Each assertion is an object with type and value:
| Type | Description | Example value |
|---|---|---|
status_code_equals | Response status code must equal this value | "200" |
status_code_in | Response status code must be one of these comma-separated values | "200,201,204" |
body_contains | Response body must contain this string | "ok" |
body_not_contains | Response body must not contain this string | "error" |
json_path_equals | A JSON path in the response must equal the given value (format: path=value) | "data.status=active" |
response_time_under_ms | Response time must be under this many milliseconds | "5000" |
You can add up to 10 assertions per cron job. All assertions must pass for the execution to succeed.
Next steps
- Schedule a Job (API) — Push one-off jobs to a queue
- Webhook Signing — Verify request authenticity
- Cron Schedules — Full concept reference