API reference
Four jobs, four endpoints. Start with which call — open fields and examples only when you need them.
Which endpoint do I call?
These are not four ways to search. Each exists because one product moment kept failing when everything went into a single lookup.
| You have | You need | Call |
|---|---|---|
| A remembered line, paraphrase, or story description | The closest verse or story unit, ranked with proof | POST /v1/search |
| A sermon, transcript, caption, or long chat | Every verse that was said, pointed back at the source | POST /v1/extract |
| A quote and a chapter:verse already attached | A yes / no / not sure before that claim ships | POST /v1/verify |
| A reference you already trust | Related passages, people, or themes | GET /v1/graph/… |
| A reference you already trust | The held verse text to display | GET /v1/passage |
| An app boot or session check | What this deployment holds | GET /v1/corpus |
Authentication
This website is free. Lookup, Graph, and the playground on this origin do not need a key.
Calling /v1/* from curl, another site, or your own product needs an API key:
Authorization: Bearer YOUR_TOKEN
Without a key those requests return 401. These pages set a short HttpOnly session cookie; their fetch calls send that cookie from this origin (rate-limited). Spoofing Origin is not enough. A Sardius service key or Control Panel token works as the Bearer value.
Find a passage or story
Reverse lookup: you have words, not a citation. The API returns ranked scripture — a verse if they quoted, a story unit if they described a scene.
- A search box or “what verse is this?” field
- A paraphrase (“green pastures, still waters”)
- A scene (“wedding where water becomes wine”)
- One thought in, one ranked hit list out
- The input is a whole sermon — use extract
- A chapter:verse is already claimed — use verify
- You only want related links — use graph
- You already have the ref and just need text — use passage
POST quote. Read
candidates[0].reference.
Show sharedPhrases as the proof.
Scene description? Use mode: "story".
Why this call exists What it does under the hood
People almost never type a citation. They remember a phrase, or they describe a wedding at Cana. Keyword-only search misses the meaning; a chat model guesses a reference with no proof. This is the moment that lands them on the passage and tells you why it ranked there.
In quote mode it pulls distinctive words, finds
candidate verses, then scores token overlap plus shared phrases.
In story mode it matches a scene to a story unit
(Cana, the prodigal) instead of a single verse.
auto picks from the wording so a mixed search box does not have to.
Request fields quote · mode · limit
| Field | Type | Required | What it is / how to use it |
|---|---|---|---|
quote |
string | yes | The remembered line, paraphrase, or story description. Aliases: q, text. Imperfect wording is expected. Max 4,000 characters. |
mode |
string | no | quote (default) ranks verses. story ranks story units. auto chooses from the wording so a mixed search box does not have to. |
limit |
number | no | How many candidates to return. Default 8, max 20. Use 1–3 for a “best hit” UI; more when you want a shortlist. |
translations |
string[] | no | Optional corpus ids to search in quote mode. Omit to search everything this deployment holds. |
Response fields candidates[] · sharedPhrases
| Field | Type | What it is / how to use it |
|---|---|---|
mode |
string | Always quote in this shape. Check it if you sent auto. |
corpusVersion |
string | Which corpus this result was scored against. Cache or log it with the hit. |
query |
string | The text that was actually searched (trimmed). |
keywords |
string[] | Tokens used to prefilter the corpus. Useful for debugging a miss, not for display. |
candidates[] |
object[] | Ranked hits, best first. Empty if nothing scored well. |
candidates[].reference |
string | Display reference (e.g. John 3:16). This is the product answer. |
candidates[].score |
number | 0–1 token-overlap confidence. Treat ≥ ~0.7 as a strong hit in a search box. |
candidates[].phraseScore |
number | How well multi-word phrases lined up. High phrase score is better proof than a high token score alone. |
candidates[].sharedPhrases |
string[] | The overlapping phrases. Show these under the hit (“matched: so loved the world”). |
candidates[].matchedTranslation |
string | null | Corpus id that scored best for this candidate. |
candidates[].text |
string | null | Held verse text when available. Always show publisher attribution if you display it. |
note |
string? | Human-readable miss reason when the list is empty. |
| Field | Type | What it is / how to use it |
|---|---|---|
unitId |
string | Stable story-unit id. Use this as the key for a story card, not a single verse. |
title · summary |
string | null | Card copy for the scene. Prefer these over raw verse text in story UIs. |
reference |
string | Span of the story (often a range, not one verse). |
people · themes · places |
string[] | Tags from the story unit. Good chips on a result card; also a hop into graph explore. |
scale |
string | Always coarse today — this is a story, not a single verse. |
Example curl
// Paraphrase → verse
curl -X POST ${ORIGIN}/v1/search \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"quote":"God so loved the world that he gave his only son","limit":6}'
// Scene → story unit
curl -X POST ${ORIGIN}/v1/search \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"mode":"story","quote":"wedding where Jesus turns water into wine"}'
Pull verses out of a transcript
Find the scripture that was quoted or alluded to inside longer talk — even when only part of a verse is spoken — and point back to the words in your source text.
- Auto-tagging a sermon with verses that were said
- Highlighting quotes in a caption or notes feed
- Recovering several verses from one recap
- The input is long — paragraphs, not a search box
- The user typed one clean line — use search
- You already have quote + reference — use verify
- You only want neighbors of a known ref — use graph
POST text. Highlight
excerptStart–excerptEnd
in the source and tag it with reference.
Several hits can come back from one clip.
Why this call exists How it windows the talk
Sermons, captions, and chat bury half-quotes mid-sentence. Sending that whole
transcript to /v1/search ranks noise. Extract recovers
several verses from one clip and tells you where in the talk each one appeared.
It does not search the whole blob as one query. It splits the input into spans (quoted clauses, sentences, sliding windows, and explicit “John 3:16” mentions), drops speech filler, reverse-searches each span, then merges hits by reference.
Request fields text · limit · minScore
| Field | Type | Required | What it is / how to use it |
|---|---|---|---|
text |
string | yes | The sermon clip, transcript, caption, or notes. Aliases: quote, q. Max ~20,000 characters. |
limit |
number | no | Max distinct references to return. Default 8, max 20. |
minScore |
number | no | Confidence floor for a span to become a hit. Default 0.32. Raise it if you only want obvious quotes; lower it if you are mining allusions. |
maxSpans |
number | no | How many windows to search (budget). Default grows with text length, max 40. Leave it alone unless you are tuning cost vs. recall. |
translations |
string[] | no | Optional corpus ids, same as search. |
Response fields hits[] · excerpt + offsets
| Field | Type | What it is / how to use it |
|---|---|---|
corpusVersion |
string | Corpus this extract was scored against. |
query |
string | The text that was processed (trimmed). |
spansConsidered |
number | How many windows were searched. Useful when debugging a miss on a long clip. |
hits[] |
object[] | Merged, ranked scripture found in the talk. Empty if nothing was confident. |
hits[].reference |
string | The verse (or range) this span most likely quoted. |
hits[].score · phraseScore |
number | Same meaning as search. Phrase score is what keeps partial spoken quotes. |
hits[].sharedPhrases |
string[] | Overlapping phrases — show these as the highlight reason. |
hits[].excerpt |
string | The substring of your text that produced the hit — not the corpus verse. |
hits[].excerptStart · excerptEnd |
number | Character offsets into the request text. Use these to paint a highlight. |
hits[].kind |
string | quoted · sentence · window · reference. Tells you whether it came from quotes, a sentence, a sliding window, or an explicit “John 3:16” mention. |
hits[].claimedRef |
string? | Present when the speaker also said a reference. Still verify it before you trust it. |
hits[].text |
string? | Held corpus wording for the matched verse, when available. |
note |
string? | Short summary (“Found 3 likely quotes…”) or a miss hint. |
Example curl
curl -X POST ${ORIGIN}/v1/extract \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"text":"He was talking about how God so loved the world that he gave his only son…","limit":6}'
Check a claim before it publishes
You send a quote and the reference you were given. You get a verdict — not a silent rewrite. If the claim is wrong, better matches come back so the UI can suggest a correction.
- A human or model already attached a verse number
- You need a yes/no before publish
- You want “this looks like Psalm 23, not that ref”
- You are reviewing a batch of extracted claims
- There is no claimed reference — use search
- You need every quote in a transcript — use extract first
- You only want neighbors of a trusted ref — use graph
POST items with quote + reference.
Branch on verdict:
confirmed can ship.
contradicted offer
candidates[0].
uncertain /
unverified do not auto-publish.
Why this call exists Guard rail, not a rewrite
Wrong chapter:verse slips into slides, emails, and captions. Verify is the guard rail: confirm, contradict, or admit uncertainty — and never overwrite the caller’s reference. Your product chooses whether to block, warn, or suggest.
For each item it scores the quote against the claimed passage, then nearby verses. A deterministic scorer decides; embeddings do not vote. An item with no usable reference falls back to ranked search in the same response shape.
Request fields items[].quote + reference
| Field | Type | Required | What it is / how to use it |
|---|---|---|---|
items |
object[] | yes | Batch of claims, 1–200. One item is fine. Use a batch for a review queue. |
items[].quote |
string | yes | The wording you were given. Too short to judge returns unverified. |
items[].reference |
string or object | no | The claimed citation, e.g. "John 3:16" or {"raw":"John 3:16"}. Omit it and this item becomes a reverse-search (still in verify shape). |
items[].id |
string | no | Your id, echoed on the result so you can join a batch back to rows. |
items[].hintVersion |
string | no | Optional corpus id / abbreviation to try first when scoring the claim. |
items[].source |
string | no | Opaque caller metadata (where the claim came from). Not used in scoring. |
translations |
string[] | no | Optional corpus filter for the whole batch. |
Verdicts confirmed · contradicted · uncertain · unverified
| Verdict | What it means | What you should do |
|---|---|---|
| confirmed | The quote matches the claimed passage well enough to trust. | Safe to publish the claim as given. |
| contradicted | A nearby passage fits far better than the claimed one. | Do not ship the claimed ref. Offer candidates[0] as the correction. |
| uncertain | Partial match, or a rival that is not strong enough to contradict. | Ask a human, or show the note. Do not auto-correct. |
| unverified | Too short, not held in the corpus, or no usable reference. | Do not treat as a yes. Use candidates as a search shortlist if present. |
Response fields results[].verdict · candidates[]
| Field | Type | What it is / how to use it |
|---|---|---|
corpusVersion |
string | Corpus this batch was judged against. |
results[] |
object[] | One result per item, same order is not guaranteed — join on id. |
results[].id |
string? | Echo of the item id you sent. |
results[].verdict |
string | The product switch: confirmed / contradicted / uncertain / unverified. |
results[].score |
number | How well the quote matched the claimed passage (not the rival). |
results[].matchedTranslation |
string | null | Corpus id used for the claimed (or best) match. |
results[].candidates[] |
object[] | Better or nearby matches (same shape as search candidates). Empty when confirmed. Suggestions only — never applied for you. |
results[].note |
string? | Why it judged this way. Good copy for a review UI. |
results[].matchedText |
string | null | Held text of the claimed passage when available, for side-by-side review. |
Example intentionally wrong ref
curl -X POST ${ORIGIN}/v1/verify \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"items":[{"id":"1","quote":"The Lord is my shepherd; I shall not want","reference":"John 3:16"}]}'
That example is intentionally wrong. Expect contradicted and a Psalm 23 candidate.
What this deployment holds
Inventory of the live corpus — version stamp plus the translations this Worker can search, verify, and display.
GET once at startup. Cache the list if you have a picker. Do not call it on every search.
Response fields corpusVersion · translations[]
Search and verify only work against what is actually ingested here. Apps call this on boot, and the demo UIs use it as a session check.
| Field | Type | What it is / how to use it |
|---|---|---|
corpusVersion |
string | Stamp of the loaded corpus. Log it with searches if you need to reproduce a result later. |
translations[] |
object[] | What this deployment holds. Use id in translations filters on other calls. |
translations[].id |
string | Corpus id — the value you pass as a filter. |
translations[].name · abbreviation |
string | Display labels if you render a picker. |
translations[].licensed |
boolean | Whether this text is a licensed edition. Always attribute if you display it. |
translations[].books · verses |
number | How much of that edition is actually loaded. |
curl "${ORIGIN}/v1/corpus" -H 'Authorization: Bearer YOUR_TOKEN'
Fetch held verse text
Given a reference you already trust, return the held wording so a UI can display it.
After a search or verify hit, GET
?translation=…&ref=John+3:16.
Always show attribution. This does not rank or guess.
Request & response ref · translation · text
Search, extract, and verify find and judge. Passage is for showing — license and attribution stay in one place.
| Field | Type | Required | What it is / how to use it |
|---|---|---|---|
ref |
string | yes* | Human reference, e.g. John 3:16 or Psalm 23:1-3. *Or pass path parts instead: /v1/passage/{translation}/{book}/{chapter}/{verse}. |
translation |
string | yes* | Corpus id from /v1/corpus. Required with ref unless you use the path form. |
| Field | Type | What it is / how to use it |
|---|---|---|
translation · name |
string | Which edition you fetched. |
bookUsfm · chapter · verseFrom · verseTo |
string / number | Parsed location. Use these if you need structured keys, not just display text. |
text |
string | The held wording. This is what you put on screen. |
attribution |
string | Required publisher credit. Show it next to the verse. |
licensed |
boolean | Whether this edition is licensed. Still attribute either way. |
curl "${ORIGIN}/v1/passage?translation=bsb&ref=John+3:16" \
-H 'Authorization: Bearer YOUR_TOKEN'
Show what sits around the hit
Once you already have a reference, these GET routes return the neighborhood —
linked passages, people, themes, concepts, and promise/fulfillment links.
They do not reverse-search wording. Same Bearer (or demo cookie) as the rest of /v1.
Multi-hop cross-reference neighborhood around one verse. This is the “related scripture” panel and the 3D passage map.
GET with the winning ref.
depth=1 for a related rail;
depth=2 for a map. Read
nodes and edges.
Query & response ref · depth · nodes[]
Finding the verse is half the product. Subgraph answers “what else connects?” without another reverse search.
| Field | Type | Default | What it is / how to use it |
|---|---|---|---|
ref |
string | required | Center verse, e.g. John 3:16. Aliases: key, verse. |
depth |
number | 2 | Hops from the center. Use 1 for a compact rail, 2 for a map. |
limit |
number | 22 | Max neighbors off the center. Alias: limit_center. |
limit_per_node |
number | 8 | Max neighbors expanded from each hop-1 node at depth 2. |
translation |
string | held default | Which edition to hydrate text from. The graph itself is translation-independent. |
text |
0 | 1 | 1 | Pass text=0 if you only need structure and will fetch wording via /v1/passage. |
| Field | What it is / how to use it |
|---|---|
center |
The verse you asked about, plus optional held text. |
nodes[] |
Each related verse: display, hop (1 or 2), via (parent), optional text, plus timeline labels for a map. |
edges[] |
Why two nodes connect: ref_type, votes, strength, notes. |
stats |
Counts by hop and type — useful for a footer (“12 links · 4 quotations”). |
curl "${ORIGIN}/v1/graph/subgraph?ref=John+3:16&depth=2&limit=12" \
-H 'Authorization: Bearer YOUR_TOKEN'
More graph routes neighbors · people · themes · concepts
One hop of related verses — the lighter cousin of subgraph when you only need a list, not a map.
Query: ref (required), optional types (comma-separated link types), limit (default 40), min_votes, text=0 to skip wording.
Everyone named in the story units — counts, first appearance, companions. This is the people map.
Use it after a search hit when you want “who else is in this story?” or a browse index of people. Drill in with /v1/graph/explore/person/David for that person’s thread of passages.
Query: limit (default 280), min_cooccur (default 2) to hide weak companion edges.
Themes that run through the story units — the theme map and tag cloud.
Use it for a “kingdom / covenant / exile” browse, or to chip-tag a result. Drill in with /v1/graph/explore/theme/kingdom for the passages under that theme.
Query: limit, min_cooccur, optional testament=ot|nt or book=JHN.
Curriculum + doctrine graph — Foundations topics and courses, plus the gospel thread. Not the same as theme chips.
/v1/graph/concepts lists them.
/concepts/map is the overview.
/concepts/{id} is the bundle of passages.
/concepts/{id}/trajectory is how that concept moves through Scripture.
Kinds: topic (Nature of God, Soteriology, … — the mapping surface), course (F-101–A-304), practice (maturity markers), plus the original doctrine / theme / event seed. Edges are requires, builds_on, and covers.
Promise and fulfillment links for a verse: what this passage answers, and where this promise is answered.
Query: ref (required). Use next to a prophetic or gospel hit when the product question is “where is this kept?”
Graph inventory — how many verse links and concepts this deployment has. Good for a health/status line, not for a product panel.
Interactive UI: /graph · people /graph/people · passage /graph/passages
Live playground
Run the same routes against this alpha while you’re signed into the demo.
Production integrations should send Authorization: Bearer YOUR_TOKEN.
// Run a request