JavaScript / Node.js Examples
Complete examples for integrating DocBit AI into your JavaScript application.Installation
Copy
npm install axios
Basic Setup
Copy
const axios = require('axios');
const DocBit AIClient = axios.create({
baseURL: 'https://api.docbit.ai',
headers: {
'Authorization': `ApiKey ${process.env.DOCBIT_API_KEY}`,
'Content-Type': 'application/json'
}
});
// Helper to add required headers
function withContext(orgId, userId, roles) {
return {
headers: {
'X-External-Org-Id': orgId,
'X-External-User-Id': userId,
'X-External-Roles': JSON.stringify(roles)
}
};
}
Chat Request
Copy
async function askQuestion(orgId, userId, roles, question, conversationId = null) {
const response = await DocBit AIClient.post(
'/api/ai/chat',
{
message: question,
conversationId
},
withContext(orgId, userId, roles)
);
return response.data;
}
// Usage
const answer = await askQuestion(
'acme',
'user-456',
['hr', 'all-staff'],
'What is our vacation policy?'
);
console.log(answer.content);
console.log('Citations:', answer.citations);
Streaming Chat
Copy
const EventSource = require('eventsource');
function streamChat(orgId, userId, roles, question, onToken, onDone) {
return new Promise((resolve, reject) => {
const body = JSON.stringify({ message: question });
// Note: EventSource doesn't support POST, use fetch with ReadableStream
fetch('https://api.docbit.ai/api/ai/chat/stream', {
method: 'POST',
headers: {
'Authorization': `ApiKey ${process.env.DOCBIT_API_KEY}`,
'Content-Type': 'application/json',
'X-External-Org-Id': orgId,
'X-External-User-Id': userId,
'X-External-Roles': JSON.stringify(roles)
},
body
}).then(async response => {
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));
if (data.token) {
onToken(data.token);
} else if (data.citations) {
onDone(data);
resolve(data);
}
}
}
}
}).catch(reject);
});
}
// Usage
let fullResponse = '';
await streamChat(
'acme',
'user-456',
['employee'],
'Summarize the benefits package',
(token) => {
fullResponse += token;
process.stdout.write(token);
},
(done) => {
console.log('\n\nCitations:', done.citations);
}
);
Upload Document
Copy
const FormData = require('form-data');
const fs = require('fs');
async function uploadDocument(orgId, userId, roles, filePath, aclRoles = []) {
const form = new FormData();
form.append('file', fs.createReadStream(filePath));
if (aclRoles.length > 0) {
aclRoles.forEach(role => form.append('aclRoles', role));
}
const response = await DocBit AIClient.post(
'/api/documents/upload',
form,
{
...withContext(orgId, userId, roles),
headers: {
...withContext(orgId, userId, roles).headers,
...form.getHeaders()
}
}
);
return response.data;
}
// Usage - upload HR document visible only to HR team
await uploadDocument(
'acme',
'admin-1',
['admin'],
'./hr-policy.pdf',
['hr']
);
// Upload company-wide document
await uploadDocument(
'acme',
'admin-1',
['admin'],
'./employee-handbook.pdf',
['all-staff']
);
Express Middleware
Copy
const express = require('express');
const app = express();
// Middleware to add DocBit AI headers from your session
function DocBit AIContext(req, res, next) {
// Get user from your auth system
const user = req.session.user;
req.DocBit AIHeaders = {
'X-External-Org-Id': user.organizationId,
'X-External-User-Id': user.id,
'X-External-Roles': JSON.stringify(user.roles)
};
next();
}
app.use(DocBit AIContext);
app.post('/api/ask', async (req, res) => {
try {
const response = await DocBit AIClient.post(
'/api/ai/chat',
{ message: req.body.question },
{ headers: req.DocBit AIHeaders }
);
res.json(response.data);
} catch (error) {
res.status(error.response?.status || 500).json({
error: error.response?.data?.error || 'Internal error'
});
}
});
Error Handling
Copy
async function safeAsk(orgId, userId, roles, question) {
try {
return await askQuestion(orgId, userId, roles, question);
} catch (error) {
if (error.response) {
switch (error.response.status) {
case 400:
throw new Error(`Bad request: ${error.response.data.error}`);
case 401:
throw new Error('Authentication failed. Check API key.');
case 429:
// Rate limited - implement retry with backoff
await sleep(1000);
return safeAsk(orgId, userId, roles, question);
default:
throw new Error(`API error: ${error.response.status}`);
}
}
throw error;
}
}
TypeScript Types
Copy
interface ChatRequest {
message: string;
conversationId?: string;
documentIds?: string[];
folderIds?: string[];
}
interface Citation {
documentId: string;
documentTitle: string;
page?: number;
section?: string;
excerpt: string;
}
interface ChatResponse {
conversationId: string;
content: string;
citations: Citation[];
confidence: 'High' | 'Medium' | 'Low';
}
async function askQuestion(
orgId: string,
userId: string,
roles: string[],
question: string
): Promise<ChatResponse> {
// ... implementation
}