All projects

Daily Saints API

Daily Saints API

· Source

A free API that serves one or more saints for every day of the year, 564 saints across all 366 days, plus a one-line widget to drop the day’s saint into any website.

Live at acoci86.github.io/daily-saints.

What it is

Ask for a date and get back JSON: the saint’s name, era, patronage, a short summary, an image, and a Wikipedia link.

GET /api/v1/saints/07-22.json

There is no server. It is 366 plain files sitting on GitHub Pages. That is the whole point of the design, and it is what makes it free to run and impossible to knock over.

Decisions, and what they cost

A file per day, not a running server

Every day is a static JSON file, generated once. A request for July 22 just fetches 07-22.json. Nothing is computed when you ask.

That means no database, no server bill, and no outage at 3am, because there is nothing running to fall over. The cost is that the data only changes when I rebuild and push. For saints’ days, which have not moved in centuries, that is no cost at all.

The response is shaped for the caller, not the data

169 days have more than one saint, so saints is always an array, even on the many days with just one. And every response carries a count, so you can tell how many there are without looping.

The widget refuses to make a mess

The embed is one line, and it holds itself to three rules. It adds no global styles, so it cannot change anything else on your page. It uses only single-class selectors and puts its own CSS before yours, so your styles win with no !important fight. And if it cannot reach the API, it removes itself completely rather than leaving a broken box behind.

The parts that were actually hard

The day has to turn over at the right hour

The widget reads the visitor’s own local date, not UTC, so the saint changes at their midnight rather than Greenwich’s.

The UTC version looks like this:

var now = new Date();
var key =
  String(now.getUTCMonth() + 1).padStart(2, "0") + "-" +
  String(now.getUTCDate()).padStart(2, "0");

That turns the day over at the wrong hour. new Date() is a single instant, but getUTCDate() reads it in Greenwich time, so someone in New York loading the page at 8pm has already crossed into tomorrow in UTC and gets tomorrow’s saint. Reading the same instant in the visitor’s own timezone avoids it:

var now = new Date();
var key =
  String(now.getMonth() + 1).padStart(2, "0") + "-" +
  String(now.getDate()).padStart(2, "0");

Only two method names change, the UTC readers become their local equivalents. It is the kind of detail that is invisible from where you build it and obvious to everyone further west.

The images were the real work

Nearly every saint has a picture, 537 of them pulled from that saint’s own Wikipedia article and scaled down. The rest were chosen by hand, and kept only when the image genuinely showed the right person.

The unglamorous part was the licensing. Most are public domain, but 113 are not, so every single image is logged with its source, licence and author in a credits file. Shipping images without knowing where each one came from is how a free project quietly becomes someone else’s legal problem.

One saint, two calendars

The dates follow the traditional pre-1970 calendar, and roughly one day in five differs from the modern one. Apollinaris is July 23 here and July 20 in the modern calendar.

Rather than silently pick a side, the API says up front which calendar it uses and gives an example of the difference, so nobody is surprised when a date does not match the one they expected.

What’s next