Skip to main content

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.

API Version

All endpoints use API v1 and are prefixed with /api/v1/. This ensures stability and backward compatibility.

Who is this for?
  • 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:

  1. ✅ An Axie Studio account
  2. ✅ A knowledge base created in your dashboard
  3. ✅ 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
API Versioning

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'
}
Getting Your 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:

  1. Document is uploaded ⬆️
  2. Text is extracted 📄
  3. AI creates searchable embeddings 🧠
  4. 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:

ActionLimitWindow
Upload documents10 requestsper minute
Query knowledge base60 requestsper minute
Other operations100 requestsper 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 success field 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

CodeMeaningWhat to do
200✅ SuccessUse the data
201✅ CreatedResource created successfully
400❌ Bad RequestCheck your input
401❌ UnauthorizedCheck your auth token
403❌ ForbiddenYou don't have permission
404❌ Not FoundResource doesn't exist
413❌ Too LargeFile is too big
429❌ Rate LimitedWait and retry
500❌ Server ErrorTry again or contact support

🔄 Migrating from Old API

If you're using the old API, here's how to upgrade:

Endpoint Changes

Old EndpointNew EndpointWhat Changed
/api/knowledge-base/upload/api/v1/knowledge-base/documentsAdded version, better naming
/api/knowledge-base/documents/api/v1/knowledge-base/documentsAdded version
/api/knowledge-base/query/api/v1/knowledge-base/queryAdded version, better responses
/api/knowledge-base/collections/list/api/v1/knowledge-base/collectionsCleaner 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

Before Contacting Support

Please have ready:

  1. Your account email
  2. Knowledge base ID
  3. Error messages (if any)
  4. Steps to reproduce the issue

🎓 Next Steps

Now that you know how to use the API, here's what to do next:

  1. Create your first knowledge base →
  2. Set up authentication →
  3. Explore tools & integrations →
  4. View analytics →

Pro Tip

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