Skip to content

Schedule agent runs

A schedule version binds a name, calendar, overlap policy and the exact request used to admit an agent run. Publication creates an immutable version. It does not enable execution. Schedule reads report execution_ready; enabling is refused while the execution service is unavailable. Availability does not establish that an installed worker has completed a scheduled run.

Prepare a run request with its exact agent version, input reference, output target, workload grants, budget and usage class. Test simulation, paid Test Compute and Live retain their normal authority and funding requirements. A calendar does not extend a grant, consent or content lifetime.

A scheduled run pays the way its budget pays: credits, or the wallet a budget is paid from. Each occurrence is admitted against the wallet like a run started by hand, so an occurrence is refused while the wallet owes its unpaid limit or has a failed collection. A schedule cannot pay its runs with x402, and cannot use a budget paid per run.

Each scheduled run reads the input as the person who enabled the schedule, so the agent needs no share or grant for it. Enabling checks that the person can read the input, and every occurrence checks it again. If they lose access to the input or leave the organization, a run already started stops reading it and later occurrences are refused.

Read the current environment before publication and include its expected_environment_epoch and expected_reset_generation. Choose a schedule UUID. Use expected_revision: 0 for its first version, or the current head revision when publishing a replacement. A replacement does not silently replace an enabled version.

The calendar requires both calendars and intervals arrays. Use [] for an unused family; null is invalid. Supply an exact IANA timezone name and canonical UTC start_at and end_at timestamps ending in Z. The bounds are inclusive. Local times are evaluated in the named timezone, including its daylight-saving transitions; your computer’s timezone does not determine occurrences.

Each calendar rule requires second, minute, hour, day_of_month, month and day_of_week ranges. year is optional and otherwise permits every year. A range has explicit integer start, end and step. Bounds are inclusive: seconds 0..59 with step 15 select 0, 15, 30 and 45. Weekdays use Sunday 0 through Saturday 6. Fields within a rule must all match; matching any rule selects an occurrence.

Ranges must be ordered, disjoint and within their field bounds. Each field allows at most 64 ranges. Calendar and interval rules together allow 1–32 entries. Interval rules specify every_seconds from 1 through 316,224,000 and offset_seconds from zero to less than the interval. They select UTC instants at epoch plus offset plus whole intervals, within the explicit time bounds. Duplicate rules are refused.

The policy selects skip, buffer_one, buffer_all or allow for overlapping occurrences. catchup_window_seconds must be 10–86,400; older missed occurrences are outside that window. Set pause_on_failure explicitly. Buffered work still needs valid authority when execution is attempted.

const scope = { org_id, environment_id };
const published = await client.schedules.publish(scope, {
schedule_id,
expected_revision: 0,
expected_environment_epoch: environment.authority_epoch,
expected_reset_generation: environment.reset_generation,
configuration: { name: "Daily review", calendar, policy, run },
}, publicationKey);
const record = await client.schedules.getVersion(scope, published.resource_id);

Python provides client.schedules.publish, get_version, get, list, set_enabled and retire. TypeScript uses getVersion and setEnabled for the corresponding operations. SDKs snapshot requests before asynchronous authentication and never retry these mutations automatically.

Schedule operations require synapse:schedules:write. Publication and reads accept an appropriately scoped key or human session. Enable, pause and retire require a human session. Enabling also requires execution_ready: true.

Review the exact version reference and activation generation before changing activation. Submit version, expected_generation, both environment preconditions and the explicit enabled boolean. Use generation zero when no activation exists. An enabled version can differ from the publication head: inspect activation.version before pausing it.

Retirement submits the same exact reference and generation preconditions without enabled. It permanently retires that schedule identity; it does not erase historical versions or receipts. Publishing another version cannot revive a retired schedule.

await client.schedules.setEnabled(scope, {
version: record.reference,
expected_generation: record.activation?.generation ?? 0,
expected_environment_epoch: environment.authority_epoch,
expected_reset_generation: environment.reset_generation,
enabled: true,
}, activationKey);

list accepts limit from 1–50, an optional after schedule UUID and include_retired. The default limit is 25. Continue with the returned next_cursor. get reads the current publication head; getVersion reads an exact immutable version.

Keep the reviewed request, selected account and environment, and caller-generated idempotency key until the outcome is known. If a response is lost, inspect current state and explicitly retry the same body and key only after confirming the same account and scope. Do not replace the key, rebuild the request from a newer head, or automatically enable after a recovered publication. A reset or revoked authority can refuse recovery; retain the uncertain request for investigation. A completed receipt confirms that operation, while current activation may have changed afterward.

Every record and directory entry includes runtime.state, runtime.generation, and an optional runtime.observed_at. The generation is the canonical activation generation, or zero without an activation. It can refer to an older version than the publication head. execution_ready reports whether both runtime workers started; it does not establish that this schedule is active.

Runtime stateMeaning
unconfiguredNo runtime profile is enrolled for the environment mode, even if activation metadata exists.
pendingThe controller has not established active execution for the requested generation.
activeThe controller reports the generation active; each occurrence still needs current admission authority.
pausedThe runtime is stopped, including a never-activated schedule at generation zero.
reviewAn enabled native schedule stopped or needs review. A new explicit activation generation is required; it does not resume automatically.
stoppingPause or retirement is recorded, but native cleanup remains pending.
errorThe controller could not establish the requested runtime state.

The optional observation time is the last controller check, including a failed attempt. It is not proof of successful execution. Inspect fresh metadata before a new explicit activation review. No occurrence preview is implied by these fields.