Skip to main content
Schedules are cron-driven background jobs. Same handler shape, same ctx as webhooks and tools.

Basic schedule

Declare the schedule

Invocation object

Use trigger to distinguish scheduled runs from a human pressing “Run now” (in the harness, or an admin in the host). Handlers may branch on it, but must be safe under both, and under redelivery.

Result contract

completed means work was done. skipped means the handler correctly decided nothing needed to happen (no credentials, nothing to reconcile). Only throw for genuine faults.

Cron syntax

Standard 5 fields: minute hour day-of-month month day-of-week
No seconds field, no @daily macros, no named months/days. A step needs * or a range as its base — 5/15 is rejected; write */15 or 0-59/15. Validation happens at defineIntegration() import time.

Common patterns

Reconcile from upstream

Fetch and cache once a day:

Bypass an idempotency window for manual runs

Testing

Use invokeSchedule():
Reuse one context across multiple invocations so state accumulates:

Troubleshooting

Cron validation error

defineIntegration() reports schedules["<id>"]: Cron expression "<expr>" is invalid: <detail>. followed by the expected grammar. Check:
  • 5 fields exactly
  • No seconds field
  • No names like JAN or MON
  • Valid ranges per field
  • No @daily macros
  • No step on a single value (5/15)

Schedule id not declared

invokeSchedule() throws Integration "<slug>" declares no schedule "<id>". and lists the declared ids. Check the id spelling.

Next steps

  • On-activate — seed data at connect time
  • Testing — test schedules with invokeSchedule()