# Auto Schedules

Create clock-driven automation schedules that fire on a cron expression, fan out to a resolved audience, and trigger one automation run per row. Legacy path /event-schedules is also accepted.

**Base URL:** `https://api.trustpager.com/functions/v1/api/v1`

## Endpoints

### GET /auto-schedules

List all auto schedules for the workspace.

**Scopes:** `schedules:read` — [full detail](./auto-schedules/get-auto-schedules.md)

### GET /auto-schedules/:id

Retrieve a single auto schedule.

**Scopes:** `schedules:read` — [full detail](./auto-schedules/get-auto-schedules-id.md)

### POST /auto-schedules

Create a new auto schedule. Required fields: name, audience_type, automation_id, and exactly one schedule input (see below).

**Specify the schedule in one of two ways:**

**Option A -- Structured (recommended for AI agents):** Provide time_of_day ("HH:MM", e.g. "08:00") plus optional days_of_week (array of ints 0-6, where 0=Sunday and 6=Saturday) and timezone. The server derives the cron expression automatically.
- Example: time_of_day "08:00", days_of_week [1,2,3,4,5], timezone "Australia/Melbourne" -- stores cron "0 8 * * 1,2,3,4,5"

**Option B -- Raw cron:** Provide cron_expression (standard 5-field syntax) and timezone. Use this for patterns that time_of_day cannot express, such as every-N-minutes, twice-daily, or monthly schedules.
- Example: cron_expression "0 9,17 * * *", timezone "Australia/Sydney" -- fires 9am and 5pm daily

If both are provided, cron_expression wins. Cron is the canonical stored form -- the response always includes cron_expression regardless of which input option was used.

**Common cron patterns:**
- "*/15 * * * *" -- every 15 minutes
- "0 * * * *" -- every hour
- "0 9 * * *" -- daily at 9am
- "0 9 * * 1-5" -- weekdays at 9am
- "0 9 * * 1" -- every Monday at 9am
- "0 9,17 * * *" -- 9am and 5pm daily
- "0 9 1 * *" -- 1st of every month at 9am

**audience_type** controls who receives a run:
- "users" -- one run per staff member (with optional role/user_ids filter)
- "tasks_by_assignee" -- one run per assignee who has open tasks (digest pattern)
- "contacts" -- one run per matching contact
- "deals" -- one run per matching deal

**audience_filter** is type-specific JSON:
- users: { "roles": ["client_editor"], "user_ids": ["uuid"] }
- tasks_by_assignee: { "statuses": ["open"], "include_overdue_only": true, "max_tasks_per_user": 20 }
- contacts: { "contact_type": "lead", "has_email": true, "limit": 500 }
- deals: { "status": "open", "stale_days": 14, "pipeline_id": "uuid", "stage_ids": ["uuid"], "limit": 200 }

Optionally set end_at (ISO timestamp) to stop firing after a date, or max_runs (integer) to auto-deactivate after N fires.

**Scopes:** `schedules:write` — [full detail](./auto-schedules/post-auto-schedules.md)

### PATCH /auto-schedules/:id

Partial update -- modify any field. Accepts the same two schedule-input options as POST: either time_of_day (+ optional days_of_week) or cron_expression. If cron_expression is provided it takes precedence. Changing either schedule input or timezone automatically recomputes next_run_at.

**Scopes:** `schedules:write` — [full detail](./auto-schedules/patch-auto-schedules-id.md)

### DELETE /auto-schedules/:id

Permanently delete an auto schedule. The linked automation is NOT deleted. This cannot be undone.

**Scopes:** `schedules:delete` — [full detail](./auto-schedules/delete-auto-schedules-id.md)

### POST /auto-schedules/preview-cron

Validate a cron expression and preview the next N fire times in a specified timezone. Does NOT create any schedule. Use to confirm a pattern before saving.

**Scopes:** `schedules:read` — [full detail](./auto-schedules/post-auto-schedules-preview-cron.md)

### POST /auto-schedules/:id/fire-now

Manually fire an auto schedule immediately. Resolves the current audience and triggers one automation run per row. Does NOT advance next_run_at, increment run_count, or respect end_at/max_runs limits. Useful for testing, ad-hoc sends, or recovering from a missed fire.

**Scopes:** `schedules:write` — [full detail](./auto-schedules/post-auto-schedules-id-fire-now.md)

### GET /auto-schedules/:id/audience-preview

Preview the audience a schedule WOULD resolve to right now -- returns the total count and a configurable sample of trigger_data rows, without firing anything. Use before enabling a schedule to verify the filter targets the right rows.

**Scopes:** `schedules:read` — [full detail](./auto-schedules/get-auto-schedules-id-audience-preview.md)

### GET /auto-schedules/:id/runs

List historical fire records for a schedule. Shows audience_size, runs_triggered, runs_failed, status (completed/partial/failed), and timing. Use to verify schedules are firing, debug failures, or audit history. Supports cursor pagination ordered by fired_at descending.

**Scopes:** `schedules:read` — [full detail](./auto-schedules/get-auto-schedules-id-runs.md)
