API Integration Guide
Connect your applications to Axie Studio's Knowledge Base using our REST API v1. Whether you're a developer building custom integrations or a power user automating workflows, this guide will help you get started.
All endpoints use API v1 and are prefixed with /api/v1/. This ensures stability and backward compatibility.
- Developers: Build custom applications that interact with your knowledge base
- Power Users: Automate document uploads and queries
- Integration Teams: Connect Axie Studio to your existing systems
🚀 Quick Start
What You'll Need
Before you start, make sure you have:
- ✅ An Axie Studio account
- ✅ A knowledge base created in your dashboard
- ✅ Your authentication token (from Clerk)
Your First API Call
Let's make your first API call to list your knowledge bases:
// Simple example - List your knowledge bases
const response = await fetch('https://your-domain.com/api/v1/knowledge-base/configs', {
headers: {
'Authorization': 'Bearer YOUR_AUTH_TOKEN'
}
});
const data = await response.json();
console.log(data);
That's it! You just made your first API call. 🎉
📚 Understanding the API
How It Works
Think of the API as a way to control your knowledge base programmatically:
Your App → API Request → Axie Studio → API Response → Your App
Example Use Cases:
- 📤 Automatically upload documents from your CMS
- 🔍 Query your knowledge base from a mobile app
- 📊 Build custom analytics dashboards
- 🤖 Create chatbots powered by your content
API Basics
Base URL
All API requests start with:
https://your-domain.com/api/v1/knowledge-base
All Axie Studio APIs are versioned under /api/v1/. This ensures your integrations remain stable as we add new features.
Authentication
Every request needs your auth token:
headers: {
'Authorization': 'Bearer YOUR_AUTH_TOKEN'
}
Your authentication token comes from Clerk. If you're logged into the Axie Studio dashboard, you already have one! Check your browser's developer tools or use Clerk's SDK to get it.
Response Format
All responses follow the same pattern:
✅ Success:
{
"success": true,
"data": {
// Your actual data here
}
}
❌ Error:
{
"success": false,
"error": {
"message": "What went wrong",
"details": "More information"
}
}
🎯 Common Tasks
Task 1: Upload a Document
What it does: Adds a new document to your knowledge base
When to use: Automate document uploads from your CMS, Dropbox, or file system
async function uploadDocument(file, knowledgeBaseId) {
const formData = new FormData();
formData.append('file', file);
formData.append('configId', knowledgeBaseId);
const response = await fetch('/api/v1/knowledge-base/documents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${yourAuthToken}`
},
body: formData
});
const result = await response.json();
if (result.success) {
console.log('✅ Document uploaded!', result.data);
} else {
console.error('❌ Upload failed:', result.error.message);
}
}
What happens next:
- Document is uploaded ⬆️
- Text is extracted 📄
- AI creates searchable embeddings 🧠
- Document becomes searchable 🔍
File limits:
- Free: 10MB per file
- Premium: 50MB per file
- Enterprise: 100MB per file
Supported formats: PDF, DOCX, TXT, MD
Task 2: Query Your Knowledge Base
What it does: Ask questions and get AI-powered answers from your documents
When to use: Build chatbots, search interfaces, or Q&A systems
async function askQuestion(question, knowledgeBaseId) {
const response = await fetch('/api/v1/knowledge-base/query', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${yourAuthToken}`
},
body: JSON.stringify({
query: question,
configId: knowledgeBaseId
})
});
const result = await response.json();
if (result.success) {
console.log('Answer:', result.data.answer);
console.log('Sources:', result.data.sources);
}
}
// Example usage
askQuestion('How do I reset my password?', 1);
Response includes:
- 💬 Answer: AI-generated response
- 📚 Sources: Which documents were used
- 📊 Usage: Token consumption for billing
Task 3: List Your Documents
What it does: See all documents in a knowledge base
When to use: Build document management interfaces, check upload status
async function listDocuments(knowledgeBaseId) {
const response = await fetch(
`/api/v1/knowledge-base/documents?configId=${knowledgeBaseId}`,
{
headers: {
'Authorization': `Bearer ${yourAuthToken}`
}
}
);
const result = await response.json();
if (result.success) {
result.data.documents.forEach(doc => {
console.log(`📄 ${doc.fileName} - Status: ${doc.status}`);
});
}
}
Document statuses:
- 🟡 processing: Still being processed
- 🟢 completed: Ready to use
- 🔴 failed: Processing failed
Task 4: Delete Documents
What it does: Remove documents from your knowledge base
When to use: Clean up outdated content, manage storage
Delete one document:
async function deleteDocument(documentId) {
const response = await fetch(`/api/v1/knowledge-base/documents/${documentId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${yourAuthToken}`
}
});
const result = await response.json();
if (result.success) {
console.log('✅ Document deleted');
}
}
Delete multiple documents (bulk):
async function deleteMultipleDocuments(documentIds) {
const response = await fetch('/api/v1/knowledge-base/documents/bulk-delete', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${yourAuthToken}`
},
body: JSON.stringify({
documentIds: documentIds // Array of IDs, max 100
})
});
const result = await response.json();
if (result.success) {
console.log(`✅ Deleted ${result.data.deleted} documents`);
}
}
// Example: Delete 5 documents at once
deleteMultipleDocuments([1, 2, 3, 4, 5]);
🎨 Advanced Features
Real-Time Streaming Responses
Get answers as they're generated for a better user experience:
async function streamingQuery(question, knowledgeBaseId) {
const response = await fetch('/api/v1/knowledge-base/query/stream', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${yourAuthToken}`
},
body: JSON.stringify({
query: question,
configId: knowledgeBaseId
})
});
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 = line.slice(6);
if (data === '[DONE]') {
console.log('✅ Stream complete');
break;
}
const event = JSON.parse(data);
if (event.type === 'complete') {
console.log('Answer:', event.answer);
}
}
}
}
}
Why use streaming?
- ⚡ Faster perceived response time
- 📱 Better mobile experience
- 🎯 Show progress to users
Managing Knowledge Base Settings
Get your knowledge base configuration:
async function getConfig(knowledgeBaseId) {
const response = await fetch(`/api/v1/knowledge-base/configs/${knowledgeBaseId}`, {
headers: {
'Authorization': `Bearer ${yourAuthToken}`
}
});
const result = await response.json();
if (result.success) {
console.log('Config:', result.data);
}
}
Update settings:
async function updateConfig(knowledgeBaseId, updates) {
const response = await fetch(`/api/v1/knowledge-base/configs/${knowledgeBaseId}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${yourAuthToken}`
},
body: JSON.stringify(updates)
});
const result = await response.json();
if (result.success) {
console.log('✅ Config updated');
}
}
// Example: Make responses more creative
updateConfig(1, {
temperature: '0.9', // More creative (0.0 = factual, 2.0 = very creative)
maxTokens: 3000 // Longer responses
});
🛡️ Rate Limits & Best Practices
Understanding Rate Limits
To ensure fair usage, we limit API requests:
| Action | Limit | Window |
|---|---|---|
| Upload documents | 10 requests | per minute |
| Query knowledge base | 60 requests | per minute |
| Other operations | 100 requests | per minute |
How to check your limits: Every response includes these headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1732294800
What happens if you exceed limits?
You'll get a 429 error. Wait until the reset time, then try again.
Best Practices
✅ DO:
- Check the
successfield before using data - Handle errors gracefully - show user-friendly messages
- Implement retry logic with exponential backoff
- Cache responses when possible
- Use streaming for long responses
❌ DON'T:
- Ignore rate limits - you'll get blocked
- Upload huge files - split them first
- Make parallel uploads - queue them instead
- Hardcode tokens - use environment variables
Example: Retry with backoff
async function queryWithRetry(question, configId, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch('/api/v1/knowledge-base/query', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${yourAuthToken}`
},
body: JSON.stringify({ query: question, configId })
});
if (response.status === 429) {
// Rate limited - wait and retry
const waitTime = Math.pow(2, i) * 1000; // Exponential backoff
console.log(`⏳ Rate limited. Waiting ${waitTime}ms...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
continue;
}
const result = await response.json();
return result;
} catch (error) {
if (i === maxRetries - 1) throw error;
console.log(`❌ Attempt ${i + 1} failed. Retrying...`);
}
}
}
🔧 Troubleshooting
Common Issues
"Unauthorized" Error (401)
Problem: Your auth token is missing or invalid
Solution:
// Make sure your token is included
headers: {
'Authorization': `Bearer ${yourAuthToken}` // Don't forget 'Bearer '
}
"Configuration not found" Error (404)
Problem: The knowledge base ID doesn't exist or you don't have access
Solution:
- Check the ID is correct
- Verify you own this knowledge base
- List all configs to see available IDs
"File too large" Error (413)
Problem: File exceeds your plan's limit
Solution:
- Free: Max 10MB - split larger files
- Premium: Max 50MB - upgrade if needed
- Enterprise: Max 100MB - contact support for more
"Rate limit exceeded" Error (429)
Problem: Too many requests too quickly
Solution:
// Check the reset time
const resetTime = response.headers.get('X-RateLimit-Reset');
const waitSeconds = resetTime - Math.floor(Date.now() / 1000);
console.log(`Wait ${waitSeconds} seconds before retrying`);
Processing Failed
Problem: Document upload succeeded but processing failed
Solution:
- Check file format (PDF, DOCX, TXT, MD only)
- Ensure file isn't corrupted
- Try a different file
- Contact support if issue persists
📖 Complete API Reference
All Available Endpoints
Configuration Management
GET /api/v1/knowledge-base/configs List all configs
POST /api/v1/knowledge-base/configs Create config
GET /api/v1/knowledge-base/configs/:id Get config
PATCH /api/v1/knowledge-base/configs/:id Update config
DELETE /api/v1/knowledge-base/configs/:id Delete config
Document Management
GET /api/v1/knowledge-base/documents List documents
POST /api/v1/knowledge-base/documents Upload document
DELETE /api/v1/knowledge-base/documents/:id Delete document
POST /api/v1/knowledge-base/documents/bulk-delete Delete multiple
Querying
POST /api/v1/knowledge-base/query Standard query
POST /api/v1/knowledge-base/query/stream Streaming query
Tools & Utilities
GET /api/v1/knowledge-base/configs/:id/tools List tools
PATCH /api/v1/knowledge-base/configs/:id/tools Update tool
GET /api/v1/knowledge-base/collections List collections
POST /api/v1/knowledge-base/test-reducto Test API key
GET /api/v1/knowledge-base/health Health check
HTTP Status Codes
| Code | Meaning | What to do |
|---|---|---|
| 200 | ✅ Success | Use the data |
| 201 | ✅ Created | Resource created successfully |
| 400 | ❌ Bad Request | Check your input |
| 401 | ❌ Unauthorized | Check your auth token |
| 403 | ❌ Forbidden | You don't have permission |
| 404 | ❌ Not Found | Resource doesn't exist |
| 413 | ❌ Too Large | File is too big |
| 429 | ❌ Rate Limited | Wait and retry |
| 500 | ❌ Server Error | Try again or contact support |
🔄 Migrating from Old API
If you're using the old API, here's how to upgrade:
Endpoint Changes
| Old Endpoint | New Endpoint | What Changed |
|---|---|---|
/api/knowledge-base/upload | /api/v1/knowledge-base/documents | Added version, better naming |
/api/knowledge-base/documents | /api/v1/knowledge-base/documents | Added version |
/api/knowledge-base/query | /api/v1/knowledge-base/query | Added version, better responses |
/api/knowledge-base/collections/list | /api/v1/knowledge-base/collections | Cleaner URL |
Response Format Changes
Old format:
{
"documents": [...],
"count": 5
}
New format:
{
"success": true,
"data": {
"documents": [...],
"count": 5
}
}
Migration tip: Always check success field first:
const result = await response.json();
if (result.success) {
// Use result.data
} else {
// Handle result.error
}
💡 Real-World Examples
Example 1: Auto-Upload from Dropbox
// Monitor a Dropbox folder and auto-upload new files
async function syncDropboxToKnowledgeBase(dropboxFiles, knowledgeBaseId) {
for (const file of dropboxFiles) {
console.log(`📤 Uploading ${file.name}...`);
const formData = new FormData();
formData.append('file', file);
formData.append('configId', knowledgeBaseId);
const response = await fetch('/api/v1/knowledge-base/documents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${yourAuthToken}`
},
body: formData
});
const result = await response.json();
if (result.success) {
console.log(`✅ ${file.name} uploaded successfully`);
} else {
console.error(`❌ Failed to upload ${file.name}:`, result.error.message);
}
// Wait 1 second between uploads to respect rate limits
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
Example 2: Build a Search Interface
// Create a simple search UI
async function searchKnowledgeBase(searchTerm, knowledgeBaseId) {
// Show loading state
document.getElementById('results').innerHTML = '⏳ Searching...';
const response = await fetch('/api/v1/knowledge-base/query', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${yourAuthToken}`
},
body: JSON.stringify({
query: searchTerm,
configId: knowledgeBaseId
})
});
const result = await response.json();
if (result.success) {
// Display answer
document.getElementById('results').innerHTML = `
<div class="answer">
<h3>Answer:</h3>
<p>${result.data.answer}</p>
</div>
<div class="sources">
<h4>Sources:</h4>
${result.data.sources.map(source => `
<div class="source">
📄 ${source.metadata.fileName} (Score: ${source.score})
</div>
`).join('')}
</div>
`;
} else {
document.getElementById('results').innerHTML = `
<div class="error">❌ ${result.error.message}</div>
`;
}
}
Example 3: Batch Document Cleanup
// Delete all failed documents
async function cleanupFailedDocuments(knowledgeBaseId) {
// Get all documents
const response = await fetch(
`/api/v1/knowledge-base/documents?configId=${knowledgeBaseId}`,
{
headers: {
'Authorization': `Bearer ${yourAuthToken}`
}
}
);
const result = await response.json();
if (!result.success) {
console.error('Failed to fetch documents');
return;
}
// Find failed documents
const failedDocs = result.data.documents
.filter(doc => doc.status === 'failed')
.map(doc => doc.id);
if (failedDocs.length === 0) {
console.log('✅ No failed documents to clean up');
return;
}
console.log(`🗑️ Deleting ${failedDocs.length} failed documents...`);
// Bulk delete
const deleteResponse = await fetch('/api/v1/knowledge-base/documents/bulk-delete', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${yourAuthToken}`
},
body: JSON.stringify({
documentIds: failedDocs
})
});
const deleteResult = await deleteResponse.json();
if (deleteResult.success) {
console.log(`✅ Deleted ${deleteResult.data.deleted} failed documents`);
}
}
🆘 Need Help?
Support Resources
- 📧 Email Support: support@axiestudio.se
- 📚 Documentation: https://docs.axiestudio.se
- 💬 Community Forum: https://community.axiestudio.se
Before Contacting Support
Please have ready:
- Your account email
- Knowledge base ID
- Error messages (if any)
- Steps to reproduce the issue
🎓 Next Steps
Now that you know how to use the API, here's what to do next:
- Create your first knowledge base →
- Set up authentication →
- Explore tools & integrations →
- View analytics →
Start small! Upload a few documents, make some queries, and get comfortable with the API before building complex integrations.
Ready to build something amazing? Start coding! 🚀
Last Updated: 2025-01-27
API Version: v1.0.0
Base URL: https://public.axiestudio.se/api/v1