What it does

Send a cron string. Get back the next N times it fires.

curl -X POST https://x402.agentutility.ai/cron-next \
  -d '{"expression": "0 9 * * 1-5", "timezone": "America/New_York", "count": 3}'
{
  "expression": "0 9 * * 1-5",
  "timezone": "America/New_York",
  "count": 3,
  "fires": [
    { "iso": "2026-05-18T13:00:00.000Z", "epoch_seconds": 1779462000, "human": "5/18/2026, 09:00:00" },
    { "iso": "2026-05-19T13:00:00.000Z", "epoch_seconds": 1779548400, "human": "5/19/2026, 09:00:00" },
    { "iso": "2026-05-20T13:00:00.000Z", "epoch_seconds": 1779634800, "human": "5/20/2026, 09:00:00" }
  ],
  "interval_seconds": 86400,
  "is_regular": true
}

$0.003 USDC. Deterministic. Same input always returns the same fire sequence (modulo the start timestamp).

Why a new endpoint when cron-explain already exists

cron-explain (and its alias cron-parse) describe the cadence in English. "At 9:00 AM on every weekday." Useful for surfacing to a human, validating a cron string, generating a docs blurb.

What they don't do: tell you when the cron will actually fire next. A human can read "every weekday at 9am" and figure out it's tomorrow morning. An agent needs the timestamp.

cron-next fills that gap. It runs the cron through cron-parser (MIT, deterministic) and returns the next N fires as ISO 8601, Unix epoch seconds, and a localized human string. Three formats because different downstream consumers want different things:

  • A scheduler queues by epoch_seconds
  • A logging system stamps by iso
  • A UI displays the human string

It also returns is_regular and interval_seconds when the cadence has a constant gap. That detail catches a class of cron bugs where the author intended 0 9 1-5 (every weekday) but typed 0 9 * (every day) — the latter has interval_seconds: 86400, the former does not.

Who calls this

  • Schedulers that need to know exactly when a job is supposed to run
  • Audit tools comparing "what cron said" vs "what actually fired" in logs
  • UI surfaces showing a user the next 5 runs of their scheduled task
  • Dependency-resolution code figuring out which cron will fire first across N jobs
  • Backfill tools computing how many historical runs they'd need to replay

The timezone bit matters

0 9 1-5 in UTC and 0 9 1-5 in America/New_York fire at different absolute times. Most cron libraries default to UTC; cron-parser respects an IANA timezone string and handles DST correctly. We surface that — the timezone field is mandatory in the response, even if you didn't pass one, because the absolute timestamps depend on it.

If you pass an unknown timezone like "America/New_Yorkk", you get a 400 with the underlying error from the IANA database. Better to fail clearly than silently default to UTC and ship wrong timestamps.

Edge cases

  • 5-field, 6-field (with seconds), and 7-field (with year) crons all work
  • Macros: @daily, @hourly, @weekly, @monthly, @yearly all expand correctly
  • DST transitions are handled by cron-parser — the human strings will show the time shift
  • Past start timestamps work (compute fires from a historical point); future ones work too
  • count > 50 returns 400 — we cap at 50 to keep iteration bounded
  • Invalid cron returns 400 with the parser's actual error message, not a generic "bad input"

What's NOT here

  • No "did this cron fire?" — that's a log-checking question, not a schedule question
  • No conversion between cron and other schedule formats (rrule, AWS rate expressions). Could be a follow-up if there's demand.
  • No skipping holidays or business-day awareness. Cron strings can't express that and we don't pretend.

Call it. Pairs with cron-explain for a complete cron-introspection pair: one tells you what it means, the other tells you when it fires.