Search passages
Searches the library with hybrid semantic and keyword retrieval, reranked for relevance. Returns passages with their book, author, printed pages and a link to the printed page. To restrict results to an author or book, resolve its name to an ID with GET /catalog/lookup first. Body fields not listed here are refused with a 422.
/searchAuthorizationBearer token · headerrequiredAn API key from qaf.ai Settings › API keys.
application/jsonquerystringrequiredWhat to search for, in Arabic or English.
filtersobjectRestrict results by author, book, death year or genre. Filters match a passage's book and author, not what the passage mentions.
Show propertiesHide properties
authorIdsinteger[]Author IDs, from GET /catalog/lookup or a passage's author.id.
bookIdsstring<uuid>[]Book IDs, from GET /catalog/lookup or a passage's book.id.
deathYearAHobjectBounds on the author's death year, in AH. Give at least one; all must hold.
Show propertiesHide properties
gtintegergteintegerltintegerlteintegergenresstring[]Genre slugs. A genre describes a book, not a topic, so use one only to search books of that genre.
filterOperatorstringCombine supplied filter dimensions with AND (default) or OR. Values within each ID list always use OR; all death-year bounds must hold together.
ANDORlimitintegerPassages to return.
excludeIdsstring<uuid>[]IDs of passages you already have; the search skips them. Pass the IDs from earlier results to get further passages for the same query.
localestringLanguage for book and author names; Arabic names are always included.
arenThe matching passages, ranked by relevance.
resultsobject[]requiredShow propertiesHide properties
objectidstring<uuid>requiredStable passage ID. Read it with GET /passages/{id}, or skip it in a later search with excludeIds.
titlestringrequiredBook, author and printed page.
urlstring<uri>requiredOpens the printed page in the Turath reader; cite it.
textstringrequiredThe passage's Arabic text as printed in the edition, with vowel marks where the edition has them.
footnotesstringpagesobject[]requiredPrinted volume and page numbers the passage spans.
Show propertiesHide properties
objectvolstring | nullrequiredShow propertiesHide properties
stringnullpagenumber | nullrequiredShow propertiesHide properties
numbernullbookobjectrequiredShow propertiesHide properties
idstring<uuid>requiredtitlestringrequiredtitleArabicstringrequiredauthorobjectrequiredShow propertiesHide properties
idintegerrequirednamestringrequirednameArabicstringrequiredversionIdintegerrequiredThe printed edition the passage comes from.
sequenceNumberintegerrequiredPosition within the edition.
The request can't be processed as sent, such as a filter with an unknown author ID. data.reason, when present, says why.
codestringrequiredBAD_REQUESTstatusintegerrequiredmessagestringrequireddataobjectShow propertiesHide properties
reasonstringThe API key is missing, invalid or revoked.
codestringrequiredUNAUTHORIZEDstatusintegerrequiredmessagestringrequiredThe key's account can't use the API.
codestringrequiredFORBIDDENstatusintegerrequiredmessagestringrequiredThe request body is larger than 64 KiB.
codestringrequiredPAYLOAD_TOO_LARGEstatusintegerrequiredmessagestringrequiredA field is invalid. data.fieldErrors lists the problems by field.
codestringrequiredINPUT_VALIDATION_FAILEDstatusintegerrequiredmessagestringrequireddataobjectShow propertiesHide properties
formErrorsstring[]requiredfieldErrorsobjectrequiredToo many requests; data.reason says which limit was reached. For minute, the account's requests per minute, retry after Retry-After seconds. For day, the account's daily search cap, Retry-After is the time until the cap resets. For invalid_keys, the key doesn't exist or was revoked and this address has sent too many such keys, so fix the key rather than retrying. The X-RateLimit headers describe the account's minute window, so an invalid_keys refusal, which comes before any key is known, has none.
codestringrequiredRATE_LIMITEDstatusintegerrequiredmessagestringrequireddataobjectShow propertiesHide properties
retryAfterintegerrequiredSeconds to wait.
reasonstringrequiredWhich limit was reached: minute, the account's requests per minute; day, its searches per day; or invalid_keys, a key that doesn't exist or was revoked, from an address that has sent too many such keys.
minutedayinvalid_keysSomething went wrong on our side.
codestringrequiredINTERNAL_SERVER_ERRORstatusintegerrequiredmessagestringrequiredQaf could not complete the request in time, or a service it relies on is unavailable. Retry shortly.
codestringrequiredSERVICE_UNAVAILABLEstatusintegerrequiredmessagestringrequired