Cron API
Internal endpoints for scheduled operational tasks
The Cron API consists of headless endpoints triggered by Vercel Cron on a scheduled basis. These endpoints handle background tasks such as compliance monitoring, report reminders, announcement publication, data synchronization, contact retention, and coupon expiration.
OK
response?stringtext/plaincurl -X GET "https://example.com/cron/keep-alive""OK"cronSecretAuthorizationBearer <token>CRON_SECRET environment variable
Cron job completed
response?stringtext/plaincurl -X GET "https://example.com/cron/report-reminder""OK — 3 reminders sent"cronSecretAuthorizationBearer <token>CRON_SECRET environment variable
Cron job completed
response?stringtext/plaincurl -X GET "https://example.com/cron/check-compliance""OK — nudged 5 staff, 2 managers"cronSecretAuthorizationBearer <token>CRON_SECRET environment variable
Cron job completed
response?stringtext/plaincurl -X GET "https://example.com/cron/aggregate-heroes""OK — MVP messages created for: John Doe"cronSecretAuthorizationBearer <token>CRON_SECRET environment variable
Cron job completed
curl -X GET "https://example.com/cron/publish-scheduled-announcements"cronSecretAuthorizationBearer <token>CRON_SECRET environment variable
Cron job completed
curl -X GET "https://example.com/cron/prune-soft-deleted-contacts"cronSecretAuthorizationBearer <token>CRON_SECRET environment variable
Cron job completed
curl -X GET "https://example.com/cron/sync-schedule-from-7shifts"cronSecretAuthorizationBearer <token>CRON_SECRET environment variable
Cron job completed
curl -X GET "https://example.com/cron/sync-7shifts-roles"cronSecretAuthorizationBearer <token>CRON_SECRET environment variable
Cron job completed
curl -X GET "https://example.com/cron/expire-coupons"Security
Endpoints are protected by a shared secret passed in the Authorization: Bearer <CRON_SECRET> header. The keep-alive endpoint is public but performs no sensitive operations.
Configured Vercel schedules
Schedules are defined in apps/api/vercel.json. All configured jobs except
/cron/keep-alive require cron authentication.
| Route | Schedule (UTC) | Purpose |
|---|---|---|
/cron/keep-alive | 0 1 * * * | Keep the database connection warm |
/cron/report-reminder | 0 20 * * * | Remind about unfiled reports |
/cron/check-compliance | 0 14 * * 1 | Check weekly filing compliance |
/cron/aggregate-heroes | 0 14 * * 1 | Aggregate Hero of the Shift mentions |
/cron/publish-scheduled-announcements | */5 * * * * | Publish due announcements |
/cron/prune-soft-deleted-contacts | 30 8 * * * | Prune expired soft-deleted contacts |
/cron/sync-schedule-from-7shifts | 0 */6 * * * | Refresh the 7shifts schedule read model |
/cron/sync-7shifts-roles | 0 */4 * * * | Refresh 7shifts role mappings |
/cron/expire-coupons | * * * * * | Release due coupon reservations and check expiry health |
For tip mart backfill across a date range, use the CLI documented in Analytics & Tips Integration.
Coupon expiry health
GET /cron/expire-coupons uses the shared authenticated cron handler. Its
schedule is owned by apps/api/vercel.json.
The database owns expiry and reserved capacity; Vercel Cron only schedules work.
The sweep claims bounded batches (currently 100) and atomically transitions due
active reservations, releases their held capacity, and accepts stable expiry
events. Repeated delivery cannot release the same capacity twice. Lazy expiry
on supported guest resume/transition paths remains part of the lifecycle.
The sweep stays disabled until complete retry readiness is admitted. Its disabled
HTTP 200 response explicitly says status: "disabled"; this is not evidence
that expiry ran or that admission flags may be enabled.
Completed runs record privacy-safe correlation, duration, expired/ignored counts, accepted/duplicate event counts, reconciliation delta, and oldest expiry lag. A nonzero reconciliation delta or lag above the current 120-second health bound records diagnostics before raising the failed health gate. Investigate the safe run/correlation evidence rather than editing campaign counters. Existing cron run history and logs provide execution evidence. Immutable scheduled-run events remain disabled by the shared admission gate pending ADR-0102 privacy approval; their schema alone does not prove that a run was recorded.
Expiry notifications use the durable guest-event and notification queue contracts; provider failures do not reverse committed reservation transitions. No raw Contact values, private links, cookies, or staff proof belong in these diagnostics.
See Coupons and Guest NPS and the Coupon/NPS rollout runbook for schema, admission, no-op, and rollout evidence. The completed 2026-10-07 reliability release does not automatically enable expiry/retry for every team.