Documentation Index
Fetch the complete documentation index at: https://docs.orq.ai/llms.txt
Use this file to discover all available pages before exploring further.
Agent Schedules execute an agent on a recurring cadence. A scheduled run is equivalent to calling 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
- Background agents that don’t need to be driven by user traffic
Scheduling constraints: read before writing expressions.Only cron schedules are supported. Cron expressions must satisfy two additional rules:
- Weekday field: single integer
0-6 or * for every day (0 = Sunday, 1 = Monday, …, 6 = Saturday). Names (mon) and ranges (1-5) are rejected.
- Top of the hour: seconds and minutes fields must both be
0. Expressions that fire at any other time are rejected.
- Day-of-month and month: must both be
*. Specific dates are not supported.
Violations return 400 invalid_expression.
Schedule type
Only cron is supported. The expression is a 6-field cron string (seconds field required):
Seconds and minutes must always be 0. Day-of-month and month must always be *. The weekday field must be a single integer 0-6, or * for every day.
| Expression | Fires |
|---|
0 0 9 * * 1 | Every Monday at 09:00 UTC |
0 0 3 * * 0 | Every Sunday at 03:00 UTC |
0 0 9 * * * | Every day at 09:00 UTC |
All timestamps are UTC. Expressions in any other timezone are rejected.
Quick start
Create a daily schedule that runs at 09:00 UTC:
curl -X POST https://api.orq.ai/v3/agents/customer_digest/schedules \
-H "Authorization: Bearer $ORQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "cron",
"expression": "0 0 9 * * *",
"payload": {
"input": "Summarize new tickets from the last 24 hours"
}
}'
Response:
{
"_id": "01KPN29WWKSK0VDPJNTKZPVNRB",
"workspace_id": "...",
"agent_key": "customer_digest",
"type": "cron",
"expression": "0 0 9 * * *",
"is_active": true,
"generation": 1,
"payload": { "input": "Summarize new tickets from the last 24 hours" },
"trigger_count": 0,
"created": "2026-04-20T10:00:00Z",
"updated": "2026-04-20T10:00:00Z"
}
The agent runs every day at 09:00 UTC with the provided input. Each run appears in traces as a schedule.<agent_key> leading span, identical in structure to an HTTP-invoked agent run.
Payload
The payload 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. |
{
"type": "cron",
"expression": "0 0 9 * * *",
"agent_tag": "v2",
"payload": {
"input": "Generate the morning briefing for {{region}}",
"variables": { "region": "EMEA" },
"memory_entity_id": "mem_entity_123",
"metadata": { "run_source": "daily-briefing" }
}
}
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 by agent_key in the URL).
Create
POST /v3/agents/{agent_key}/schedules
Required: type, expression, payload. Optional: display_name (label shown in the UI Schedules tab), agent_tag. 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. Patchable fields:
type, expression: changing either reschedules the job, bumps generation, and resets trigger_count to 0.
is_active: false stops future firings; true resumes or reactivates.
agent_tag: change the pinned version.
payload: update the input, variables, memory, or metadata.
Payload-only and 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. Permanently removes the schedule in a single call.
Trigger on demand
POST /v3/agents/{agent_key}/schedules/{schedule_id}/execution
Runs the schedule’s payload immediately (approximately 10 seconds after the request, the minimum dispatch 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
Returns 202 Accepted with { "status": "triggered", "schedule_id": "..." }. Inactive schedules return 400.
Lifecycle semantics
Inactive schedules don’t fire
When is_active is false, the schedule stops firing entirely. Fields (payload, expression) can still be patched while inactive; the new values take effect on the next is_active: true transition.
Agent deletion cascades
Deleting an agent (DELETE /v2/agents/{agent_key}) asynchronously removes all schedules attached to it. Schedules do not need to be cleaned up before deleting the agent.
Missed firings are not replayed
If Orq.ai is unavailable when a schedule would fire, that firing is lost. There is no catch-up. Schedules resume on their next scheduled time once service is restored.
Observability
Every scheduled run emits:
- A trace with a
schedule.<agent_key> leading span. The span carries orq.schedule_id, the full agent execution chain as children, and the same gen_ai.* / openresponses.* attributes present on HTTP-invoked runs. Searchable by schedule_id in the traces UI.
- An entity event with action
triggered when execution starts, then one of completed, errored, or skipped when it ends. skipped covers 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) and trigger_count (monotonic counter, reset on expression/type change).
Cost, tokens, and model are attached to the leading span the same way they appear for HTTP runs, so schedule-driven spend shows up in usage reports automatically.
Worked examples
Daily morning briefing at 09:00 UTC
curl -X POST https://api.orq.ai/v3/agents/ops_digest/schedules \
-H "Authorization: Bearer $ORQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "cron",
"expression": "0 0 9 * * *",
"agent_tag": "v2",
"payload": {
"input": "Generate the morning briefing for {{region}}",
"variables": { "region": "EMEA" },
"metadata": { "run_source": "daily-briefing" }
}
}'
Daily sync at 03:00 UTC with secret variables
curl -X POST https://api.orq.ai/v3/agents/daily_sync/schedules \
-H "Authorization: Bearer $ORQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "cron",
"expression": "0 0 3 * * *",
"payload": {
"input": "Sync new rows from {{table}} to the analytics warehouse",
"variables": {
"table": "orders",
"warehouse_token": { "secret": true, "value": "sk-secret-123" }
}
}
}'
Secrets are redacted from traces and stripped from the stored payload’s observable form, same as the Responses API.
Update only the payload (cadence unchanged)
curl -X PATCH https://api.orq.ai/v3/agents/ops_digest/schedules/01KPN29WWKSK0VDPJNTKZPVNRB \
-H "Authorization: Bearer $ORQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"payload": {
"input": "Generate the morning briefing for {{region}}, include active incidents",
"variables": { "region": "EMEA" }
}
}'
Deactivate and reactivate
# Stop future firings; the record is preserved but will not fire.
curl -X PATCH https://api.orq.ai/v3/agents/ops_digest/schedules/01KPN29WWKSK0VDPJNTKZPVNRB \
-H "Authorization: Bearer $ORQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "is_active": false }'
# Resume with the current (possibly-updated) values.
curl -X PATCH https://api.orq.ai/v3/agents/ops_digest/schedules/01KPN29WWKSK0VDPJNTKZPVNRB \
-H "Authorization: Bearer $ORQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "is_active": true }'
List all schedules for an agent
curl https://api.orq.ai/v3/agents/ops_digest/schedules \
-H "Authorization: Bearer $ORQ_API_KEY"
{
"schedules": [
{
"_id": "01KPN29WWKSK0VDPJNTKZPVNRB",
"type": "cron",
"expression": "0 0 9 * * 1",
"is_active": true,
"trigger_count": 12,
"last_triggered_at": "2026-04-20T09:00:02Z"
}
]
}
Run now (smoke test or retry)
curl -X POST https://api.orq.ai/v3/agents/ops_digest/schedules/01KPN29WWKSK0VDPJNTKZPVNRB/execution \
-H "Authorization: Bearer $ORQ_API_KEY"
Returns 202 Accepted. The run appears in traces approximately 10 seconds later as schedule.ops_digest. Regular cadence is unaffected.
Delete
curl -X DELETE https://api.orq.ai/v3/agents/ops_digest/schedules/01KPN29WWKSK0VDPJNTKZPVNRB \
-H "Authorization: Bearer $ORQ_API_KEY"
Returns 204 No Content.
Error reference
| Status | Code | Cause |
|---|
| 400 | invalid_expression | Malformed cron expression; weekday is not a single integer 0-6 or *; seconds or minutes are not 0; or fires more often than once per hour. |
| 400 | invalid_request | Unsupported type (only cron is accepted); 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. Expressions that would fire more frequently are rejected.
- Weekday field: single integer 0-6 or
*. Names and ranges are not accepted.
- Firing time: must be at the top of the hour. Seconds and minutes must both be
0.
- Day-of-month and month: must both be
*. Specific dates are not supported.
- Maximum schedules per agent: unlimited.
- Maximum payload size: same as the Responses API request body (1 MB).