Appearance
Scheduling Guide
Krafter Cron Jobs supports two scheduling modes: cron expressions for precise control and interval presets for common cadences. This guide covers both modes, timezone handling, and retry logic.
Cron Expressions
Set schedule_type to "cron" and provide a standard 5-field cron expression in the schedule field.
Cron Syntax
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, Sunday=0)
│ │ │ │ │
* * * * *Each field supports:
- Specific values --
5(only at 5) - Ranges --
1-5(1 through 5) - Lists --
1,3,5(1, 3, and 5) - Steps --
*/15(every 15 units) - Wildcards --
*(every unit)
Common Cron Patterns
| Pattern | Expression | Description |
|---|---|---|
| Every minute | * * * * * | Runs once per minute |
| Every 5 minutes | */5 * * * * | Runs at :00, :05, :10, ... |
| Every hour | 0 * * * * | Runs at the top of every hour |
| Every 6 hours | 0 */6 * * * | Runs at 00:00, 06:00, 12:00, 18:00 |
| Daily at midnight | 0 0 * * * | Runs once per day at 00:00 |
| Daily at 9 AM | 0 9 * * * | Runs once per day at 09:00 |
| Weekly on Monday | 0 0 * * 1 | Runs every Monday at 00:00 |
| Monthly on the 1st | 0 0 1 * * | Runs on the 1st of every month at 00:00 |
| Weekdays at noon | 0 12 * * 1-5 | Runs Monday--Friday at 12:00 |
Example: Create a Cron Job
bash
curl -X POST https://app.krafter.dev/api/v1/cron/jobs \
-H "Authorization: Bearer kr_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"name": "Nightly Report",
"schedule_type": "cron",
"schedule": "0 0 * * *",
"timezone": "Europe/Berlin",
"url": "https://example.com/api/reports/generate",
"method": "POST"
}'This job runs daily at midnight in the Europe/Berlin timezone.
Interval Presets
Set schedule_type to "interval" for simple recurring schedules without writing cron expressions.
Available Intervals
| Preset | Description |
|---|---|
every_30s | Every 30 seconds |
every_1m | Every 1 minute |
every_5m | Every 5 minutes |
every_15m | Every 15 minutes |
every_30m | Every 30 minutes |
every_1h | Every 1 hour |
every_6h | Every 6 hours |
every_12h | Every 12 hours |
every_1d | Every 24 hours |
Example: Create an Interval Job
bash
curl -X POST https://app.krafter.dev/api/v1/cron/jobs \
-H "Authorization: Bearer kr_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"name": "Cache Warm",
"schedule_type": "interval",
"schedule": "every_15m",
"url": "https://example.com/api/cache/warm",
"method": "POST"
}'TIP
Interval presets are ideal for high-frequency jobs (sub-minute to hourly). For jobs that need to run at specific times of day, use cron expressions instead.
One-Time Schedules
Set schedule_type to "once" and provide an ISO-8601 datetime in the schedule field. The job fires exactly once at that moment, then auto-disables (enabled becomes false, next_run_at becomes null).
A one-shot job gets the same retries as any other: next_run_at is cleared as soon as the first attempt starts, so the scheduler will not fire it a second time, but enabled stays true until the run settles — a failing one-shot job exhausts max_retries before it is marked spent.
bash
curl -X POST https://app.krafter.dev/api/v1/cron/jobs \
-H "Authorization: Bearer kr_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"name": "Migration Trigger",
"schedule_type": "once",
"schedule": "2026-05-15T18:00:00Z",
"url": "https://example.com/api/run-migration",
"method": "POST"
}'INFO
The timezone field is ignored for once schedules — the schedule string must include its own UTC offset (or trailing Z).
Timezone Handling
By default, all jobs run in UTC. You can set the timezone field to any IANA timezone identifier when creating or updating a job.
json
{
"schedule_type": "cron",
"schedule": "0 9 * * 1-5",
"timezone": "America/New_York"
}This job runs every weekday at 9:00 AM Eastern Time. Krafter automatically adjusts for daylight saving time transitions.
Common Timezones
| Timezone | UTC Offset (standard) |
|---|---|
UTC | +00:00 |
America/New_York | -05:00 |
America/Chicago | -06:00 |
America/Los_Angeles | -08:00 |
Europe/London | +00:00 |
Europe/Berlin | +01:00 |
Asia/Tokyo | +09:00 |
Australia/Sydney | +11:00 |
INFO
The timezone field only affects cron schedules. An interval job's next run is simply "now plus the interval", and a once schedule carries its own offset — in both cases the timezone is ignored.
How next_run_at Is Calculated
When a job is created or finishes executing, Krafter calculates the next run time:
- Cron jobs -- The next matching time according to the cron expression and timezone.
- Interval jobs -- The current time plus the interval duration.
The next_run_at field is always returned in UTC, regardless of the job's timezone setting. Pausing leaves it alone, but resuming recalculates it from the schedule — a job paused on Monday and resumed on Friday still carried Monday's next_run_at, which is in the past, and would have fired within the minute. Resuming a job never causes an immediate catch-up run.
Retry Logic
When a job execution fails (non-2xx status, timeout, or connection error), Krafter retries it with linear backoff: 15 seconds, 30 seconds, 45 seconds, and so on at 15 seconds per attempt. Each attempt is recorded as a separate entry in the execution history with an incrementing attempt number.
How many times it retries is up to max_retries: a job gets max_retries + 1 attempts in total, so the default of 3 means four attempts and 0 means one attempt and no retry.
| Field | Default | Description |
|---|---|---|
timeout_ms | 30000 | Receive timeout: maximum time waiting for the target endpoint to respond (in milliseconds). Valid range is 1 to 300000 (5 minutes hard cap). |
max_retries | 3 | Retries after a failed attempt, 0--10. Total attempts are max_retries + 1. |
INFO
The TCP connect timeout is fixed at 5 seconds and is not configurable. timeout_ms only governs how long Krafter waits for a response after the connection is established.
Example: Configure Timeout
bash
curl -X POST https://app.krafter.dev/api/v1/cron/jobs \
-H "Authorization: Bearer kr_live_abc123def456" \
-H "Content-Type: application/json" \
-d '{
"name": "Payment Sync",
"schedule_type": "cron",
"schedule": "*/30 * * * *",
"url": "https://example.com/api/payments/sync",
"method": "POST",
"timeout_ms": 60000
}'This job runs every 30 minutes and waits up to 60 seconds for a response. On failure it is retried according to its own max_retries (here the default: four attempts, with 15s/30s/45s backoff).
Redirects
Krafter does not follow redirects. A 3xx answer is recorded as a failed execution with the returned status in http_status.
This is deliberate. Krafter resolves your job's hostname and pins the request to the address it validated, so the call cannot be diverted to a private or internal address after the fact. Following a Location: header would hand that decision back to the endpoint and undo the check. If your URL redirects, point the job at the final URL instead.
Failure Notifications
Set failure_notify to true and Krafter emails the team owner when a job fails. The mail names the job, its URL and schedule, the number of attempts and the last error.
It is deliberately quiet:
- Once per run, not once per attempt. The mail is sent only after the retries are spent, so a job with
max_retries: 3produces one mail, not four. - Once per outage, not once per occurrence. It is sent on the transition into failure, so a job scheduled every minute that stays broken mails once — not once a minute. When the job succeeds again and later fails again, that is a new transition and you are told again.
The job stays scheduled either way; the mail is a heads-up, not a pause. You can also query the Executions API for entries with status: "failed".
Next Steps
- Jobs API -- Full CRUD and control endpoints
- Executions API -- Query execution history with status filtering