# cPanel Cron Jobs

## Environment

```env
CRON_SECRET=your-long-random-secret
SEQUENCE_WORKER_ENABLED=true
MAILBOX_SYNC_ENABLED=true
AUTO_CLASSIFY_INBOX_REPLIES=true
```

All cron endpoints require header:

```
x-cron-secret: your-long-random-secret
```

## Run sequence steps

**Endpoint:** `POST /api/cron/run-sequences`

**Recommended:** every 5 minutes

```bash
curl -X POST https://yourdomain.com/api/cron/run-sequences \
  -H "x-cron-secret: YOUR_SECRET"
```

## Sync mailboxes

**Endpoint:** `POST /api/cron/sync-mailboxes`

**Recommended:** every 1–2 minutes

```bash
curl -X POST https://yourdomain.com/api/cron/sync-mailboxes \
  -H "x-cron-secret: YOUR_SECRET"
```

## Behavior

- **run-sequences** — sends due sequence step emails, records history, updates recipient state
- **sync-mailboxes** — IMAP sync for **all** active mailboxes (independent of `/inbox` being open), creates `EmailReply` + `EmailThread`, triggers AI classification when `AUTO_CLASSIFY_INBOX_REPLIES=true`. Uses saved mailbox IMAP credentials; does not require `.env` `IMAP_*` when active mailboxes exist.

Each cron invocation creates a **`CronRunLog`** document (`jobName`, `status`, `startedAt`, `finishedAt`, `durationMs`, `triggeredBy`, `stats`, `errorMessage`).

| Status | Meaning |
|--------|---------|
| `success` | Job completed (mailbox sync may succeed partially) |
| `failed` | Unhandled error or all mailbox syncs failed |
| `skipped` | Worker disabled via env (`SEQUENCE_WORKER_ENABLED` / `MAILBOX_SYNC_ENABLED`) |

## Admin monitoring (`/settings/cron`)

Admins can view last run status, duration, stats, errors, and recent logs. Manual triggers (session auth, no cron secret):

| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/admin/cron/summary` | Last mailbox sync + last sequence run |
| GET | `/api/admin/cron/logs` | Paginated logs (`jobName`, `page`, `limit`) |
| POST | `/api/admin/cron/sync-mailboxes` | Run mailbox sync now (`triggeredBy: manual`) |
| POST | `/api/admin/cron/run-sequences` | Run sequence worker now (`triggeredBy: manual`) |

## Security

- Never commit `CRON_SECRET` to git
- Use a long random value (32+ characters)
- Restrict cron URLs to server-side curl only
