Skip to main content
A cron is one sentence and a schedule: say this to my agent, every weekday at 9. Each firing sends the prompt to POST /v1/responses on that instance’s own gateway, on a fresh session, and the request wakes the instance on its way in. That last part is the reason to use this instead of the scheduler inside the agent. A crontab inside the container only runs while the container is running, so on an instance with auto-sleep it stops firing the moment the instance sleeps, and it keeps the instance awake for nothing when it doesn’t. A platform cron is outside the instance: it fires whether the instance is awake or asleep, and between firings the instance is free to sleep and cost you nothing but disk. Crons belong to an instance. Deleting the instance deletes its crons. agent37-n8n takes none: it serves a web app rather than an agent, so there is nothing to send a message to.

Create a cron

prompt and schedule are required.
string
required
What to say to the agent. The same thing you would send as input on POST /v1/responses, so it can be a whole standing instruction, not just a line. Up to 8,000 characters.
string
required
A five-field cron expression: minute, hour, day of month, month, day of week. 0 9 * * 1-5 is 9am on weekdays; */15 * * * * is every fifteen minutes; * * * * * is every minute. Ranges, lists, steps, and three-letter day and month names all work. There is no seconds field: a six-field expression is rejected.
string
default:"UTC"
An IANA timezone name, for example America/New_York. The schedule is read in this zone, so “9am” stays 9am across daylight saving.
string
A label for your own UI. Up to 80 characters.
boolean
default:"true"
false creates it paused. A paused cron has next_run: null and never fires.

The cron object

string
12-character hex id.
number | null
When it last fired, epoch seconds. null until it has.
number | null
When it fires next, epoch seconds. null while enabled is false.
number
Epoch seconds.

List, read, edit, delete

PATCH takes any of the create fields and changes only the keys you send. Changing schedule, timezone or enabled recomputes next_run from now, so a new schedule never replays a window that has already passed; editing only the prompt or the name leaves the next firing exactly where it was. Pausing is a PATCH:
Delete acts once: a repeat is 404. An instance holds at most 50 crons.

Run one now

POST /v1/instances/{id}/crons/{cronId}/run fires the cron immediately, whether or not it is enabled, without touching its schedule. It answers 202 with the run record as soon as the turn is sent.

Run history

GET /v1/instances/{id}/crons/{cronId}/runs returns the latest 50 firings, newest first.
string
triggered (the turn was started) or skipped (nothing was sent).
string | null
The session the firing opened. Read what the agent actually did with GET /v1/sessions/{session_id} on the instance URL. null on a skip, and on agent37-codex, agent37-grok and agent37-opencode, whose harnesses mint their own session ids.
string | null
Why it was skipped: instance_stopped, past_due, free_hours_exhausted, or wake_failed.
A cron is fire and forget. triggered means the turn was started, not that it succeeded. The agent’s answer, its tool calls, and any error live in the session, which is where you read them.

What fires, and what doesn’t

A sleeping instance is woken and the turn runs. An instance you stopped stays stopped: a schedule never undoes an explicit stop, and the firing is recorded as skipped with instance_stopped. The same goes for an instance suspended for non-payment (past_due). Each firing opens its own session, so a cron never interleaves with your chat thread and 15 crons never turn into 15 conversations in the same transcript. If a firing is still running when the next one is due, the next one starts its own session as usual. A window the platform misses (a schedule that came due while the instance was stopped, or a cron paused for a week and then re-enabled) is skipped, never backfilled.

Your agent can schedule itself

The agent running on the instance can create its own crons, with the agent37 cron CLI baked into every Agent37 agent image:
Also agent37 cron list, agent37 cron update <id> [--pause|--resume], agent37 cron remove <id> and agent37 cron runs <id>. The images tell the agent this exists, so “check my email every weekday at 9” is usually enough; no key is involved, since the CLI uses the credential the instance already holds. Anything it creates is an ordinary cron: it appears in GET /v1/instances/{id}/crons, and you can edit or delete it there like any other.

Cost

A cron costs nothing to hold. What it costs is what the turn costs: the compute minutes the instance is awake for, and the managed services the turn uses, exactly as if you had sent the message yourself. An instance with auto-sleep on, fired once an hour, is billed for the minutes it is actually working plus disk for the rest of the day.