# Schedules

> Define when cloud resources start and stop using cron expressions. Timezone-aware, supports individual resource and resource group attachments.

Source: https://zop.dev/developer-docs/core-concepts/schedules

---

Schedules define when cloud resources should be automatically started or stopped using cron expressions.

## How Scheduling Works

1. Create a schedule with one or more cron entries (each specifying start or stop)
2. Attach individual resources or resource groups to the schedule
3. The scheduler evaluates all crons every minute
4. When a cron fires, action intents are queued for execution
5. The executor processes the queue and calls cloud provider APIs

**Info**

Each schedule has its own timezone setting. Cron expressions are evaluated in the schedule's timezone, making it easy to define business-hours schedules for teams in different regions.

## Cron Expression Format

ZopNight uses standard 5-field cron expressions:

```plaintext
┌───────────── minute (0-59)
│ ┌─────────── hour (0-23)
│ │ ┌───────── day of month (1-31)
│ │ │ ┌─────── month (1-12)
│ │ │ │ ┌───── day of week (0-6, Sunday=0)
│ │ │ │ │
* * * * *
```

### Common Patterns

| Pattern | Expression | Description |
|---|---|---|
| **Business Hours Start** | `0 8 * * 1-5` | Start at 8:00 AM on weekdays |
| **Business Hours Stop** | `0 18 * * 1-5` | Stop at 6:00 PM on weekdays |
| **Night Shutdown** | `0 22 * * *` | Stop at 10:00 PM every day |
| **Morning Startup** | `0 6 * * 1-5` | Start at 6:00 AM on weekdays |
| **Weekend Shutdown** | `0 20 * * 5` | Stop at 8:00 PM on Friday |
| **Weekend Startup** | `0 7 * * 1` | Start at 7:00 AM on Monday |

## Create Schedule

### POST /schedules

Create a new schedule with cron entries.

```bash title="Request"
curl -X POST https://zopnight.com/api/schedules \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Business Hours",
    "description": "Start resources at 8 AM, stop at 6 PM on weekdays",
    "timezone": "America/New_York",
    "crons": [
      {
        "cronExpression": "0 8 * * 1-5",
        "action": "start"
      },
      {
        "cronExpression": "0 18 * * 1-5",
        "action": "stop"
      }
    ]
  }'
```

```json title="Response"
{
  "data": {
    "id": "sch_abc123",
    "name": "Business Hours",
    "description": "Start resources at 8 AM, stop at 6 PM on weekdays",
    "timezone": "America/New_York",
    "crons": [
      {
        "id": "cron_001",
        "cronExpression": "0 8 * * 1-5",
        "action": "start"
      },
      {
        "id": "cron_002",
        "cronExpression": "0 18 * * 1-5",
        "action": "stop"
      }
    ],
    "resources": [],
    "groups": [],
    "createdBy": "user@company.com",
    "createdAt": "2025-01-15T10:30:00Z",
    "updatedAt": "2025-01-15T10:30:00Z"
  }
}
```

## List Schedules

### GET /schedules

List all schedules for your organization.

## Get Schedule

### GET /schedules/{scheduleID}

Get a schedule with its cron entries, attached resources, and groups.

## Update Schedule

### PUT /schedules/{scheduleID}

Update schedule name, description, timezone, or cron entries.

```bash title="Request"
curl -X PUT https://zopnight.com/api/schedules/sch_abc123 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Extended Business Hours",
    "timezone": "America/New_York",
    "crons": [
      {
        "cronExpression": "0 7 * * 1-5",
        "action": "start"
      },
      {
        "cronExpression": "0 20 * * 1-5",
        "action": "stop"
      }
    ]
  }'
```

## Delete Schedule

### DELETE /schedules/{scheduleID}

Delete a schedule. All resource and group attachments are removed.

## Attach Resource

### POST /schedules/{scheduleID}/resources/{resourceID}

Attach an individual resource to a schedule.

The resource will be started/stopped according to the schedule's cron entries.

## Detach Resource

### DELETE /schedules/{scheduleID}/resources/{resourceID}

Remove a resource from a schedule.

## Attach Resource Group

### POST /schedules/{scheduleID}/groups/{groupID}

Attach a resource group to a schedule. All resources in the group will follow the schedule.

**Tip**

When a group is attached, resources within it are started/stopped according to their configured execution tier and order. This is useful for dependencies (e.g., start database before app server).

## Detach Resource Group

### DELETE /schedules/{scheduleID}/groups/{groupID}

Remove a resource group from a schedule.

## Schedule Object

| Field | Type | Description |
|---|---|---|
| `id` | string | Unique schedule ID |
| `name` | string | Schedule display name |
| `description` | string | Optional description |
| `timezone` | string | IANA timezone (e.g., America/New_York) |
| `crons` | CronEntry[] | List of cron entries with actions |
| `resources` | AttachedResource[] | Directly attached resources |
| `groups` | Group[] | Attached resource groups |
| `createdBy` | string | Email of the creator |
| `createdAt` | string | ISO 8601 creation timestamp |
| `updatedAt` | string | ISO 8601 last update timestamp |
