POST /v3/router/responses with model: agent/<key> — same execution path, same tracing, same billing — just fired by the scheduler rather than by a client request.
Use them for:
- Nightly briefings, hourly summaries, daily digests
- One-off follow-ups at a specific time
- Background agents that don’t need to be driven by user traffic
Schedule types
| Type | Expression | Example | Fires |
|---|---|---|---|
interval | @every <duration> | @every 6h | Every 6 hours after creation |
cron | 6-field cron (seconds required) | 0 0 9 * * mon-fri | 9:00:00 UTC Mon–Fri |
once | @at <RFC3339-UTC> | @at 2026-05-01T09:00:00Z | Exactly once at that moment |
@hourly, @daily, @weekly, @monthly, @yearly.
All timestamps are UTC. Expressions in any other timezone are rejected.
Quick start
Create an hourly schedule for an existing agent:schedule.<agent_key> leading span — identical structure to an HTTP-invoked agent run.
Payload
Thepayload object is what the agent receives on each firing. All fields are optional.
| Field | Type | Description |
|---|---|---|
input | string or array | Same shape as the Responses API input — text or items. |
variables | object | Template variable substitution. Supports secret values {"secret": true, "value": "..."}. |
memory_entity_id | string | Memory store entity to attach, see Memory. |
metadata | object | Opaque key/value pairs attached to every response generated by this schedule. |
agent_tag pins the schedule to a specific agent version. Omit it to always run the agent’s current active version.
CRUD
All endpoints are workspace-scoped via the API key. Each schedule belongs to exactly one agent (identified byagent_key in the URL).
Create
POST /v3/agents/{agent_key}/schedules
Required: type, expression, payload. Returns 201 Created with the stored schedule, or 400 for invalid expressions, 404 if the agent doesn’t exist.
List
GET /v3/agents/{agent_key}/schedules
Returns { "schedules": [...] }. Schedules are listed in creation order, most recent first.
Get
GET /v3/agents/{agent_key}/schedules/{schedule_id}
Returns the full schedule document, including trigger_count, last_triggered_at, and generation.
Update
PATCH /v3/agents/{agent_key}/schedules/{schedule_id}
Partial update. Any omitted field is left unchanged. Fields you can patch:
type,expression— changing either re-publishes the NATS schedule, bumpsgeneration, and resetstrigger_countto 0.is_active—falsestops future firings (NATS entry is removed);trueresumes or reactivates.agent_tag— change the pinned version.payload— update the input, variables, memory, or metadata.
agent_tag-only changes do not reset the firing cadence — they apply to the next regularly-scheduled run. Expression/type changes shift the cadence starting from the PATCH time.
Delete
DELETE /v3/agents/{agent_key}/schedules/{schedule_id}
Returns 204 No Content. Removes the schedule from NATS, the Mongo record, and the Redis cache in one call.
Trigger on demand
POST /v3/agents/{agent_key}/schedules/{schedule_id}/execution
Runs the schedule’s payload immediately (≈10 seconds after the request, to stay above the NATS scheduler’s minimum deliver-at margin). The schedule itself is unaffected — its regular cadence continues. Useful for:
- Smoke-testing a new schedule without waiting for its next firing
- Manually re-running a missed execution
- UI “Run now” buttons
202 Accepted with { "status": "triggered", "schedule_id": "..." }. Inactive schedules return 400.
Lifecycle semantics
is_active flips automatically for once schedules
After a once schedule fires, the scheduler records the trigger and sets is_active: false on the Mongo document. The record stays available via GET so you can inspect what ran and when. To re-run it, either create a new schedule or PATCH is_active: true with a fresh @at timestamp in the future.
Agent deletion cascades
Deleting an agent (DELETE /v2/agents/{agent_key}) asynchronously purges all schedules attached to it — from NATS, Mongo, and the Redis cache. You don’t need to clean up schedules before deleting the agent.
Inactive schedules don’t fire
Whenis_active is false, the NATS message is removed. Mongo fields (payload, expression) can still be updated while inactive; the values take effect on the next is_active: true transition.
Missed firings are not replayed
If the responses-api is down when a schedule would fire, that firing is lost. There’s no catch-up. Cron and interval schedules resume on the next scheduled time after the service is healthy.Observability
Every scheduled run emits:- A trace with a
schedule.<agent_key>leading span. The span carriesorq.schedule_id, the full agent execution chain as children, and the samegen_ai.*/openresponses.*attributes you get from HTTP-invoked runs. Searchable byschedule_idin the traces UI. - An entity event with action
triggeredwhen execution starts, then one ofcompleted,errored, orskippedwhen it ends.skippedcovers inactive schedules, stale generations (the schedule was updated between the trigger being published and consumed), and deleted agents. - Field updates on the schedule document:
last_triggered_at(UTC timestamp) andtrigger_count(monotonic counter, reset on expression/type change).
Worked examples
Daily morning digest (weekdays at 9am UTC)
Follow-up in 24 hours
Hourly background summarizer (minimum allowed cadence)
Scheduled run with secret variables
Update only the payload (cadence unchanged)
Deactivate and reactivate
List all schedules for an agent
Run now (smoke test or retry)
202 Accepted. The run appears in traces ~10 seconds later as schedule.ops_digest. Regular cadence is unaffected.
Delete
204 No Content.
Error reference
| Status | Code | Cause |
|---|---|---|
| 400 | invalid_expression | Malformed cron, interval, or @at timestamp; or fires more often than once per hour. |
| 400 | invalid_request | Unknown type; missing required field. |
| 400 | schedule_inactive | POST /execution on an inactive schedule. |
| 404 | agent_not_found | agent_key (or agent_tag) doesn’t exist in the workspace. |
| 404 | schedule_not_found | Schedule ID doesn’t exist, or belongs to a different agent. |
Limits
- Minimum firing interval: 1 hour (interval + cron).
onceschedules have no minimum. - Maximum schedules per agent: unlimited.
- Maximum payload size: same as the Responses API request body (1 MB).