Scheduled deployments
Create and manage deployments with the Claude API: run an agent on a recurring cron schedule and inspect its run history.
A scheduled deployment allows an agent to start sessions autonomously, so the agent can complete tasks on a predictable cadence. You create and manage deployments with the Deployments API, part of the Claude API.
For the launch context and examples of what teams run on schedules, see scheduled deployments and vaults in Claude Managed Agents on the blog.
Create a scheduled deployment
When creating a deployment, you pass the session configurations required for execution, in addition to a schedule.
- Deployments require agent configuration and environment configuration, and optionally accept files, GitHub, memory stores, and vaults. A deployment that targets a self-hosted environment can attach memory stores;
fileandgithub_repositoryresources require a cloud environment. The Claude Console deployment form does not currently offer memory stores for self-hosted environments; attach them through the API or the SDK instead. - Deployments also require at least one initial event, a
user.messageoruser.define_outcome, that starts each session’s work. In a deployment file forant apply, the text below the frontmatter becomes thatuser.message. - In the
schedule, you define a cronexpressionand atimezone. Maximum granularity supported is at the minute level.
ant apply deployment.md---
name: Weekly compliance scan
agent: agent_011CYm1BLqPXpQRk5khsSXrs
environment_id: env_01595EKxaaTTGwwY3kyXdtbs
schedule:
type: cron
expression: "0 20 * * 5"
timezone: America/New_York
---
Run the weekly compliance scan.ant apply prints the new deployment’s ID and records it in claude-lock.json. To see the deployment object, run ant beta:deployments retrieve.
The response includes a deployment object with a populated schedule.upcoming_runs_at with the next upcoming fire times, to confirm your schedule was set correctly.
{
"id": "depl_01xyz",
"status": "active",
"paused_reason": null,
"schedule": {
"type": "cron",
"expression": "0 20 * * 5",
"timezone": "America/New_York",
"last_run_at": null,
"upcoming_runs_at": [
"2026-05-09T00:00:00Z",
"2026-05-16T00:00:00Z",
"2026-05-23T00:00:00Z"
]
}
}The upcoming run timestamps reflect the exact schedule configured. However, to distribute load, actual execution applies jitter of up to 15 percent of the interval between runs, with a minimum of 5 seconds and a maximum of 9 minutes.
A maximum of 1,000 scheduled deployments is supported for each organization. Contact Anthropic support if you need more.
See the Create DeploymentPreview with links to the API reference available — press Tab until focus enters the card, Escape to return. reference for full parameters and response schema.
Cron and timezone semantics
- Expression: Standard POSIX cron (
minute hour day-of-month month day-of-week). You can generate and validate these cron expressions in the Claude Console. - Timezone: IANA timezone identifier (for example,
"America/Los_Angeles"). - DST: Cron schedules use literal wall-clock matching, so
"0 20 * * *"inAmerica/New_Yorkfires at 8:00 PM local time regardless of whether EST or EDT is in effect.
Set a budget on each run
Pass the optional budget object when you create or update the deployment. It takes the same shape as a session budget. The deployment copies the cap onto each session it starts, so the budget bounds every run separately rather than acting as a cumulative ceiling across runs: a deployment with a "2000" cap can spend up to about $20 USD on every run.
A session started by the deployment behaves exactly like any other budgeted session: it pauses with budget_reached when its own list cost reaches the cap. Changing the deployment’s budget applies to runs started afterward; a session already running keeps the cap it started with, which you can change through the session itself. Unlike a session budget, a deployment’s budget can be removed with budget=None and set again later.
The following example sets a budget on an existing deployment:
ant apply deployment.md---
name: Weekly compliance scan
agent: agent_011CYm1BLqPXpQRk5khsSXrs
environment_id: env_01595EKxaaTTGwwY3kyXdtbs
schedule:
type: cron
expression: "0 20 * * 5"
timezone: America/New_York
budget:
type: limit
max_list_cost:
amount: "2000"
currency: USD
---
Run the weekly compliance scan.Deployment runs
Deployments can fail to trigger for a variety of reasons: for example, if the environment resource has been archived, or if session creation is rate-limited. Each attempt generates a deployment run record, allowing you to track successes and failures independent of the session lifecycle.
Successful deployments generate active sessions, and a successful deployment run contains the associated session_id. To follow a session’s lifecycle, track the session events through the event stream or webhooks. Deployment lifecycle changes and the outcome of each scheduled run are also delivered as webhook events, listed in the Deployment events and Deployment run events tabs of Supported event types.
List all deployment runs for a deployment as follows:
for run in client.beta.deployment_runs.list(
deployment_id=deployment.id,
):
print(run.created_at, run.session_id or run.error.type)You can additionally filter on deployment runs with errors:
for run in client.beta.deployment_runs.list(
deployment_id=deployment.id,
has_error=True,
):
print(run.created_at, run.error.type, run.error.message)A failed run includes an error with a type describing why session creation was rejected (for example, environment_archived_error, agent_archived_error, or session_rate_limited_error). See the List Deployment RunsPreview with links to the API reference available — press Tab until focus enters the card, Escape to return. reference for all filter parameters and the response schema.
{
"type": "deployment_run",
"id": "drun_01abc124",
"deployment_id": "depl_01xyz",
"trigger_context": { "type": "schedule", "scheduled_at": "2026-05-09T00:00:00Z" },
"session_id": null,
"error": {
"type": "environment_archived_error",
"message": "environment `env_01abc` is archived"
},
"agent": { "type": "agent", "id": "agent_01ghi789", "version": 3 },
"created_at": "2026-05-09T00:00:01Z"
}To retrieve a single run by ID, call GET /v1/deployment_runs/{deployment_run_id}Preview with links to the API reference available — press Tab until focus enters the card, Escape to return.. A deployment_run webhook event carries the run ID as its data.id.
Managing deployment lifecycle
Each lifecycle change emits a webhook event, so you can react to a paused, unpaused, or archived deployment without polling; see the Deployment events tab.
Pause suppresses scheduled triggers from that point on; sessions already running from a prior deployment run continue. Manual runs through the run endpoint are still allowed while paused. Pausing sets paused_reason to {"type": "manual"}; unpausing clears it.
client.beta.deployments.pause(deployment.id)Unpause resumes the schedule from the next scheduled occurrence. Missed triggers are not backfilled.
client.beta.deployments.unpause(deployment.id)Archive, unlike pause, is terminal: the schedule ends and the deployment cannot be modified.
client.beta.deployments.archive(deployment.id)Failure behavior
Session creation rate-limit responses are recorded immediately as a session_rate_limited_error run without retry; the schedule attempts again at the next scheduled occurrence. Rate limits on underlying API calls within a session are handled by the session itself.
If a deployment’s agent is archived, the same operation archives the deployment. If the agent is deleted, the next scheduled trigger detects the missing agent and archives the deployment. Neither records a deployment run. If the agent references an archived subagent, the next trigger records a failed run with error.type: "agent_archived_error" and pauses the deployment. Other unrecoverable session-creation errors, such as an archived environment or vault, behave the same way: the trigger records a failed run and pauses the deployment. The deployment’s paused_reason.error.type mirrors the failed run’s error.type.
If a deployment is paused because the agent has an archived subagent:
- Remove or replace the archived subagent when you update the agentPreview with links to the API reference available — press Tab until focus enters the card, Escape to return..
- Move the deployment to the agent’s latest version: update the deploymentPreview with links to the API reference available — press Tab until focus enters the card, Escape to return. and pass the same agent ID again in
agent. A deployment runs one version of its agent and keeps it even when the agent changes. - Unpause the deployment, as Managing deployment lifecycle describes.
Trigger a manual run
To run a deployment outside its schedule, call the run endpointPreview with links to the API reference available — press Tab until focus enters the card, Escape to return.. This creates a session immediately and writes a deployment run with trigger_context.type: "manual". This allows you to test a deployment before committing to the schedule.
run = client.beta.deployments.run(deployment.id)Availability
Claude API
- Status
- Beta
- API
- Managed Agents
- Beta header
- Requires
- Models
- All models
Claude Platform on AWS
- Status
- Beta
- API
- Managed Agents
- Beta header
- Requires
- Models
- All models
Claude Models on Google Cloud (Anthropic managed)
- Status
- Beta
- API
- Managed Agents
- Beta header
- Requires
- Models
- All models
Data handling
Data handling overviewApplicable endpoints
/v1/agents/v1/sessions/v1/environments
Not eligible for ZDR, except for self-hosted Managed Agents. Sessions are stateful resources; transcripts persist until you delete them. Learn more
Not eligible for HIPAA. Applies to all Managed Agents sub-features.
Was this page helpful?