Skip to content

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/crons

Authentication

Pass your API token as a Bearer token. Generate one from Settings > API.

Authorization: Bearer YOUR_API_TOKEN

Request 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

FieldTypeRequiredDescription
namestringYesDisplay name for the cron job. Max 255 characters.
urlstringYesThe URL to send the HTTP request to. Must be a valid URL. Max 2,048 characters.
cron_expressionstringYesStandard 5-field cron expression (e.g. */5 * * * *). Max 255 characters. Must be a valid cron expression.
methodstringNoHTTP method: GET, POST, PUT, PATCH, DELETE. Defaults to POST.
headersobjectNoKey-value pairs sent as request headers.
payloadstringNoRaw string body sent with the request.
callback_urlstringNoURL to receive a POST after each execution completes. Must be a valid URL. Max 2,048 characters.
timeout_secondsintegerNoRequest timeout in seconds (1-300). Defaults to 30.
alert_thresholdintegerNoConsecutive failures before a failure alert fires: 1, 2, or 3.
success_assertionsarrayNoResponse conditions that must pass for the execution to be considered successful. Max 10 assertions. See Assertions.
is_activebooleanNoWhether 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
}
FieldTypeDescription
idintegerID of the created cron job
namestringDisplay name
cron_expressionstringThe cron expression
next_run_atstring | nullISO 8601 timestamp of the next scheduled run
is_activebooleanWhether 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

Terminal window
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_active

Python

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

Terminal window
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

Terminal window
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

Terminal window
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

Terminal window
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:

TypeDescriptionExample value
status_code_equalsResponse status code must equal this value"200"
status_code_inResponse status code must be one of these comma-separated values"200,201,204"
body_containsResponse body must contain this string"ok"
body_not_containsResponse body must not contain this string"error"
json_path_equalsA JSON path in the response must equal the given value (format: path=value)"data.status=active"
response_time_under_msResponse 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