A worldwide directory of churches and the times of their Masses, confessions and adoration. Reads are open to anyone; a correction is a suggestion that a person reviews.
openapi.json, for Postman, Bruno or a client generator
Auth
None. Every route allows any origin, so a web page can call it directly.
Cache
Reads are public, max-age=300; map tiles an hour, then a day stale while revalidating.
Errors
A missing church is 404 { "error": "not_found" }. A bad parameter is 400 with the validation issues. Too many writes is 429 { "error": "rate_limited" }.
Reading a schedule
A church’s services are its recurring times, one pattern at one time each: “Sundays at 9:00” is one service and “Sundays at 11:30” another. rrule is an iCalendar rule that picks the days, and startTime gives the wall-clock time in the church’s own timezone. exdate lists cancelled days and rdate added ones. The API sends the rules unexpanded, so you compute the next Mass on your side.
expand.ts does this in sixty lines on the rrule package, and like the rest of Ember’s code it is in the public domain to copy:
JavaScript
import { expandService } from './expand' // packages/api/src/expand.ts
const church = await (await fetch('https://ember-mass-times.dpgu.workers.dev/churches/ns-do-carmo-se-sao-paulo-sp')).json()
for (const service of church.services.filter((s) => s.kind === 'mass')) {
for (const { date, startTime } of expandService(service, { count: 3 })) {
console.log(date.toISOString().slice(0, 10), startTime, service.language)
}
}
A bundler takes it as it is. Plain Node finds no named exports in rrule: write import rrule from 'rrule' and const { RRule, RRuleSet } = rrule.
Where no structured schedule is on record (hasStructuredSchedule is false), the parish’s own wording is in texts, as it was published.
Churches
Public reads
GET/churches/near
Churches near a point
Churches within radiusKm of a point, nearest first. A kind or rite filter trims each church’s services and drops churches left with none.
Parameters
latqueryrequired
number
lngqueryrequired
number
radiusKmquery
number
kindquery
string
Keep only services of this kind: mass, confession, adoration
ritequery
string
Keep only services of this rite, e.g. latin_tridentine
institutequery
string
Only churches served by this institute, e.g. FSSP
statusquery
string
active | temporarily_closed | closed
limitquery
integer
Responses
200OK{ churches: (Church & { distanceKm: number })[] }
Every church in id order, with the few fields a sitemap needs, or with full=1 each church whole, as /churches/{id} gives it. Pass the next of one page as the after of the next; a page without next is the last.
Parameters
afterquery
string
The last id of the previous page
scheduledquery
"1"
Only churches with service times on record
countryquery
string
Only churches in these countries: ISO codes, comma-separated (BR,PT)
limitquery
integer
fullquery
"1"
Each church whole, as /churches/{id} gives it: schedule, texts, links, parish and chapels
A five-character cell answers with its churches (without texts and links); a shorter one, or root, with the counts of the cells inside it. Cached for an hour.
Parameters
cellpathrequired
string
A geohash of 1–5 characters, or root
kindquery
string
Count only churches with services of this kind
Responses
200{ churches } for a full-length cell, { cells } above it{ churches: Church[] } | { cells: Cluster[] }
What the moderators changed, for directories that keep in step
GET/changes
The change log
Every change a moderator applied to the directory and that still stands, newest first. Each church it touched comes with what changed and its schedule as it now stands, and message says the same as plain text, ready to pass on. Pass the next of one page as the before of the next; to keep in step, ask with since set to the newest appliedAt you hold.
429Too many writes from this client: rate_limitedError
Shell
curl -X POST 'https://ember-mass-times.dpgu.workers.dev/churches/ns-do-carmo-se-sao-paulo-sp/corrections' \
-H 'Content-Type: application/json' -H 'X-Client-Id: device-7f3a2c' \
-d '{"kind": "note", "comment": "From October the Sunday Mass is at 9:30."}'
POST/churches/{id}/corrections/attachments
Attach a photo to a correction
The raw bytes of one file of at most 1 MB, such as a photo of the bulletin. Send the returned key in the correction’s attachmentKeys.
Parameters
idpathrequired
string
The church id, a slug of its name and city
X-Client-Idheader
string
A stable id per device or person; with the IP, it identifies the client for the rate limit and for confirmations