Search Links API
Search Links provide public access to semantic search over your knowledge base.
Public Search Endpoint
No authentication required for public search endpoints.
Search Documents
GET /public/{token}/search
Search documents within a workspace scope defined by the Search Link.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
q | string | Yes | Search query (URL encoded) |
limit | number | No | Max results (default: 10, max: 50) |
tags | string | No | Comma-separated tags to filter |
Example Request
curl "https://api.synjar.com/public/abc123def456/search?q=refund+policy&limit=5"
Response
{
"results": [
{
"documentId": "550e8400-e29b-41d4-a716-446655440000",
"title": "Refund Policy",
"content": "Our refund policy allows returns within 30 days of purchase...",
"score": 0.95,
"tags": ["support", "policy"]
},
{
"documentId": "550e8400-e29b-41d4-a716-446655440001",
"title": "FAQ - Returns",
"content": "Q: How do I request a refund? A: Contact support...",
"score": 0.87,
"tags": ["faq", "support"]
}
],
"totalResults": 2
}
POST Alternative
For longer queries, you can use POST:
curl -X POST "https://api.synjar.com/public/abc123def456/search" \
-H "Content-Type: application/json" \
-d '{"query": "how to request a refund for my order", "limit": 10}'
Response Fields
| Field | Type | Description |
|---|---|---|
results | array | Matching document chunks |
results[].documentId | string | Document UUID |
results[].title | string | Document title |
results[].content | string | Matched content chunk |
results[].score | number | Relevance score (0-1) |
results[].tags | string[] | Document tags (filtered by Link scope) |
totalResults | number | Total number of results |
Management Endpoints
These endpoints require authentication.
Create Search Link
POST /api/workspaces/{workspaceId}/public-links
Request Body
{
"name": "Support Knowledge Base",
"allowedTags": ["public", "support"],
"expiresAt": "2025-12-31T23:59:59Z"
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Human-readable name |
allowedTags | string[] | No | Restrict search to documents with these tags |
expiresAt | ISO 8601 | No | When the link expires |
Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"token": "abc123def456",
"name": "Support Knowledge Base",
"allowedTags": ["public", "support"],
"expiresAt": "2025-12-31T23:59:59Z",
"isActive": true,
"createdAt": "2025-12-30T10:00:00Z",
"publicUrl": "https://api.synjar.com/public/abc123def456/search",
"documentCount": 47
}
List Search Links
GET /api/workspaces/{workspaceId}/public-links
Returns all Search Links for the workspace.
Get Search Link
GET /api/workspaces/{workspaceId}/public-links/{id}
Update Search Link
PATCH /api/workspaces/{workspaceId}/public-links/{id}
Request Body
{
"name": "Updated Name",
"allowedTags": ["public"],
"expiresAt": "2026-01-31T23:59:59Z"
}
Revoke Search Link
DELETE /api/workspaces/{workspaceId}/public-links/{id}
Permanently deactivates the Search Link. The token will no longer work.
Rate Limits
| Endpoint | Limit |
|---|---|
| Public search | 30 requests/minute per token |
| Management endpoints | Standard API limits |
Error Responses
404 - Link Not Found
{
"error": "NOT_FOUND",
"message": "Search link not found or has been revoked"
}
410 - Link Expired
{
"error": "EXPIRED",
"message": "This search link has expired"
}
429 - Rate Limited
{
"error": "RATE_LIMITED",
"message": "Too many requests. Please wait before trying again."
}
Integration Examples
Python
import requests
def search_knowledge_base(query: str, token: str, limit: int = 10):
url = f"https://api.synjar.com/public/{token}/search"
params = {"q": query, "limit": limit}
response = requests.get(url, params=params)
response.raise_for_status()
return response.json()["results"]
# Usage
results = search_knowledge_base("refund policy", "abc123def456")
for result in results:
print(f"{result['title']}: {result['score']}")
JavaScript/TypeScript
interface SearchResult {
documentId: string;
title: string;
content: string;
score: number;
tags: string[];
}
async function searchKnowledgeBase(
query: string,
token: string,
limit = 10
): Promise<SearchResult[]> {
const url = new URL(`https://api.synjar.com/public/${token}/search`);
url.searchParams.set('q', query);
url.searchParams.set('limit', String(limit));
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Search failed: ${response.status}`);
}
const data = await response.json();
return data.results;
}
// Usage with OpenAI
import OpenAI from 'openai';
const openai = new OpenAI();
async function answerWithContext(question: string, token: string) {
const results = await searchKnowledgeBase(question, token);
const context = results.map(r => r.content).join('\n\n');
const response = await openai.chat.completions.create({
model: 'gpt-4',
messages: [
{
role: 'system',
content: `Answer based on this context:\n\n${context}`,
},
{ role: 'user', content: question },
],
});
return response.choices[0].message.content;
}
cURL
# Search
curl "https://api.synjar.com/public/abc123/search?q=how+to+reset+password"
# Create new link (authenticated)
curl -X POST "https://api.synjar.com/api/workspaces/ws123/public-links" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Public FAQ", "allowedTags": ["faq"]}'