Generate Context for Users
The Synvo API provides powerful query processing and intelligent file retrieval capabilities. These endpoints enable semantic search across your documents and conversational interactions with your data.
Important Note
⚠️ Query Usage Guide
- Queries will only provide context based on uploaded files
- If no files have been uploaded, queries will return empty responses
- Make sure to upload relevant files before making queries for meaningful results
For example:
- Upload your documents using the
/file/uploadendpoint - Wait for processing to complete (check status with
/file/status) - Then submit queries to get relevant context from your uploaded files
This ensures your queries have the necessary document context to provide accurate responses.
Authentication
All endpoints require authentication via:
- API Key:
X-API-Key: <api_key>
Base URL
https://api.synvo.aiSubmit Query
Processes queries with reference to all the uploaded files and output relevant context that supports the query.
Endpoint: POST /ai/query
Content-Type: multipart/form-data
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
payload | string | Yes | - | JSON string containing messages array for query processing |
sub_user_name | string | No | default | User isolation identifier for scoping queries to specific users |
final_answer | string | No | false | Whether to return a final summarized answer |
Payload Format
The payload parameter should be a JSON string containing a messages array:
{
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "Your question here"
}
]
}
]
}Example Request
curl -X POST "https://api.synvo.ai/ai/query" \
-H "X-API-Key: ${API-KEY}" \
-F 'payload={"messages":[{"role":"user","content":[{"type":"text","text":"What is the capital of France?"}]}]}' \
-F "model=synvo" \
-F "streaming=false"import requests
import json
api_key = "<API_KEY>"
url = "https://api.synvo.ai/ai/query"
headers = {"X-API-Key": api_key}
payload = {
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "What is the capital of France?"}
]
}
]
}
data = {
"payload": json.dumps(payload),
"model": "synvo",
"streaming": "false"
}
response = requests.post(url, data=data, headers=headers, timeout=60)
response.raise_for_status()
print(response.json())const api_key = "<API_KEY>";
const payload = {
messages: [
{
role: "user",
content: [
{ type: "text", text: "What is the capital of France?" }
]
}
]
};
const formData = new FormData();
formData.append("payload", JSON.stringify(payload));
formData.append("model", "synvo");
formData.append("streaming", "false");
const response = await fetch("https://api.synvo.ai/ai/query", {
method: "POST",
headers: {
"X-API-Key": apiKey,
},
body: formData,
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());Example Response
{
"success": true,
"response": {
"role": "assistant",
"content": [
{
"type": "text",
"text": "The capital of France is Paris."
}
],
"cuid": "msg_abc123xyz",
"created_at": "2024-01-15T10:30:00Z"
},
"suid": "sess_def456uvw",
"summary": "Question about French capital",
"timestamp": "2024-01-15T10:30:00Z"
}[Upcoming Feature] Streaming Response
When streaming=true, the response is sent as Server-Sent Events (SSE):
Content-Type: text/event-stream
data: {"type": "token", "content": "The"}
data: {"type": "token", "content": " capital"}
data: {"type": "token", "content": " of"}
data: {"type": "done", "response": {...}}Response Codes
200- Query processed successfully400- Bad request (invalid payload or parameters)401- Unauthorized
Search Files
Uses intelligent search to find files relevant to a query and returns file information.
Endpoint: POST /ai/search
Content-Type: application/x-www-form-urlencoded
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
message | string | Yes | Search query |
Example Request
curl -X POST "https://api.synvo.ai/ai/search" \
-H "X-API-Key: ${API-KEY}" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "message=financial reports for Q4"import requests
api_key = "<API_KEY>"
url = "https://api.synvo.ai/ai/search"
data = {"message": "financial reports for Q4"}
headers = {"X-API-Key": api_key}
response = requests.post(url, data=data, headers=headers, timeout=30)
response.raise_for_status()
print(response.json())const api_key = "<API_KEY>";
const params = new URLSearchParams({
message: "financial reports for Q4"
});
const response = await fetch("https://api.synvo.ai/ai/search", {
method: "POST",
headers: {
"X-API-Key": apiKey,
},
body: params,
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());Example Response
[
{
"file_id": "abc123xyz",
"file_path": "/reports/q4-financial.pdf",
"file_name": "q4-financial.pdf",
"file_type": "application/pdf",
"created_at": "2024-01-15T10:30:00Z"
},
{
"file_id": "def456uvw",
"file_path": "/reports/q4-summary.docx",
"file_name": "q4-summary.docx",
"file_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"created_at": "2024-01-14T15:45:00Z"
}
]Response Codes
200- Search completed successfully401- Unauthorized
Advanced Features
File Context
File-specific querying is coming soon! This feature will allow you to include specific files in your queries by adding file content to messages. Here's how it will work:
{
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "Analyze this document"
},
{
"type": "file",
"file_id": "abc123xyz",
"path": "/documents/report.pdf"
}
]
}
]
}Best Practices
Query Optimization
- Be Specific: Use clear, specific queries for better results
- Context Length: Keep conversations focused to avoid context limits
- File References: Include relevant files when asking document-specific questions
Performance Tips
- Streaming: Use streaming for long responses to improve user experience
- Model Selection: Choose appropriate models based on task complexity
- Search First: Use
/ai/searchto find relevant files before querying
Rate Limiting
- Standard rate limits apply per API key
- Streaming requests may have different limits
- Monitor response headers for rate limit information
Error Handling
Common Error Responses
{
"error": "Invalid payload format",
"code": "INVALID_PAYLOAD"
}{
"error": "Model not available",
"code": "MODEL_UNAVAILABLE"
}Error Codes
INVALID_PAYLOAD- Malformed JSON in payload parameterMODEL_UNAVAILABLE- Requested model is not availableRATE_LIMITED- Too many requestsCONTEXT_TOO_LONG- Message context exceeds limitsSEARCH_FAILED- File search operation failed
Handling Query Errors
def safe_query(api_key, payload, max_retries=3):
"""Safely perform query with error handling"""
for attempt in range(max_retries):
try:
data = {
"payload": json.dumps(payload),
"model": "synvo"
}
response = requests.post(
"https://api.synvo.ai/ai/query",
data=data,
headers={"X-API-Key": api_key},
timeout=60
)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 400:
error_data = e.response.json()
if error_data.get("code") == "INVALID_PAYLOAD":
print("Invalid payload format")
return None
elif e.response.status_code == 429:
print(f"Rate limited, retrying in {2**attempt} seconds...")
time.sleep(2**attempt)
continue
else:
print(f"Query failed: {e}")
return None
except Exception as e:
print(f"Unexpected error: {e}")
if attempt < max_retries - 1:
time.sleep(2**attempt)
continue
return None
# Usage
payload = {
"messages": [
{
"role": "user",
"content": [{"type": "text", "text": "Hello"}]
}
]
}
result = safe_query("your-api-key", payload)
if result:
print("Query successful")async function safeQuery(apiKey, payload, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const formData = new FormData();
formData.append("payload", JSON.stringify(payload));
formData.append("model", "synvo");
const response = await fetch("https://api.synvo.ai/ai/query", {
method: "POST",
headers: { "X-API-Key": apiKey },
body: formData
});
if (!response.ok) {
if (response.status === 400) {
const errorData = await response.json();
if (errorData.code === "INVALID_PAYLOAD") {
console.log("Invalid payload format");
return null;
}
} else if (response.status === 429) {
console.log(`Rate limited, retrying in ${2**attempt} seconds...`);
await new Promise(resolve => setTimeout(resolve, (2**attempt) * 1000));
continue;
} else {
throw new Error(`Request failed: ${response.status}`);
}
}
return await response.json();
} catch (error) {
console.log(`Query error (attempt ${attempt + 1}): ${error.message}`);
if (attempt < maxRetries - 1) {
await new Promise(resolve => setTimeout(resolve, (2**attempt) * 1000));
continue;
}
return null;
}
}
}
// Usage
const payload = {
messages: [
{
role: "user",
content: [{ type: "text", text: "Hello" }]
}
]
};
const result = await safeQuery("your-api-key", payload);
if (result) {
console.log("Query successful");
}