{"openapi":"3.1.0","info":{"title":"CTAI API","version":"1.0.0","description":"Concordance-consistent linguistic analysis and AI translation of Arabic and Persian Bahá'í texts. The Jafar concordance engine indexes 105,000+ occurrences across 4,000+ roots from Shoghi Effendi's translations.","contact":{"name":"CTAI","url":"https://ctai.info"}},"servers":[{"url":"https://ctai.info/api/v1","description":"Production"}],"security":[{"bearerAuth":[]}],"paths":{"/":{"get":{"summary":"OpenAPI specification","description":"Returns this OpenAPI 3.1 JSON spec. No authentication required.","security":[],"responses":{"200":{"description":"OpenAPI spec","content":{"application/json":{}}}}}},"/jafar":{"post":{"summary":"Jafar enrichment report","description":"Full linguistic enrichment for an Arabic or Persian passage. Tokenizes the source text, looks up every root in the Jafar concordance, and returns rendering spectrums, forms, and cross-references. By default, Haiku scores each root for relevance to the passage and prunes noise.\n\n**`rendering_spectrum` vs `se_rendering`:** `rendering_spectrum` is the corpus-wide frequency of how a root is rendered across all books — always populated. `se_rendering` is Shoghi Effendi’s choice *for this specific passage*, and it is only filled when you supply the paired `translation` **and** `alignment`; with bare source text there is no pair to anchor to, so it comes back empty (by design — the endpoint will not guess the passage-specific choice from the corpus-wide spectrum).\n\n**To get the passage-specific rendering without doing alignment yourself, use `GET /passages`** — its `aligned[].translation` (and `phrase` in granularity=phrase) is SE’s rendering of that exact phrase, read straight from the corpus. `/jafar` answers “what does this root mean across the corpus”; `/passages` answers “what did SE do here”.\n\nInput must be Arabic/Persian source text. English input returns `term_count: 0` (no roots to tokenize).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string","description":"Arabic or Persian source text"},"source_lang":{"type":"string","enum":["ar","fa"],"default":"ar"},"translation":{"type":"string","description":"Optional English translation. Supply together with alignment to populate se_rendering (the passage-specific SE rendering)."},"alignment":{"type":"array","description":"Optional precomputed alignment pairs (same shape as /passages aligned[]). Required alongside translation to fill se_rendering."},"filter":{"type":"boolean","default":true,"description":"Use AI relevance filtering to prune irrelevant roots (costs ~$0.001)"}}}}}},"responses":{"200":{"description":"Enrichment report","content":{"application/json":{"schema":{"type":"object","properties":{"source_text":{"type":"string"},"source_lang":{"type":"string"},"gloss":{"type":"string","description":"Word-by-word gloss of the source"},"enriched_terms":{"type":"array","items":{"$ref":"#/components/schemas/EnrichedTerm"}},"term_count":{"type":"integer"},"filtered":{"type":"boolean"},"filter_cost_usd":{"type":"number"}}}}}}}}},"/concordance":{"post":{"summary":"Quick phrase lookup","description":"Lighter than /jafar — returns matching roots and occurrences for an Arabic/Persian phrase without full enrichment or filtering.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["phrase"],"properties":{"phrase":{"type":"string","description":"Arabic or Persian word/phrase to look up"},"source_lang":{"type":"string","enum":["ar","fa"],"default":"ar"}}}}}},"responses":{"200":{"description":"Concordance results"}}}},"/english/{word}":{"get":{"summary":"English rendering spectrum","description":"Given an English word, returns every Arabic/Persian root that Shoghi Effendi translated as that word. Each root includes its full rendering spectrum (all English words this root was translated as, with counts), Arabic forms seen, and example references. Use this to understand the semantic range of a translation choice.","parameters":[{"name":"word","in":"path","required":true,"schema":{"type":"string"},"description":"English word slug (e.g., \"glory\", \"sovereignty\", \"light\")"}],"responses":{"200":{"description":"Word analysis","content":{"application/json":{"schema":{"type":"object","properties":{"word":{"type":"string"},"slug":{"type":"string"},"total_occurrences":{"type":"integer"},"root_count":{"type":"integer"},"roots":{"type":"array","items":{"$ref":"#/components/schemas/EnglishWordRoot"}},"see_also":{"type":"array","items":{"type":"object","properties":{"word":{"type":"string"},"slug":{"type":"string"},"count":{"type":"integer"}}}}}}}}},"404":{"description":"No occurrences found"}}}},"/roots":{"get":{"summary":"Search/browse roots","description":"List or search Arabic/Persian roots in the Jafar concordance.","parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Search by transliteration, meaning, or Arabic script"},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Root list","content":{"application/json":{"schema":{"type":"object","properties":{"roots":{"type":"array","items":{"$ref":"#/components/schemas/Root"}},"count":{"type":"integer"},"offset":{"type":"integer"}}}}}}}}},"/roots/{slug}":{"get":{"summary":"Root detail with rendering spectrum","description":"Full detail for a single root: all English renderings with frequency counts, Arabic forms, and related roots.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"Root slug (e.g., \"n-w-r\", \"z-h-r\")"}],"responses":{"200":{"description":"Root detail","content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string"},"root":{"type":"string"},"transliteration":{"type":"string"},"meaning":{"type":"string"},"is_name":{"type":"boolean"},"occurrence_count":{"type":"integer"},"rendering_count":{"type":"integer"},"rendering_spectrum":{"type":"array","items":{"$ref":"#/components/schemas/SpectrumEntry"}},"related_roots":{"type":"array","items":{"$ref":"#/components/schemas/Root"}}}}}}},"404":{"description":"Root not found"}}}},"/passages":{"get":{"summary":"Find parallel-text passages by phrase","description":"Find text in the parallel corpus (original ↔ Shoghi Effendi translation) and get it back in **both languages**. No AI — every pairing is read straight from the precomputed corpus alignment. Built to be driven by an AI agent; the two modes below cover the common questions.\n\n**Mode 1 — phrase search (pass `q`).** Locate the phrase across the corpus, ranked by BM25. Search either language; Arabic is diacritic-insensitive (vocalized or not, both match). Scope to a book with `work`.\n\n**Mode 2 — reference lookup (pin a passage in a book).** Pass `work` plus **either** `section` **or** `pair_index`. `section` is **how people cite** — Gleanings #29, a named passage, etc. It accepts the canonical section number as arabic **or** Roman (`29` and `XXIX` both resolve), or the section page-slug / words from it (`knowledge-of-own-selves`, or just `justice`). A citation like “Gleanings #29” almost always means this — use `section`, not `pair_index`. `pair_index` is the **internal flat index** (the trailing number in a /models/{slug}/{n}/ URL); it does not equal the citation number (Gleanings #29 = section XXIX = pair_index 133), so use it only when you literally have that URL. Add `q` to find a phrase *inside* the pinned passage: `?work=gleanings&section=135&q=the Báb&in=en&granularity=phrase` → read `results[0].phrase.source`. Omit `q` for the whole passage pair plus full `aligned[]`. Every result carries `section` and `page_slug` for citing back. If a phrase was rendered periphrastically (no single original term), `phrase` is `null` and `phrase_note` says so — fall back to `granularity=sentence`.\n\n**`granularity` sets how much text comes back:** `paragraph` (full original + full translation), `sentence` (just the matched sentence, both languages), `phrase` (just the matched phrase, both languages — e.g. `\"fire of separation\"` ↔ `\"نَارِ الفِرَاقِ\"`).\n\nEvery mode also returns `aligned[]`: the phrase-level pairs overlapping your match. **`aligned[].translation` is Shoghi Effendi’s rendering of that exact phrase in this exact passage** — the passage-specific, interpretive choice. That differs from `/jafar`’s `rendering_spectrum`, which is the corpus-wide frequency of how a root is rendered across all books. Use `/passages` for “what did SE do *here*”; use `/jafar` for “what does this root mean *across the corpus*”.","parameters":[{"name":"q","in":"query","schema":{"type":"string"},"example":"fire of separation","description":"Phrase to find, in English or Arabic/Persian. Required unless you pass work + pair_index. With work + pair_index, q restricts the match to inside that one paragraph. Arabic need not be vocalized."},{"name":"in","in":"query","schema":{"type":"string","enum":["both","en","source"],"default":"both"},"example":"en","description":"Which side q searches: `en` = English translation, `source` = original Arabic/Persian, `both` = either. Set `en` when q is an English rendering you want the original of."},{"name":"match","in":"query","schema":{"type":"string","enum":["contains","starts"],"default":"contains"},"example":"contains","description":"`contains` = phrase anywhere in the paragraph; `starts` = paragraph begins with the phrase (leading ornaments/quotes skipped)."},{"name":"work","in":"query","schema":{"type":"string"},"example":"gleanings","description":"Book filter (partial, case-insensitive slug or title), e.g. \"gleanings\", \"iqan\", \"hidden words\". Required when pair_index is given."},{"name":"pair_index","in":"query","schema":{"type":"integer"},"example":31,"description":"Reference lookup by passage number: the flat paragraph index within `work` (the trailing number in a /models/{slug}/{n}/ URL). Requires `work`. Combine with `q` to find a phrase inside that paragraph."},{"name":"section","in":"query","schema":{"type":"string"},"example":"29","description":"Reference lookup by canonical citation — how humans cite the passage. Accepts the section number in arabic OR Roman (\"29\" and \"XXIX\" both resolve to Gleanings §XXIX), or the section page-slug / words from it (\"knowledge-of-own-selves\", \"justice\"). Requires `work`. Combine with `q` to find a phrase inside the section. Prefer this over pair_index for citations like \"Gleanings #29\". Use section OR pair_index, not both."},{"name":"granularity","in":"query","schema":{"type":"string","enum":["paragraph","sentence","phrase"],"default":"paragraph"},"example":"phrase","description":"How much text to return: `paragraph` (full pair), `sentence` (matched sentence pair), or `phrase` (just the matched phrase pair). Ignored for a reference lookup with no q."},{"name":"align","in":"query","schema":{"type":"boolean","default":true},"example":true,"description":"Include `aligned[]` — the SE-rendered phrase pairs overlapping the match. Set false to omit and shrink the payload."},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100},"example":5},{"name":"offset","in":"query","schema":{"type":"integer","default":0},"example":0,"description":"Skip this many results (pagination)."}],"responses":{"200":{"description":"Matching passages","content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string"},"in":{"type":"string"},"match":{"type":"string"},"granularity":{"type":"string"},"total":{"type":"integer","description":"Total matches across the corpus (before limit/offset)"},"count":{"type":"integer","description":"Results returned in this page"},"limit":{"type":"integer"},"offset":{"type":"integer"},"results":{"type":"array","items":{"$ref":"#/components/schemas/Passage"}}}},"examples":{"reference_lookup":{"summary":"Reference lookup — \"original term translated as 'the Báb' in Gleanings #31\"","description":"work + pair_index pins the paragraph; q + in=en + granularity=phrase find the phrase inside it. Read results[0].phrase.source for the Arabic/Persian original.","value":{"query":"the Báb","in":"en","match":"contains","granularity":"phrase","work":"gleanings","pair_index":31,"total":1,"count":1,"limit":20,"offset":0,"results":[{"work":{"slug":"gleanings","title":"Gleanings","author":"Bahá'u'lláh"},"pair_index":31,"url":"/models/gleanings/31/","bm25_score":null,"matched_in":["en"],"match_span":{"side":"en","start":210,"end":217},"phrase":{"source":"نبیل","translation":"the Báb","source_span":[87,91],"target_span":[210,217]}}]}},"section_lookup":{"summary":"Section lookup — a passage cited by section name","description":"work + section pins the passage by its page-slug (case/spacing normalized). Every result carries section + page_slug for citing back.","value":{"query":null,"in":"both","match":"contains","granularity":"paragraph","work":"the-hidden-words","section":"justice","total":1,"count":1,"limit":20,"offset":0,"results":[{"work":{"slug":"the-hidden-words","title":"The Hidden Words","author":"Bahá'u'lláh"},"pair_index":3,"section":"5","page_slug":"justice-see-with-thine-own-eyes","url":"/models/the-hidden-words/3/","bm25_score":null,"source_text":"(٢) ﴿ يَا ابْنَ الرُّوحِ ﴾ أَحَبُّ الأَشْيَاءِ عِنْدِي الإنْصافُ …","translation":"(2) O SON OF SPIRIT! The best beloved of all things in My sight is Justice …","aligned":[{"source":"الإنْصافُ","translation":"Justice","source_span":[40,49],"target_span":[52,59]}]}]}},"phrase":{"summary":"granularity=phrase — just the matched phrase, both languages","value":{"query":"fire of separation","in":"en","match":"contains","granularity":"phrase","total":1,"count":1,"limit":5,"offset":0,"results":[{"work":{"slug":"fire-tablet","title":"Fire Tablet","author":"Bahá'u'lláh"},"pair_index":1,"url":"/models/fire-tablet/1/","bm25_score":-6.12,"matched_in":["en"],"match_span":{"side":"en","start":115,"end":133},"phrase":{"source":"نَارِ الفِرَاقِ","translation":"fire of separation","source_span":[80,89],"target_span":[115,133]},"aligned":[{"source":"نَارِ","translation":"fire","source_span":[80,85],"target_span":[115,119]},{"source":"الفِرَاقِ","translation":"of separation","source_span":[86,95],"target_span":[120,133]}]}]}},"sentence":{"summary":"granularity=sentence — the matched sentence, both languages","value":{"query":"chain of successive Revelations","in":"en","match":"contains","granularity":"sentence","total":1,"count":1,"limit":5,"offset":0,"results":[{"work":{"slug":"gleanings","title":"Gleanings","author":"Bahá'u'lláh"},"pair_index":135,"url":"/models/gleanings/135/","bm25_score":-4.73,"matched_in":["en"],"match_span":{"side":"en","start":38,"end":69},"sentence":{"en":"Contemplate with thine inward eye the chain of successive Revelations that hath linked the Manifestation of Adam with that of the Báb.","source":"فانظر بطرف البدء فیما نظرت إلی آدم الأولی ثمّ من بعده إلی أن یصل الأمر إلی عَلِيٍّ قبل نبیل"},"aligned":[{"source":"فانظر","translation":"Contemplate","source_span":[0,5],"target_span":[0,11]},{"source":"الأمر","translation":"the chain of successive Revelations","source_span":[65,70],"target_span":[34,69]}]}]}},"paragraph":{"summary":"granularity=paragraph — full original + full translation","value":{"query":"chain of successive Revelations","in":"en","match":"contains","granularity":"paragraph","total":1,"count":1,"limit":5,"offset":0,"results":[{"work":{"slug":"gleanings","title":"Gleanings","author":"Bahá'u'lláh"},"pair_index":135,"url":"/models/gleanings/135/","bm25_score":-4.73,"matched_in":["en"],"match_span":{"side":"en","start":38,"end":69},"source_text":"فانظر بطرف البدء فیما نظرت إلی آدم الأولی … (full original paragraph)","translation":"Contemplate with thine inward eye the chain of successive Revelations … (full translated paragraph)","aligned":[{"source":"الأمر","translation":"the chain of successive Revelations","source_span":[65,70],"target_span":[34,69]}]}]}}}}}},"400":{"description":"Missing query (q is required)"}}}},"/covers":{"get":{"summary":"List book cover images","description":"Browse every book across all collections (library translations, parallel-text corpus works, Qur’án suras) with a ready-to-use cover image URL. Pass width/format to get a sized, format-optimized link. Cover images are served from an image CDN.","parameters":[{"name":"collection","in":"query","schema":{"type":"string","enum":["library","corpus","quran"]},"description":"Restrict to one collection"},{"name":"author","in":"query","schema":{"type":"string"},"description":"Filter by author name or slug (partial)"},{"name":"q","in":"query","schema":{"type":"string"},"description":"Search title/author (partial)"},{"name":"has_cover","in":"query","schema":{"type":"boolean"},"description":"Only books that have a cover image"},{"name":"width","in":"query","schema":{"type":"integer","minimum":16,"maximum":2000},"description":"Cover width in px (CDN-resized); height scales to keep aspect"},{"name":"format","in":"query","schema":{"type":"string","enum":["webp","avif","png","jpg"]},"description":"Image format; omit for auto"},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":500}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Books with cover links","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"integer"},"count":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"results":{"type":"array","items":{"$ref":"#/components/schemas/Cover"}}}}}}}}}},"/covers/{id}":{"get":{"summary":"Cover image link for one book","description":"Return the cover image URL for a single book by its id (library doc_id, corpus slug, or Qur’án sura slug). Pass width/format to size it.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Book id (e.g. \"fire-tablet\", \"quran-al-fatihah\", or a library doc_id)"},{"name":"collection","in":"query","schema":{"type":"string","enum":["library","corpus","quran"]},"description":"Disambiguate if the same id exists in multiple collections"},{"name":"width","in":"query","schema":{"type":"integer","minimum":16,"maximum":2000},"description":"Cover width in px (CDN-resized)"},{"name":"format","in":"query","schema":{"type":"string","enum":["webp","avif","png","jpg"]},"description":"Image format; omit for auto"}],"responses":{"200":{"description":"Cover link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Cover"}}}},"404":{"description":"No book with that id"}}}},"/translate":{"post":{"summary":"Submit text for AI translation","description":"Translates Arabic or Persian text using the CTAI pipeline (concordance-informed, Shoghi Effendi-consistent terminology). Admin users are not billed. Non-admin users are charged via Stripe at 2x AI cost.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","lang"],"properties":{"text":{"type":"string","description":"Arabic or Persian source text"},"lang":{"type":"string","enum":["ar","fa"]},"style":{"type":"string","default":"literary","description":"Translation style"},"return_url":{"type":"string","description":"Redirect URL after Stripe payment"},"cancel_url":{"type":"string","description":"Redirect URL on payment cancel"}}}}}},"responses":{"201":{"description":"Job created","content":{"application/json":{"schema":{"type":"object","properties":{"job_id":{"type":"string"},"status":{"type":"string","enum":["processing","pending_payment"]},"poll_url":{"type":"string"}}}}}}}}},"/translate/estimate":{"post":{"summary":"Estimate translation cost","description":"Returns cost estimate for translating the given text without starting a job.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","lang"],"properties":{"text":{"type":"string"},"lang":{"type":"string","enum":["ar","fa"]}}}}}},"responses":{"200":{"description":"Cost estimate"}}}},"/translate/{jobId}":{"get":{"summary":"Translation job status","description":"Poll for status of a submitted translation job. Returns the translated text when complete.","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Job status"},"404":{"description":"Job not found"}}}},"/keys":{"post":{"summary":"Create API key","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","default":"Default","maxLength":64}}}}}},"responses":{"201":{"description":"Key created (save the key — cannot be retrieved again)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}}}},"get":{"summary":"List API keys","responses":{"200":{"description":"All keys for this user","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}}}}},"/keys/{id}":{"delete":{"summary":"Revoke API key","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Key revoked"}}},"patch":{"summary":"Rename API key","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":64}}}}}},"responses":{"200":{"description":"Key renamed"}}}},"/keys/{id}/rotate":{"post":{"summary":"Rotate API key","description":"Revokes the existing key and creates a new one with the same name.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"New key created, old key revoked"}}}},"/billing/setup":{"post":{"summary":"Save payment method","description":"Creates a Stripe SetupIntent for saving a card. Use the returned client_secret with Stripe.js.","responses":{"200":{"description":"Setup intent details"}}}},"/billing/method":{"get":{"summary":"Check saved payment method","responses":{"200":{"description":"Payment method status"}}}},"/usage":{"get":{"summary":"Usage breakdown","parameters":[{"name":"key_id","in":"query","schema":{"type":"string"},"description":"Filter to a specific key"},{"name":"days","in":"query","schema":{"type":"integer","default":30,"maximum":365}}],"responses":{"200":{"description":"Usage by service and date"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from POST /api/v1/keys. Format: Authorization: Bearer ctai_<key>"}},"schemas":{"AlignedPair":{"type":"object","description":"A precomputed phrase pair from the corpus alignment","properties":{"source":{"type":"string","description":"Original phrase (Arabic/Persian)","example":"نَارِ"},"translation":{"type":"string","description":"Shoghi Effendi rendering of that phrase","example":"fire"},"source_span":{"type":"array","items":{"type":"integer"},"description":"[start,end] char offsets into source_text"},"target_span":{"type":"array","items":{"type":"integer"},"description":"[start,end] char offsets into translation"}}},"Passage":{"type":"object","description":"A corpus paragraph matched by phrase search. Which of source_text/translation, sentence, or phrase is present depends on granularity; aligned[] is present in all modes unless align=false.","properties":{"work":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"author":{"type":"string"}}},"pair_index":{"type":"integer","description":"Flat paragraph index within the work (the number in the /models URL)"},"section":{"type":"string","nullable":true,"description":"Section label this paragraph belongs to (e.g. Gleanings \"XXIX\", the Will's Part \"1\"); may be null for flat works"},"section_index":{"type":"string","nullable":true,"description":"Canonical section.paragraph citation, e.g. \"XXIX.2\" (section XXIX, 2nd paragraph). For flat works this is just the paragraph number."},"section_para":{"type":"integer","nullable":true,"description":"Paragraph number within the section (the part after the dot in section_index)"},"page_slug":{"type":"string","nullable":true,"description":"Section name-slug for this passage, e.g. \"knowledge-of-own-selves\" — pass it back as ?section= to re-fetch"},"url":{"type":"string","example":"/models/fire-tablet/1/","description":"Canonical page for this paragraph on ctai.info"},"bm25_score":{"type":"number","nullable":true,"description":"BM25 relevance (lower is better); null in dev"},"matched_in":{"type":"array","items":{"type":"string","enum":["en","source"]},"description":"Which side(s) contained the phrase"},"match_span":{"type":"object","description":"Char offsets of the hit on the matched side","properties":{"side":{"type":"string","enum":["en","source"]},"start":{"type":"integer"},"end":{"type":"integer"}}},"source_text":{"type":"string","description":"Full original paragraph (granularity=paragraph only)"},"translation":{"type":"string","description":"Full translated paragraph (granularity=paragraph only)"},"sentence":{"type":"object","description":"Matched sentence in both languages (granularity=sentence only)","properties":{"en":{"type":"string","nullable":true},"source":{"type":"string","nullable":true}}},"phrase":{"$ref":"#/components/schemas/AlignedPair","description":"The matched phrase itself, both languages, merged from the overlapping alignment (granularity=phrase only). null when the phrase was rendered periphrastically — see phrase_note."},"phrase_note":{"type":"string","description":"Present only when granularity=phrase matched an English phrase that has no single corresponding original term (periphrastic rendering). Explains the null phrase and points to granularity=sentence."},"aligned":{"type":"array","items":{"$ref":"#/components/schemas/AlignedPair"},"description":"Phrase pairs overlapping the match. translation = Shoghi Effendi’s rendering of that phrase in THIS passage (interpretive, passage-specific — not the corpus-wide spectrum from /jafar)."}}},"Cover":{"type":"object","description":"A book with its cover image link","properties":{"id":{"type":"string","example":"fire-tablet"},"collection":{"type":"string","enum":["library","corpus","quran"]},"title":{"type":"string"},"title_original":{"type":"string","nullable":true},"title_english":{"type":"string","nullable":true},"author":{"type":"string"},"author_slug":{"type":"string","nullable":true},"index":{"type":"integer","description":"Qur’án sura number (quran collection only)"},"has_cover":{"type":"boolean"},"cover_image":{"type":"string","nullable":true,"description":"Versioned source path","example":"/covers/fire-tablet_v1.png"},"cover_url":{"type":"string","nullable":true,"description":"Ready-to-use CDN image URL (sized if width/format given)","example":"https://ik.imagekit.io/1260/tr:f-auto,w-400/fire-tablet_v1.png"}}},"Root":{"type":"object","properties":{"slug":{"type":"string","example":"n-w-r"},"root":{"type":"string","example":"ن-و-ر","description":"Arabic root letters"},"transliteration":{"type":"string","example":"n-w-r"},"meaning":{"type":"string","example":"light; illuminate"},"is_name":{"type":"boolean"},"occurrence_count":{"type":"integer"}}},"SpectrumEntry":{"type":"object","description":"One English rendering with its frequency in the corpus","properties":{"rendering":{"type":"string","example":"light"},"count":{"type":"integer","example":89},"pct":{"type":"integer","description":"Percentage of total occurrences for this root"},"forms":{"type":"array","items":{"type":"string"},"description":"Arabic forms that produced this rendering"}}},"EnrichedTerm":{"type":"object","description":"A term from the Jafar concordance enrichment pipeline","properties":{"term":{"type":"string"},"root":{"type":"string"},"transliteration":{"type":"string"},"literal":{"type":"string"},"se_rendering":{"type":"string","description":"Shoghi Effendi’s rendering of this term in THIS passage. Only populated when the request supplied translation + alignment; empty otherwise. For the passage rendering without supplying alignment, use GET /passages (aligned[].translation)."},"note":{"type":"string"},"occurrence_count":{"type":"integer"},"rendering_spectrum":{"type":"array","items":{"$ref":"#/components/schemas/SpectrumEntry"}},"is_deviation":{"type":"boolean"},"deviation_label":{"type":"string","nullable":true,"enum":["unique","distinctive",null]},"forms_in_passage":{"type":"array","items":{"type":"object","properties":{"form":{"type":"string"},"translit":{"type":"string"},"se":{"type":"string"}}}},"cross_refs":{"type":"array","description":"Up to 8 example usages from other passages, diversified across works","items":{"type":"object","properties":{"work":{"type":"string"},"para":{"type":"integer"},"snippet":{"type":"string","description":"English rendering in context"}}}}}},"EnglishWordRoot":{"type":"object","description":"A root that produces a given English rendering","properties":{"root":{"type":"string"},"slug":{"type":"string"},"transliteration":{"type":"string"},"meaning":{"type":"string"},"occurrence_count":{"type":"integer","description":"How many times this root → this English word"},"total_root_occurrences":{"type":"integer","description":"Total occurrences of this root across all renderings"},"pct_of_root":{"type":"integer","description":"What % of this root's occurrences are rendered as this word"},"forms":{"type":"array","items":{"type":"object","properties":{"form":{"type":"string"},"count":{"type":"integer"}}}},"rendering_spectrum":{"type":"array","items":{"$ref":"#/components/schemas/SpectrumEntry"}},"examples":{"type":"array","items":{"type":"object","properties":{"work":{"type":"string"},"para":{"type":"integer"},"form":{"type":"string"},"rendering":{"type":"string"}}}}}},"ApiKey":{"type":"object","properties":{"id":{"type":"string"},"key_prefix":{"type":"string","example":"ctai_abc1"},"name":{"type":"string"},"created_at":{"type":"string"},"last_used":{"type":"string","nullable":true},"revoked":{"type":"boolean"}}}}}}