{"id":7641,"plugin_id":"plugin_asdk_app_6a5e7ac6ddf881919de226cb7506ef57","kind":"skill","collection_source":null,"comparison_source":null,"observed_at":"2026-09-30T22:50:58.105Z","digest":"acdfe645d0e3f28dc026b5aebaa929c9b54dccdfb14ac12c6a8a8638bee2f05a","against":null,"payload":{"name":"cron-and-intervals","description":"Use when building a val that runs on a schedule — periodic jobs, recurring tasks, polling, cron jobs, monitoring, alerting. Covers the interval handler signature, cron expressions, the UTC timezone constraint, and the `lastRunAt` pattern for detecting new items since the previous run.","included_files":[],"skill_md_contents":"---\nname: cron-and-intervals\ndescription: Use when building a val that runs on a schedule — periodic jobs, recurring tasks, polling, cron jobs, monitoring, alerting. Covers the interval handler signature, cron expressions, the UTC timezone constraint, and the `lastRunAt` pattern for detecting new items since the previous run.\n---\n\n# Cron / Interval Vals\n\nInterval vals (`fileType: \"interval\"`) run on a recurring schedule defined by a cron expression. Use them for polling external APIs, sending reminders, running cleanups, generating reports, or any work that should happen on a clock rather than in response to a request.\n\n## Basic handler\n\n```ts\n// Learn more: https://docs.val.town/vals/cron/\nexport default async function (interval: Interval) {\n  // interval.lastRunAt: Date | undefined\n  console.log(interval);\n}\n```\n\nThe file must have an `export` — `export default` for the handler.\n\n## Timezone\n\n**Cron expressions run in UTC.** Convert any human-readable schedule (e.g. \"9am Eastern\") to UTC before writing the cron expression. Daylight savings is not handled — pick a UTC time that's close enough year-round.\n\n## The `lastRunAt` pattern\n\n`interval.lastRunAt` is the timestamp of the previous successful run (or `undefined` on the first run). Use it to fetch only items created since the last run, instead of re-scanning everything:\n\n```ts\nexport default async function (interval: Interval) {\n  const since = interval.lastRunAt ?? new Date(Date.now() - 24 * 60 * 60 * 1000);\n  const newItems = await fetchItemsSince(since);\n  for (const item of newItems) {\n    await handle(item);\n  }\n}\n```\n\nThis makes the val idempotent against missed runs and avoids reprocessing.\n\n## Reading and updating the schedule\n\n- `read_interval_settings` — fetch the current cron expression and active state of an interval file.\n- `write_interval_settings` — change the cron expression or pause/resume an interval.\n\n## When to skip a template\n\nFor simple scheduled jobs, create a new val with a single `interval`-type file directly — no template needed. Templates are for more complex shapes (dashboards, AI agents, webhook + UI combos).\n\n## Verifying changes\n\nAfter editing an interval val, use `run_file` to invoke the handler manually instead of waiting for the next scheduled run.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}