Search Content

Search across document content in one or more libraries. Returns ranked passages (document parts) with full document metadata. Supports neural (semantic) and keyword search modes.

GET /api/search

Authentication

Requires a Bearer token. See Getting Started.

Authorization: Bearer <your-api-key>

Query parameters

ParameterTypeDefaultDescription
searchstringRequiredSearch query. Supports advanced query syntax.
modestring"neural"Search mode: "neural" or "keyword".
rerankbooleanfalseFor neural search, rerank grouped documents using the title, author, headings, and useful passages. Adds latency but improves precision.
librariesstring[]["private"]Libraries to search. Pass multiple values with libraries=a&libraries=b or libraries[]=a&libraries[]=b.
pageinteger1Page number (1-indexed).
per_pageinteger10Results per page. Min: 1, Max: 100.
authorstring—Filter by author name (partial match).
publication_datestring—Filter by publication year.
isbnstring—Filter by ISBN or ISBN-13.
idstring—Filter by a specific document ID.
document_idstring—Search within a specific document.
collection_idsstring[]—Restrict results to documents in these collections. Every value must be a collection UUID — get them from GET /api/document-collections. Repeatable: collection_ids=a&collection_ids=b (or collection_ids[]=a&collection_ids[]=b).
teamstring—Team slug. Automatically inferred from your API key if not provided.
user_idstring—User ID for private library access. Automatically inferred from session-based auth.

Response

Success response

{
  "data": [SearchResult],
  "count": 42,
  "error": null
}
FieldTypeDescription
dataSearchResult[]Array of matching document parts.
countintegerEstimated total number of results (for pagination).
errornullnull on success.

SearchResult object

FieldTypeDescription
idstringUnique ID of the document part.
created_atstringISO 8601 timestamp.
document_idstringID of the parent document.
indexstring | numberURN reference within the document (e.g. urn:vulgate:doc-id:section), or a numeric position.
content_renderedstring | nullHTML-rendered content of the matching passage.
headingsstring[] | nullSection headings associated with this passage.
languagestring | nullISO language code (e.g. "en", "la", "grc").
namespacestringTeam slug / namespace the result belongs to.
relevance_scorenumber | nullDocument-level reranker score when rerank=true succeeds; otherwise null.
documentsobjectParent document metadata (see below).

Documents object

FieldTypeDescription
idstringDocument ID.
titlestring | nullDocument title.
authorstring | nullAuthor name.
publication_datestring | nullPublication year.
publication_placestring | nullPlace of publication.
isbnstring | nullISBN-10.
isbn_13string | nullISBN-13.
publisherstring | nullPublisher name.
product_urlstring | nullCanonical product page associated with the document.
document_formatstring | nullDocument format (e.g. "PDF", "MEDIA", "DOC").
scopestring | nullVisibility scope: "private", "shared", or "organization".

Error response

{
  "data": null,
  "count": 0,
  "error": {
    "code": "no-libraries-selected",
    "message": "No libraries selected"
  }
}
HTTP StatusError CodeDescription
400—Validation error (invalid parameters).
400no-libraries-selectedNo libraries were included in the request.
400private-library-no-user-idPrivate library requires a user_id.
400invalid-collection-idscollection_ids contained at least one empty value. A malformed (non-UUID) value returns the generic validation error above instead.
401—Missing or invalid authentication.
403—Magisterium AI library requires a paid plan.
404collection-not-foundOne or more requested collections do not exist or are not visible to you.
404team-not-foundThe team slug does not match a team.
500collection-lookup-failedThe requested collections could not be resolved.

Examples

curl -G "https://vulgate.ai/api/search" \
  -H "Authorization: Bearer $VULGATE_TEAM_API_KEY" \
  --data-urlencode "search=the role of bishops in early Christianity" \
  --data-urlencode "libraries=mai" \
  --data-urlencode "mode=neural" \
  --data-urlencode "rerank=true" \
  --data-urlencode "per_page=10" \
  --data-urlencode "page=1"
curl -G "https://vulgate.ai/api/search" \
  -H "Authorization: Bearer $VULGATE_TEAM_API_KEY" \
  --data-urlencode "search=Nicene Creed" \
  --data-urlencode "libraries=mai" \
  --data-urlencode "mode=keyword"

Filter by author

curl -G "https://vulgate.ai/api/search" \
  -H "Authorization: Bearer $VULGATE_TEAM_API_KEY" \
  --data-urlencode "search=grace" \
  --data-urlencode "author=Augustine" \
  --data-urlencode "libraries=orientale"

Search within a document

curl -G "https://vulgate.ai/api/search" \
  -H "Authorization: Bearer $VULGATE_TEAM_API_KEY" \
  --data-urlencode "search=sacraments" \
  --data-urlencode "document_id=doc-xyz789" \
  --data-urlencode "libraries=mai"

Search within a collection

curl -G "https://vulgate.ai/api/search" \
  -H "Authorization: Bearer $VULGATE_TEAM_API_KEY" \
  --data-urlencode "search=grace" \
  --data-urlencode "collection_ids=b6f0c1d2-3e45-4a67-89bc-0de1f2a34567" \
  --data-urlencode "libraries=orientale"

Search multiple libraries

curl -G "https://vulgate.ai/api/search" \
  -H "Authorization: Bearer $VULGATE_TEAM_API_KEY" \
  --data-urlencode "search=liturgical calendar" \
  --data-urlencode "libraries=orientale" \
  --data-urlencode "libraries=mai"

Search private documents

curl -G "https://vulgate.ai/api/search" \
  -H "Authorization: Bearer $VULGATE_TEAM_API_KEY" \
  --data-urlencode "search=meeting notes" \
  --data-urlencode "libraries=private" \
  --data-urlencode "user_id=your-user-id"

Pagination

Results are paginated. Use page and per_page to navigate through results.

The count field in the response provides an estimated total number of matching results. This is suitable for rendering pagination controls but should not be treated as an exact count.

# Page 1
?search=theology&per_page=20&page=1
 
# Page 2
?search=theology&per_page=20&page=2

count stays an estimate under collection_ids too: a full first page can report the vector search’s 1000-result cap even for a small collection.

Scope and permissions

Search results respect document visibility scopes:

  • Private documents are only returned when the authenticated user matches the document uploader. Requires user_id to be set (inferred automatically with session auth).
  • Shared documents are returned to the uploader and to users who own or have an accepted invite to a shared collection that contains the document.
  • Organization documents are returned for any authenticated team member.
  • Magisterium AI library (mai) requires the team to have an active paid subscription.
  • Collections (collection_ids) return only published documents in those collections that you can already see. Private and shared collections require a user-backed key; a service-role key can only scope to organization collections. Collection scoping narrows within your team and ignores the Magisterium AI side of libraries. Combining collection_ids with document_id or id intersects the two filters — a document outside the collection returns no results. An unknown or inaccessible collection id is a 404, not an unfiltered search.

When searching both private and organization libraries simultaneously, results from both scopes are merged and paginated together.