REST API · v1
API Reference
Start here: authentication, the response envelope, rate limits, caching, and offline downloads. Each endpoint is documented on its own page — pick a feature in the sidebar (or the cards below), and test any of them in the live Explorer. A machine-readable OpenAPI 3.1 spec is available for codegen, Postman, and Swagger UI.
Base URL
https://myselahh.comAuthentication
Every /api/v1/* endpoint except /health and /ping requires an API key. Get one free at /register. Pass it any of three ways (Bearer is recommended):
bapi_sk_… · Secret key
Server-side, full access. Keep it private — never ship it in a browser, mobile app, or public repo.
bapi_pk_… · Publishable key
Safe to embed in a website/widget. Works only from the domains you allow-list in your dashboard; any other origin (or a server-side call with no Origin) gets 403 ORIGIN_NOT_ALLOWED.
Both are issued per account. Use the secret key from servers; use the publishable key in client/browser code.
# 1. Authorization header (recommended)
curl 'https://myselahh.com/api/v1/verses/john/3/16' \
-H 'Authorization: Bearer $BIBLE_API_KEY'
# 2. X-API-Key header
curl 'https://myselahh.com/api/v1/verses/john/3/16' \
-H 'X-API-Key: $BIBLE_API_KEY'
# 3. Query string (appears in logs — least preferred)
curl 'https://myselahh.com/api/v1/verses/john/3/16?key=$BIBLE_API_KEY'Response envelope
Successful responses share a { data, meta, pagination? } envelope; errors return { data: null, meta: {}, errors: [...] } with an HTTP status and a stable error code.
// success
{ "data": { /* payload */ }, "meta": { "reference": "John 3:16" } }
// error
{ "data": null, "meta": {},
"errors": [{ "code": "INVALID_REFERENCE", "message": "Use format: \"John 3:16\".",
"docs": "https://myselahh.com/docs/errors#invalid_reference" }] }Rate limits
Each key has a per-minute ceiling and a rolling per-window quota. Exceeding either returns 429 RATE_LIMIT_EXCEEDED. If key validation is temporarily unavailable the API fails closed with 503. Watch the RateLimit-* response headers for remaining quota.
Caching
Immutable reads — scripture, cross-references, and book/translation metadata — return an ETag and Cache-Control. Send the ETag back as If-None-Match to get a 304 Not Modified (no body, no quota wasted on unchanged data):
# First request returns an ETag
curl -i 'https://myselahh.com/api/v1/passages/John%203:16' -H 'Authorization: Bearer $BIBLE_API_KEY'
# → ETag: W/"abc123-..."
# Revalidate cheaply — 304 if unchanged
curl -i 'https://myselahh.com/api/v1/passages/John%203:16' \
-H 'Authorization: Bearer $BIBLE_API_KEY' \
-H 'If-None-Match: W/"abc123-..."'Offline downloads & sync
To build offline Bible reading into your app, sync against the download manifest rather than calling per-verse endpoints. The bundles are pre-built, versioned, gzipped static files served from the CDN (public, immutable) — so a full offline copy costs essentially no quota, and you only re-download what changed.
GET /api/v1/download/manifest— the catalog of every bundle (whole-translation + per-book) withurl,bytes,sha256, andversion.- Download the bundles you need from their
url(each a public/media/…CDN file). Verify with thesha256, then gunzip. - Store them on-device (this part is yours — SQLite, IndexedDB, files…). Read entirely offline from there.
- Periodically re-fetch the manifest and re-download only the bundles whose
versionchanged.
It's the standard offline-sync model — static CDN bundles + a manifest; the only part you own is on-device storage. For a quick one-shot grab without the manifest, GET /api/v1/download/{translation} returns the whole Bible in one request (~1.2 MB gzipped), and /api/v1/books/{book}/download returns a single book.
# 1. Get the catalog
curl 'https://myselahh.com/api/v1/download/manifest' -H 'Authorization: Bearer $BIBLE_API_KEY'
# 2. Download a bundle from its url (public CDN — no key needed, gzipped, immutable)
curl -o web.json.gz 'https://myselahh.com/media/bundles/web-<version>.json.gz'
# 3. Verify + decompress
shasum -a 256 web.json.gz # compare to the manifest's sha256
gunzip web.json.gz # → web.json (compact: books[].chapters[][])Browse the endpoints
Every endpoint lives on its own documentation page — params, examples, and responses. Open one from the sidebar, or pick a feature below.