nano-api / relay

Cron, without a machine
to keep alive

A cron expression, a timezone and a URL. It retries, keeps the run history, and posts to your webhook when the endpoint starts failing. The timezone is the part I got tired of getting wrong by hand.

Take a key Curl walkthrough

Free. Signup is one curl and the key comes back in the response. No form, no card, nobody to ask.

0 * * * * · Europe/Oslo POST /jobs/sync
  1. 03:00 → 200 412ms
  2. 04:00 → 200 388ms
  3. 05:00 → 500 attempt 1/3
  4. 05:00 → 500 attempt 2/3
  5. 05:00 → 500 attempt 3/3
Schedule sync failed: endpoint returned HTTP 500 (3 attempts).

Creating a schedule

curl -X POST https://relay.nano-api.com/v1/schedules \
  -H "Authorization: Bearer $NANO_API_KEY" \
  -H 'content-type: application/json' \
  -d '{
    "slug": "nightly-report",
    "cron": "0 3 * * *",
    "timezone": "Europe/Oslo",
    "url": "https://api.example.com/jobs/nightly-report"
  }'

Optional: body, headers, timeout_seconds, max_attempts, alert_webhook_url. Test it with POST /v1/schedules/:slug/run.

03:00 means 03:00, in March and in November

Platform crons run in UTC, so a 03:00 job quietly moves twice a year. Relay evaluates the expression in the zone you name.

UTC-only cron

  • Drifts an hour twice a year
  • Skips the run when the local hour does not exist
  • Can run twice on the ambiguous hour

NanoRelay

  • 0 3 * * * in Europe/Oslo stays at 03:00
  • A missing hour runs just after the gap
  • An ambiguous hour runs once, on its first instant

All three are pinned by tests in the repo.

When the call fails

  1. 1

    Retry

    Three attempts, 2s and 6s backoff, each bounded by your timeout.

  2. 2

    Alert on the change

    Once when it breaks, once when it recovers. Never one per failed run.

  3. 3

    Keep the evidence

    Status code, duration, attempts, and the start of the response body.

Delivery is at-least-once, so make the endpoint idempotent. Every request carries X-NanoRelay-Run-Id. Missed slots are skipped, not replayed: no catch-up stampede after an outage.

Using it with the others

Take a Lock at the top of the job and ping Pulse at the end. Then a scheduler that dies quietly is still an alert.

How to, in curl What this is