# Schedules
> Run a command in a sandbox at the times a cron line names, waking it when it sleeps.
A schedule runs a command in a sandbox at the times a cron line names, in UTC. It wakes the sandbox when it is asleep, like an [exec](https://nanite.run/docs/exec.md), and the sandbox goes back to sleep once the command is done and nothing else uses it.
## Add a schedule
```http
POST /v1/sandboxes/{name}/schedules
```
```json
{ "cron": "0 9 * * 1-5", "cmd": ["sh", "-c", "/srv/report >> /srv/report.log"] }
```
Answers `201` with the schedule:
```json
{
"id": "sch_7c491e237bc742dcb202",
"cron": "0 9 * * 1-5",
"cmd": ["sh", "-c", "/srv/report >> /srv/report.log"],
"next_run_at": "2026-11-02T09:00:00Z",
"last_run_at": null,
"last_result": null,
"created_at": "2026-11-01T08:12:40.118Z"
}
```
| Field | Type | About |
| ------------- | -------------- | ------------------------------------------------------------------- |
| `cron` | string | Five fields: minute, hour, day of month, month, day of week. UTC. |
| `cmd` | array | A command as exec takes it: 1 to 64 strings, at most 16 KiB in all. |
| `next_run_at` | string or null | When it runs next. `null` when the line names no time left. |
| `last_run_at` | string or null | When it last ran. |
| `last_result` | string or null | How the last run ended: `exit 0`, an error code, or `timed out`. |
Each field takes `*`, numbers, ranges such as `1-5`, steps such as `*/15`, and lists of them. Sunday is `0` or `7`. When both day of month and day of week are restricted, either one is enough, as in cron.
## List and remove
```http
GET /v1/sandboxes/{name}/schedules
DELETE /v1/sandboxes/{name}/schedules/{id}
```
The list answers `{ "schedules": [...] }`. A remove answers `204`, or `404 schedule_not_found`. Deleting a sandbox removes its schedules.
## How a run goes
- Runs start within the minute they are due, and a run is never repeated.
- The command runs as an exec with no stdin. Its output is not kept, so write what you need to a file.
- `last_result` is `timed out` when the command is still going after 60 seconds. It keeps running in the sandbox.
- A run that cannot start records why in `last_result`, such as `insufficient_credits`, `concurrent_sandbox_limit_exceeded` or `sandbox_held`, and the schedule moves on to its next time.
## Limits
| What | Limit | Refusal |
| ----------------------- | ------------- | ----------------------------- |
| Schedules per sandbox | 20 | `409 schedule_limit_exceeded` |
| How often one runs | Once a minute | |
| Time before `timed out` | 60 seconds | |
Run a command in a sandbox at the times a cron line names, waking it when it sleeps.
A schedule runs a command in a sandbox at the times a cron line names, in UTC. It wakes the sandbox when it is asleep, like an exec, and the sandbox goes back to sleep once the command is done and nothing else uses it.
Five fields: minute, hour, day of month, month, day of week. UTC.
cmd
array
A command as exec takes it: 1 to 64 strings, at most 16 KiB in all.
next_run_at
string or null
When it runs next. null when the line names no time left.
last_run_at
string or null
When it last ran.
last_result
string or null
How the last run ended: exit 0, an error code, or timed out.
Each field takes *, numbers, ranges such as 1-5, steps such as */15, and lists of them. Sunday is 0 or 7. When both day of month and day of week are restricted, either one is enough, as in cron.
Runs start within the minute they are due, and a run is never repeated.
The command runs as an exec with no stdin. Its output is not kept, so write what you need to a file.
last_result is timed out when the command is still going after 60 seconds. It keeps running in the sandbox.
A run that cannot start records why in last_result, such as insufficient_credits, concurrent_sandbox_limit_exceeded or sandbox_held, and the schedule moves on to its next time.