← Val TownCONTENT HISTORY

Update to Val Town

Snapshot Sep 30, 2026 · 22:50 UTC · version 3.0.0

Collection source: not recorded for this historical snapshot.

WHAT CHANGED · RULE-BASED ANALYSIS

First saved snapshot

No earlier snapshot is available to establish a change.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "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"
}

SHA-256: acdfe645d0e3f28dc026b5aebaa929c9b54dccdfb14ac12c6a8a8638bee2f05a