A scheduled agent task sounds simple: pick a time, save an instruction, and expect the work to happen. But the moment an agent can act on a schedule, the important question is no longer just when it starts. It is what happens if the session is busy, an approval is needed, a tool call fails, or the invocation is delivered but the work never reaches a useful result.
OpenAI's new Scheduled Automations for the Agents API makes that distinction visible. An automation stores a schedule and sends a task to an agent session. Each attempt creates an invocation record. That is not the same contract as a traditional cron process that starts a command on a host and lets the command's supervisor report its exit status. The official documentation says delivery can wait while the target session is busy, a scheduled run does not interrupt an active turn, and the application still has to handle required actions.
That is the story worth paying attention to. Agent platforms are adding scheduling, but a schedule is only one link in a longer chain: trigger, delivery, session, tools, approval, side effect, and verification. If your system treats “invocation queued” as “task completed,” it can report success while useful work has not happened.
What OpenAI has actually added
The feature lets developers save a one-time or recurring automation for an agent session. A one-time run uses a future Unix timestamp. A recurring run uses a five-field cron expression and a time zone. The automation can start a new session or continue an existing one. An application can also enable an automations tool so an agent can create, list, update, pause, resume, or delete automations in its current session.
When a run is due, the Agents API creates an invocation, described as a record of an attempt to send a task to the target session. The invocation has fields such as status, session ID, source type, and scheduled time. A manual invocation can be triggered for testing, and its history can be inspected separately from scheduled runs.
Those are useful building blocks. They let an application delegate timing and scheduling state to the API rather than maintain every timer itself. But the language in the documentation matters: the service schedules and delivers work to a session. It does not promise that every scheduled task will finish successfully, that every requested tool action will be approved, or that a downstream system has accepted the result.
A schedule is not a completion guarantee
A conventional cron entry is often treated as a direct command launch: at a time, start a process. Even there, reliable operations require more than cron. The process can crash, the host can be down, and a second run can overlap the first. But the execution boundary is comparatively clear: a process began, and its exit status can be collected.
An agent automation has a different boundary. The schedule causes an invocation to be delivered to a session. The session then needs to become available, interpret instructions, decide whether to use tools, possibly request approval, and interact with external systems. The official docs explicitly note that if a session is working, delivery waits for it to become available. The scheduled run does not interrupt the active turn or provide a missing tool result or approval. The application must handle those requirements.
That means several states that sound like success are only intermediate states:
- The schedule is saved. This proves configuration exists, not that a run was delivered.
- The invocation is queued. This proves the attempt is waiting, not that the session acted.
- The invocation is completed. This is a delivery-history status, not necessarily proof that the intended external side effect occurred correctly.
- The agent produced a response. This does not establish that a database write, email, deployment, or ticket update was accepted and verified.
The practical lesson is not that the feature is unreliable. It is that the API's unit of scheduling is a task delivery to an agent, not a business outcome. Applications need to define their own completion condition.
Why the busy-session detail changes design
Suppose an agent reviews a queue every hour and updates a ticket when it finds a clear duplicate. If the same session is still handling the previous run when the next schedule fires, the new delivery waits. That may be correct for a conversation that must preserve context. It may be wrong for independent periodic checks where each run should start with a clean state.
The docs let the developer choose whether each run starts a new session or continues an existing conversation. That choice affects more than memory. A continuing session can carry prior state and context forward, but it can also accumulate stale assumptions or make diagnosis harder. A fresh session limits conversational carry-over, but it requires the task payload and application state to provide everything the run needs.
Neither option is automatically best. A report generator that runs once per day may benefit from a new session and a bounded snapshot of the day's data. A multi-step research workflow may need a continuing session because later work depends on earlier findings. In both cases, the application should identify the authoritative input for each run rather than relying on an agent's conversational memory as the only record.
The difference between “queued” and “done” belongs in your data model
When a scheduled agent affects another system, model the workflow as a state machine. For example, a task could move through scheduled, invocation_created, delivered, awaiting_approval, action_submitted, verified, or failed. The exact names are up to the application. The important part is not collapsing those states into a single boolean called success.
The Agents API invocation history can help answer whether delivery was attempted and which session received it. The application should record the business task ID, intended operation, schedule occurrence, and the external resource affected. When the agent submits a side effect, verify that effect by reading the target system back. A model's message saying “updated” is not a receipt from the database or issue tracker.
This also suggests a useful design rule: make actions idempotent where possible. If a scheduled task is retried, resumed, manually invoked, or delivered after a delay, the same logical task should not create duplicate invoices, send repeated notifications, or open multiple identical tickets. Include a stable operation key in the action layer and let the destination reject duplicate operations. The model can help decide what action to request; deterministic application code should enforce whether that action has already been applied.
Approval is a first-class workflow state
Scheduled work can create a false sense of autonomy. A task may be due at 2 a.m., but a particular operation may still need a human decision. The documentation says a schedule does not supply a missing approval. That is an important boundary, not a minor implementation detail.
Before scheduling an agent, classify its possible actions:
- Read-only work: gather data, summarize changes, or prepare a report.
- Reversible writes: label an item or create a draft that can be undone.
- High-impact writes: send external messages, change access, deploy software, issue refunds, or delete data.
The first category can often run unattended if access is properly scoped. The second should have a clear audit trail and undo path. The third should usually require an explicit authorization mechanism that is separate from the model's own judgment. A notification saying that the agent wants approval is not itself an approval workflow. The application needs to store who approved what, when, and against which version of the proposed action.
Observability should follow the whole chain
The API gives invocation records and allows developers to inspect status and session ID. That is a starting point for operations, not a complete monitoring plan. For each scheduled job, a team should be able to answer:
- Did the schedule produce the expected invocation?
- Was it queued, delivered, delayed, or blocked?
- Which session and configuration handled it?
- Did the agent request a tool, and did the tool call succeed?
- Was an approval required, and how long did the task wait?
- Did the target system reflect the intended change?
- Was the run duplicated, retried, paused, or manually triggered?
A randomized delay for recurring runs is another detail worth including in expectations. The docs say the service adds a small randomized delay to spread load, and a task can wait longer if its target session is busy. Therefore, a cron expression should be read as a schedule for initiating work, not as a promise that an action will happen at the exact second. If a business process has a hard deadline, implement deadline monitoring and escalation outside the agent prompt.
The same logic applies to pause, resume, and delete. Pausing or deleting an automation does not stop work already accepted by a session, and a delivery already in progress may still reach its session. An operator who needs to stop an active action must understand the separate cancellation path. “Schedule paused” and “work stopped” are not interchangeable operational states.
Where this fits, and where it does not
Scheduled Automations can be a good fit when an application already uses the Agents API and wants recurring or one-time agent work delivered into managed sessions. It offers a shared place to define a schedule, inspect invocations, and let an agent manage schedules when that tool is enabled.
It is not a drop-in replacement for every job system. If a task is deterministic and does not need reasoning, a normal scheduler and program may be simpler. If a workflow must meet a strict service-level objective, preserve durable retries, or coordinate transactions across services, those requirements still need explicit infrastructure. An agent's ability to interpret an instruction does not remove the need for queue semantics, deduplication, timeouts, access controls, and outcome verification.
The best mental model is a scheduler attached to an asynchronous agent-session delivery system. Treat the schedule as the trigger, the invocation as evidence of an attempt, and the verified external state as evidence of completion. The distinction keeps the feature useful without attributing guarantees the API does not claim.
A checklist before scheduling an agent
- Define what counts as completion in the external system, not in the agent's final message.
- Decide whether each run needs a fresh session or continuing context.
- Make repeated actions safe with idempotency keys or deduplication.
- Keep high-impact operations behind an approval process the application enforces.
- Monitor schedule time, invocation state, session delivery, tool results, and final state separately.
- Set a deadline and escalation path for busy sessions or missing approvals.
- Test pause, resume, deletion, and active-run cancellation behavior.
- Use a conventional scheduler for deterministic jobs that do not need an agent.
The feature is a meaningful step toward agents that can work without a person sending every prompt. But a saved schedule is not an autonomous worker, and a delivered instruction is not a completed task. The design question for developers is where to place the boundary between the agent's flexible reasoning and the application's deterministic guarantees.
I write about developer tools, AI systems, and backend engineering. Subscribe for more practical breakdowns of how these systems behave in production.
Have you put an agent on a schedule yet? What do you use as proof that the task actually finished?
Save the checklist before making a scheduled agent responsible for a real side effect.
Top comments (1)
In Household Manager, built with Laravel AI SDK, I use existing application records to decide whether scheduled work has run: meal timestamps, shopping-list rows, and maintenance logs. Bounded catch-up handles missed runs. This is not a general solution for verifying external side effects, but it avoids a separate tracking table for this application. Implementation notes: Household Manager