getNodi

Templates / Daily digest email

Sending a digest at the right local hour

Timing is most of what a digest is. The same content at 08:00 is read and at 03:00 is deleted, and the difference is a timezone setting rather than anything about the mail.

The recipe

Request
POST https://{{domain}}/api/digest/daily
Schedule
At 08:00 AM (0 8 * * *)
Headers
Authorization: Bearer {{secret}}encrypted
Timeout
120s
Attempts
3
Counts as success
2xx

You supply

Your domain
example.com

Host only — no https:// and no trailing slash.

Shared secret
s3cr3t-valuestored encrypted

Whatever your endpoint checks the caller against.

Why this job exists

Digest email lives or dies on arrival time. Landing in the inbox shortly before someone starts work puts it near the top when they first look; landing overnight buries it under everything that arrived after. The content matters less than most people expect and the hour matters more.

Servers are configured in UTC, sensibly, and scheduling in UTC is where this goes wrong. A job set for 08:00 UTC reaches a reader in California at midnight. It is a small mistake with a large effect, and because engagement is the only symptom, it is usually attributed to the content.

Scheduling in the readers timezone rather than the server one costs nothing and removes the class of bug entirely — including the twice-yearly variety, where a UTC schedule silently shifts by an hour when daylight saving changes and nobody connects the drop to the clocks.

Setting it up

Set the timezone on the job to where your readers are, not where the server is. The schedule is evaluated in that zone, including across daylight saving transitions, so 08:00 stays 08:00 in March and in November.

For readers spread across many zones, the schedule cannot solve it alone. Run this hourly and have the endpoint select the subscribers whose local hour is now the send hour — the schedule provides the tick and the query provides the personalisation.

Checking it actually works

  • Confirm the arrival time in a real inbox, not the send time in your logs. Queueing and provider throughput sit between the two.
  • Check what happens on a daylight saving boundary — the run history will show whether the UTC time shifted while the local time held.
  • Make the endpoint idempotent per day and confirm a retry cannot double-send.

Where it goes wrong

Sending twice

A retry after a timeout will call the endpoint again. If the send is not guarded by a per-day marker, some subscribers get two copies. Record the digest date before sending and return early if it is already present.

Blocking on the whole send

Sending fifty thousand emails inside one HTTP request will time out. Have the endpoint queue the send and return; use the queue drain recipe to work through it.

Mailing an empty digest

A digest with nothing in it trains people to ignore the next one. Have the endpoint skip subscribers with no content and report how many were skipped.

Questions

What time is best?

Between 07:00 and 09:00 local on weekdays is the usual answer, but your own data beats the convention. Change one thing at a time and give it a fortnight.

How do I handle many timezones?

Run hourly and filter by the subscriber local hour in the query. This is the only approach that scales past two or three regions.

Should I skip weekends?

For anything work-related, usually yes — cron makes it a one-character change, from * to 1-5 in the day-of-week field.

Running it here

This is a preset in the product, not an illustration. Pick it in the dashboard, fill in the 2 values above, and the job is created, scheduled and enabled — with retries, a record of every run showing status, latency and response, and an alert the first time one fails. Secret values are encrypted at rest and never rendered back.

The free plan runs 3 jobs hourly and needs no card. Where a recipe wants a finer cadence than your plan allows, it is slowed to the fastest schedule you are permitted rather than rejected.