Overview
The Query API is Sorcia’s core endpoint for searching your knowledge base. It uses hybrid search (vector + text) and AI to provide accurate, cited answers to natural language questions.
Base URL : https://api.sorcia.ai/api/ai/query
Method : POST
Authentication : Required (Bearer token or API key)
Quick Example
cURL
JavaScript
Python
TypeScript
curl -X POST https://api.sorcia.ai/api/ai/query \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"question": "What is our vacation policy?"
}'
Request Parameters
Required Parameters
The question or search query in natural language Example : “How do I submit expense reports?”
Optional Parameters
Filters to narrow search results Limit search to specific integrations Example : ["slack", "notion"]
Filter by document update date Slack channels to search (if source includes Slack)
Filter by document authors/creators
Query behavior options Maximum number of source documents to retrieve (1-20)
Stream the response as Server-Sent Events
Include full document metadata in citations
AI creativity (0-1, lower is more deterministic)
Success Response (200)
{
"answer" : "Based on your Employee Handbook, all full-time employees receive 20 days of paid time off (PTO) per year..." ,
"confidence" : 0.95 ,
"citations" : [
{
"id" : "doc_123" ,
"title" : "Employee Handbook 2024" ,
"source" : "google-drive" ,
"url" : "https://drive.google.com/file/d/abc123" ,
"snippet" : "All full-time employees receive 20 days of paid time off..." ,
"relevance" : 0.92 ,
"metadata" : {
"author" : "HR Team" ,
"updated_at" : "2024-01-15T10:00:00Z" ,
"file_type" : "pdf"
}
}
],
"related_questions" : [
"How do I request time off?" ,
"Can I roll over unused vacation days?" ,
"What's the policy for sick leave?"
],
"query_metadata" : {
"query_id" : "qry_abc123" ,
"response_time_ms" : 1247 ,
"sources_searched" : 847 ,
"sources_used" : 3
}
}
Response Fields
AI-generated answer based on retrieved documents
Confidence score (0-1) indicating answer quality
Source documents used to generate the answer Unique document identifier
Integration source (e.g., “slack”, “notion”)
Direct link to the original document
Relevant excerpt from the document
Suggested follow-up questions
Query performance and statistics
Advanced Usage
Filtering by Source
Search only specific integrations:
const response = await fetch ( 'https://api.sorcia.ai/api/ai/query' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ accessToken } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
question: 'Latest product roadmap updates' ,
filters: {
sources: [ 'notion' , 'github' ],
dateRange: {
start: '2024-01-01' ,
end: '2024-12-31'
}
}
})
});
Streaming Responses
For real-time answer generation, use streaming:
const response = await fetch ( 'https://api.sorcia.ai/api/ai/query' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ accessToken } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
question: 'Explain our security architecture' ,
options: { stream: true }
})
});
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 );
const lines = chunk . split ( ' \n ' );
for ( const line of lines ) {
if ( line . startsWith ( 'data: ' )) {
const data = JSON . parse ( line . slice ( 6 ));
console . log ( data . delta ); // Incremental text
}
}
}
data: {"delta": "Based on ", "done": false}
data: {"delta": "your Security ", "done": false}
data: {"delta": "Policy...", "done": false}
data: {"done": true, "citations": [...]}
Error Responses
Bad Request (400)
{
"error" : "Bad Request" ,
"message" : "Question is required" ,
"code" : "MISSING_QUESTION"
}
Common Causes :
Missing question parameter
Invalid filter format
Malformed JSON
Unauthorized (401)
{
"error" : "Unauthorized" ,
"message" : "Invalid or expired token"
}
Solution : Refresh your access token
Rate Limited (429)
{
"error" : "Rate Limit Exceeded" ,
"message" : "Too many requests" ,
"retry_after" : 60
}
Solution : Implement exponential backoff
No Results (200)
{
"answer" : "I couldn't find any relevant information about that in your knowledge base." ,
"confidence" : 0.0 ,
"citations" : [],
"related_questions" : []
}
A 200 status with empty citations means no relevant documents were found, not an error.
Rate Limits
Query API limits by plan:
Plan Queries/Month Queries/Minute Free 100 5 Pro 1,000 20 Enterprise Unlimited 100
Monitor usage via the X-RateLimit-* response headers
Best Practices
Use natural language
Be specific (e.g., “Q4 2024 sales metrics” vs “sales”)
Include context when needed
Avoid overly broad questions
Filter by source when you know where info lives
Use date ranges for time-sensitive queries
Combine filters for precision
Confidence < 0.5: Show warning to users
Confidence < 0.3: Suggest refining question
Always show citations so users can verify
Cache identical queries for 5-10 minutes
Use query_id for deduplication
Invalidate cache on document updates
Retry on 5xx errors with exponential backoff
Don’t retry on 4xx errors (client errors)
Set maximum retry limit (e.g., 3 attempts)
Code Examples
React Hook
import { useState } from 'react' ;
export function useQuery () {
const [ loading , setLoading ] = useState ( false );
const [ error , setError ] = useState < string | null >( null );
const query = async ( question : string ) => {
setLoading ( true );
setError ( null );
try {
const response = await fetch ( 'https://api.sorcia.ai/api/ai/query' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ getAccessToken () } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({ question })
});
if ( ! response . ok ) {
throw new Error ( 'Query failed' );
}
return await response . json ();
} catch ( err ) {
setError ( err . message );
throw err ;
} finally {
setLoading ( false );
}
};
return { query , loading , error };
}
Python Client
class SorciaClient :
def __init__ ( self , access_token ):
self .access_token = access_token
self .base_url = 'https://api.sorcia.ai'
def query ( self , question , ** kwargs ):
"""Query the knowledge base"""
response = requests.post(
f ' { self .base_url } /api/ai/query' ,
headers = { 'Authorization' : f 'Bearer { self .access_token } ' },
json = { 'question' : question, ** kwargs}
)
response.raise_for_status()
return response.json()
def query_with_retry ( self , question , max_retries = 3 ):
"""Query with automatic retry on failure"""
for attempt in range (max_retries):
try :
return self .query(question)
except requests.exceptions.RequestException as e:
if attempt == max_retries - 1 :
raise
time.sleep( 2 ** attempt) # Exponential backoff
Next Steps