Public Search API

Integrate AI-powered sacred text search into your applications

The SifterSearch Public API provides programmatic access to our hybrid search system with full AI analysis, scoring, and highlighting. Use it to build custom search interfaces, research tools, or integrate sacred text search into your own applications.

An interactive Swagger UI is available at https://api.siftersearch.com/api/v1/docs for exploring and testing all endpoints directly in your browser.

API Endpoints

ServiceEndpointDescription
Search — Full-text + semantic search across sacred texts
POST /api/v1/searchHybrid search with AI analysis and scoring
POST /api/v1/search/quickFast keyword-only search (no AI, cacheable)
GET /api/v1/paragraph/:idGet a specific paragraph by ID
GET /api/v1/collectionsList religions and collections with counts
Library — Browse and search the document catalog
GET /api/v1/library/documentsSearch documents by title, author, metadata
GET /api/v1/library/documents/:idGet single document metadata + canonical URL
GET /api/v1/library/authorsList authors with document counts
GET /api/v1/library/religionsReligion/collection tree with counts
Chat — AI research assistant
POST /api/v1/chatConversational AI search (SSE streaming)
Tools — For AI agents and chatbots
POST /api/v1/tools/searchUnified search tool (passages/documents/count/read)
GET /api/v1/tools/libraryLibrary overview stats
System
GET /api/v1/healthAPI health check (no auth required)

Authentication

All API requests require an API key passed in the X-API-Key header.

curl -X POST https://api.siftersearch.com/api/v1/search \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key-here" \
  -d '{"query": "what is justice"}'

API keys are self-service. Sign up for a SifterSearch account, subscribe to an API plan in Settings → API Keys, then create your first key. Your key is active immediately. See API Billing for pricing details.

Getting Started

Four steps to your first request:

  1. Sign up — Create a free SifterSearch account at /login.
  2. Subscribe — In Settings → API Keys, activate the pay-per-search plan.
  3. Create a key — Click "Create API Key", give it a name, and copy the key shown once.
  4. Make a request — Pass the key in the X-API-Key header on every call.

Your first request (example with cURL):

curl -X POST https://api.siftersearch.com/api/v1/search \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sk_live_your-key-here" \
  -d '{"query": "what does Islam teach about gratitude"}'

Rate Limits

Standard accounts are limited to 1,000 requests per hour with up to 50 results per request. Rate limit headers are included in every response:

  • X-RateLimit-Limit — Maximum requests per hour
  • X-RateLimit-Remaining — Requests remaining in current window
  • X-RateLimit-Reset — Unix timestamp when the window resets

Billing

The API uses metered pay-per-search pricing at approximately $0.001 per search. Hybrid searches (/search) are always billed. Quick/keyword searches (/search/quick) are free when served from cache — the same keyword query within 15 minutes costs nothing. Admin accounts have free unlimited access. Invoices are generated monthly via Stripe. See API Billing documentation for full details.


Search Service

Search results from both /search and /search/quick include url and documentUrl fields containing canonical siftersearch.com links to the passage and its parent document respectively.

POST /api/v1/search

Full hybrid search with AI-powered analysis. Returns scored, highlighted results with brief summaries. Best for detailed research queries.

Request Body

Field Type Required Description
query string Yes Search query (1-500 characters)
limit integer No Max results to return (1-50, default: 10)
filters object No Filter criteria (see below)

Filter Options

Field Type Description
religion string Filter by religion (e.g., "Baha'i", "Buddhism")
collection string Filter by collection (e.g., "Pilgrim Notes")
yearFrom integer Minimum publication year
yearTo integer Maximum publication year

Faceting Examples

Filter by religion:

{
  "query": "the nature of the soul",
  "filters": {
    "religion": "Buddhism"
  }
}

Filter by collection:

{
  "query": "daily devotional practice",
  "filters": {
    "collection": "Pilgrim Notes"
  }
}

Filter by author:

{
  "query": "unity of religions",
  "filters": {
    "author": "Abdu'l-Baha"
  }
}

Filter by year range:

{
  "query": "interfaith dialogue",
  "filters": {
    "yearFrom": 1900,
    "yearTo": 1950
  }
}

Example Request

POST /api/v1/search
Content-Type: application/json
X-API-Key: sk_live_your-key-here

{
  "query": "meaning of prayer and meditation",
  "limit": 5,
  "filters": {
    "religion": "Baha'i"
  }
}

Example Response

{
  "results": [
    {
      "id": "1907_07_martha_root_reflections_p42",
      "documentId": "1907_07_martha_root_reflections",
      "paragraphIndex": 42,
      "text": "Prayer and supplication are two wings whereby man soars...",
      "highlightedText": "<mark>Prayer and supplication</mark> are two wings...",
      "title": "Reflections on Prayer and Contemplation",
      "author": "Martha Root",
      "religion": "Baha'i",
      "collection": "Pilgrim Notes",
      "score": 92,
      "summary": "Prayer enables spiritual ascent",
      "url": "https://siftersearch.com/read/1907_07_martha_root_reflections#p42",
      "documentUrl": "https://siftersearch.com/read/1907_07_martha_root_reflections"
    }
  ],
  "query": "meaning of prayer and meditation",
  "totalFound": 47,
  "processingTimeMs": 1234
}

POST /api/v1/search/quick

Fast keyword-only search without AI analysis. Returns raw Meilisearch results with word-level highlighting. Best for autocomplete, typeahead, or high-volume queries.

Request Body

Field Type Required Description
query string Yes Search query (1-200 characters)
limit integer No Max results (1-50, default: 10)
filters object No Filter by religion or collection

Example Response

{
  "results": [
    {
      "id": "hidden_words_p23",
      "text": "The light of men is <mark>Justice</mark>...",
      "title": "Hidden Words",
      "author": "Baha'u'llah",
      "religion": "Baha'i",
      "collection": "Core Publications",
      "score": 0.98,
      "url": "https://siftersearch.com/read/hidden_words#p23",
      "documentUrl": "https://siftersearch.com/read/hidden_words"
    }
  ],
  "query": "justice",
  "processingTimeMs": 6
}

GET /api/v1/collections

List available religions and collections in the library. Useful for building filter UIs.

Example Response

{
  "religions": ["Baha'i", "Buddhism", "Christianity", "Hinduism", "Islam", "Judaism"],
  "collections": ["Core Publications", "Pilgrim Notes", "Letters", "Talks"],
  "totalDocuments": 12847,
  "lastUpdated": "2024-12-14T00:00:00Z"
}

GET /api/v1/health

API health check. Does not require authentication.

Example Response

{
  "status": "ok",
  "version": "1.0.0",
  "timestamp": "2024-12-14T22:52:43.717Z"
}

Library Service

Browse and query document metadata without consuming search quota. Library endpoints are useful for building browsing interfaces, populating filter dropdowns, or discovering what is available before running searches.

GET /api/v1/library/documents

Search and browse the document library. Returns document metadata and canonical URLs.

Query Parameters

Parameter Type Description
q string Search by title, author, or description
author string Filter by author name (partial match)
religion string Filter by religion (exact match)
collection string Filter by collection (exact match)
language string Filter by language code (e.g. en, ar, fa)
limit integer Max results (1-100, default: 20)
offset integer Pagination offset (default: 0)

Example Response

{
  "documents": [
    {
      "id": "hidden_words",
      "title": "The Hidden Words",
      "author": "Baha'u'llah",
      "religion": "Baha'i",
      "collection": "Core Publications",
      "language": "en",
      "year": 1858,
      "description": "A collection of ethical and mystical utterances...",
      "paragraphCount": 153,
      "url": "https://siftersearch.com/read/hidden_words"
    }
  ],
  "total": 1,
  "limit": 20,
  "offset": 0
}

GET /api/v1/library/documents/:id

Get detailed metadata for a single document by its ID.

Example Response

{
  "id": "hidden_words",
  "title": "The Hidden Words",
  "author": "Baha'u'llah",
  "religion": "Baha'i",
  "collection": "Core Publications",
  "language": "en",
  "year": 1858,
  "description": "A collection of ethical and mystical utterances...",
  "paragraphCount": 153,
  "url": "https://siftersearch.com/read/hidden_words",
  "createdAt": "2024-01-15T00:00:00Z",
  "updatedAt": "2024-12-14T00:00:00Z"
}

GET /api/v1/library/authors

List all authors with their document counts and associated religions.

Query Parameters

Parameter Type Description
religion string Filter authors by religion
q string Search authors by name
limit integer Max results (1-500, default: 100)
offset integer Pagination offset (default: 0)

Example Response

{
  "authors": [
    {
      "name": "Baha'u'llah",
      "documentCount": 42,
      "religions": ["Baha'i"]
    },
    {
      "name": "Abdu'l-Baha",
      "documentCount": 31,
      "religions": ["Baha'i"]
    }
  ],
  "total": 2
}

GET /api/v1/library/religions

Get the full religion and collection tree, including document counts at each level. Useful for building hierarchical navigation or filter components.

Example Response

{
  "religions": [
    {
      "name": "Baha'i",
      "documentCount": 284,
      "collections": [
        { "name": "Core Publications", "documentCount": 42 },
        { "name": "Pilgrim Notes", "documentCount": 118 },
        { "name": "Letters", "documentCount": 124 }
      ]
    },
    {
      "name": "Buddhism",
      "documentCount": 196,
      "collections": [
        { "name": "Pali Canon", "documentCount": 89 },
        { "name": "Mahayana Sutras", "documentCount": 107 }
      ]
    }
  ]
}

Chat Service

The Chat API provides access to Jafar, the SifterSearch AI research assistant. Jafar synthesizes passages from across the library to answer questions, identify themes, and support sustained research sessions. Responses stream via Server-Sent Events (SSE).

POST /api/v1/chat

Send a message to the AI research assistant. Responses are streamed as Server-Sent Events. Each event carries a type field indicating what kind of data it contains.

Request Body

Field Type Required Description
messages array Yes Conversation history: [{ role: "user"|"assistant", content: string }]
researchContext string No Prior research context to carry forward across turns

SSE Event Types

Type Description
status Progress update (e.g., "Searching library…")
text Incremental response text chunk
citations Array of source passages used in the response
done Stream complete; no further events will follow
error Error detail; stream will terminate after this event

Example Request

POST /api/v1/chat
Content-Type: application/json
X-API-Key: sk_live_your-key-here

{
  "messages": [
    { "role": "user", "content": "What do the Baha'i writings say about the oneness of religion?" }
  ]
}

Example SSE Stream

data: {"type":"status","message":"Searching library..."}

data: {"type":"text","content":"The Baha'i writings consistently affirm that "}

data: {"type":"text","content":"all major religions share a common divine origin..."}

data: {"type":"citations","citations":[
  {
    "id": "gleanings_p1",
    "title": "Gleanings from the Writings of Baha'u'llah",
    "author": "Baha'u'llah",
    "text": "This is the Day in which God's most excellent favors...",
    "url": "https://siftersearch.com/read/gleanings#p1"
  }
]}

data: {"type":"done"}

JavaScript Streaming Example

const response = await fetch('https://api.siftersearch.com/api/v1/chat', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': process.env.SIFTER_API_KEY
  },
  body: JSON.stringify({
    messages: [{ role: 'user', content: 'What is the Baha\'i view on science and religion?' }]
  })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  const chunk = decoder.decode(value);
  for (const line of chunk.split('\n')) {
    if (!line.startsWith('data: ')) continue;
    const event = JSON.parse(line.slice(6));
    if (event.type === 'text') process.stdout.write(event.content);
    if (event.type === 'citations') console.log('\nSources:', event.citations);
  }
}

Error Responses

All errors return a JSON object with error and code fields:

{
  "error": "API key required. Set X-API-Key header.",
  "code": "unauthorized"
}

Error Codes

HTTP Status Code Description
400 bad_request Invalid request body or parameters
401 unauthorized Missing or invalid API key
403 forbidden API key lacks required permissions
429 rate_limit_exceeded Too many requests, try again later
500 internal_error Server error, please report

SDKs & Libraries

Official SDKs are coming soon. In the meantime, use any HTTP client:

JavaScript / Node.js

const response = await fetch('https://api.siftersearch.com/api/v1/search', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': process.env.SIFTER_API_KEY
  },
  body: JSON.stringify({
    query: 'what is the purpose of life',
    limit: 10,
    filters: { religion: "Buddhism" }
  })
});

const data = await response.json();
data.results.forEach(r => console.log(`{r.score} - {r.title}: {r.summary}`));

Python

import os, requests

response = requests.post(
    'https://api.siftersearch.com/api/v1/search',
    headers={
        'Content-Type': 'application/json',
        'X-API-Key': os.environ['SIFTER_API_KEY']
    },
    json={
        'query': 'what is the purpose of life',
        'limit': 10,
        'filters': {'religion': 'Buddhism'}
    }
)

data = response.json()
for result in data['results']:
    print(f"{result['score']} - {result['title']}: {result['summary']}")

cURL

curl -X POST https://api.siftersearch.com/api/v1/search \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $SIFTER_API_KEY" \
  -d '{"query": "what is the purpose of life", "limit": 10, "filters": {"religion": "Buddhism"}}'

Best Practices

  • Use semantic queries - Ask questions naturally: "What does Buddhism teach about suffering?" works better than just "Buddhism suffering".
  • Filter when possible - If you know the tradition, use the religion filter to improve relevance.
  • Cache responses - Results for the same query don't change frequently. Cache for better performance.
  • Handle rate limits gracefully - Check the X-RateLimit-Remaining header and implement backoff.
  • Use /search/quick for autocomplete - The quick endpoint is ~10x faster for simple keyword matches.
  • Stream chat responses - The chat endpoint uses SSE; consume the stream incrementally rather than waiting for a full response body.
  • Persist researchContext - Pass the assistant's prior context back on follow-up chat turns to maintain coherent multi-turn research sessions.