Documentación de la API
Una guía completa para integrarse con la API de BrainBox
Overview
The BrainBox API provides programmatic access to your document collections. It enables two main capabilities:
- AI-powered semantic search — Find the most relevant content across your documents using natural language queries. The API uses vector embeddings and AI reranking to understand query intent and return highly relevant passages.
- Complete document retrieval — Get full document content for processing, display, or feeding into RAG pipelines. Retrieve entire documents page by page, or download original files via signed URLs.
- OpenAI-compatible chat completions — Ask questions over your documents using an endpoint that follows the OpenAI Chat Completions format, making it a drop-in replacement for any OpenAI-compatible client library.
All endpoints return JSON responses with a consistent success field. Rate limits, usage headers, and standardized error codes are included in every response to help you build robust integrations.
Base URL
All API requests are made to the following base URL. All endpoints use HTTPS — plain HTTP requests will be rejected.
https://app.brainbox.com.co/api/public/v1
Autenticación
BrainBox autentica las solicitudes de la API usando Tokens Bearer. Debes incluir una clave de API en el Authorization encabezado de cada solicitud.
Authorization: Bearer YOUR_API_KEY
Tu Clave de API
Puedes generar y administrar claves de API desde el panel de BrainBox en Cuenta → Claves de API. Las claves siguen el formato: bbfe_[prefix]_[secret_key]
Keep your API key secure. Do not share it in public repositories, client-side code, or expose it in URLs. If you believe a key has been compromised, revoke it immediately from your dashboard and generate a new one. Each key can be independently revoked without affecting other keys.
Conceptos Principales
Unidades de Inteligencia
Algunas operaciones consumen unidades para tareas intensivas de IA. Tu plan incluye una cuota mensual. Intelligence units are consumed when the API performs AI-intensive operations like semantic search or answering questions. Simple retrieval operations (listing files, downloading documents) are free.
| Operation | Cost | Notes |
|---|---|---|
| /chat/completions | 1–10 units | Varies by query complexity and context retrieved |
| /retrieve-documents | 1–5 units | Semantic search + AI reranking |
| /retrieve-full-documents | Free | Direct retrieval, no AI processing |
| /files | Free | Lists file metadata only |
| /signed-url | Free | Generates temporary download link |
Control de Acceso
El acceso a la API está vinculado a los permisos del usuario para un box específico.API keys inherit the permissions of the user who created them. Each API key is scoped to the user's account — you can only access boxes where the key owner has the appropriate role.
- Rol Requerido: Propietario y Administrador — these roles have full API access to their boxes.
VieweryEditorno pueden usar la API. Attempting to access a box with insufficient permissions returns errorB3002.
Límites Técnicos
Cada clave de API y cuenta de usuario están sujetas a diferentes límites de velocidad para garantizar un uso óptimo de la API. Puedes rastrear fácilmente tu uso con encabezados incluidos en las respuestas de la API que indican tu límite de velocidad restante.
| Recurso | Límite de Velocidad | Ventana |
|---|---|---|
| Clave de API | 100 solicitudes | 60 segundos |
| Cuenta de Usuario | 15,000 solicitudes | 24 horas |
When you exceed a rate limit, the API returns HTTP 429 Too Many Requests with error code B3107. Use the reset headers below to determine when you can retry.
Encabezados de Límite de Velocidad
Encabezados HTTP devueltos por la API para ayudarte a monitorear y administrar tus límites de solicitudes. These headers are included in every API response, even successful ones, so you can proactively monitor your usage and avoid hitting limits.
| Header | Description |
|---|---|
X-RateLimit-Hits | Número de solicitudes usadas en la ventana actual. |
X-RateLimit-Remaining-Key | Solicitudes restantes para la clave de API en la ventana actual. |
X-RateLimit-Remaining-User | Solicitudes restantes para la cuenta de usuario en este período de 24 horas. |
X-RateLimit-Reset-Key | Tiempo cuando se reinicia el límite de velocidad de la clave de API. |
X-RateLimit-Reset-User | Tiempo cuando se reinicia el límite de velocidad del usuario. |
Manejo de Errores
When an API request fails, BrainBox returns a standardized error response to help you identify and resolve issues quickly. Always check the success field in responses — if false, the error object contains a unique code, category, summary, and cause.
Formato de Respuesta de Error
Las solicitudes fallidas devuelven un objeto de error estándar con un código único y detalles.
{
"success": false,
"error": {
"code": "B3002",
"category": "permissions",
"summary": "Unauthorized user",
"cause": "API Key not found"
}
}Códigos de Error Comunes
| Code | Type | Description |
|---|---|---|
B3002 | Error de Autenticación: | Clave de API inválida, expirada o faltante, o permisos insuficientes. |
B3107 | Cuota Excedida: | Unidades de inteligencia insuficientes. |
B1004 | Parámetros Inválidos: | Parámetros de solicitud faltantes o inválidos. |
B1000 | Error Desconocido: | Error inesperado del servidor. |
Error Categories
permissions— Authentication and authorization issuesquota— Rate limits or usage quota exceededvalidation— Invalid request format or parametersserver— Internal server errors
Best Practices
- Always check the
successfield in responses before processing data - Log error codes for debugging and monitoring
- Implement retry logic with exponential backoff for
B3107(rate limit) andB1000(server) errors - Monitor rate limit headers proactively to avoid hitting quota limits
Ejemplos de Código
Complete, working examples in cURL, JavaScript (Node.js), and Python. The JavaScript and Python examples include a full API client class with error handling that you can copy directly into your project. Replace YOUR_API_KEY and YOUR_BOX_ID with your actual values.
# Health check
curl -X GET "https://app.brainbox.com.co/api/public/v1/check" \
-H "Authorization: Bearer YOUR_API_KEY"
# Semantic document retrieval (AI search)
curl -X POST "https://app.brainbox.com.co/api/public/v1/boxes/YOUR_BOX_ID/retrieve-documents" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "What is machine learning?",
"sources": ["file_123", "file_456"]
}'
# Full document retrieval (complete content)
curl -X POST "https://app.brainbox.com.co/api/public/v1/boxes/YOUR_BOX_ID/retrieve-full-documents" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sources": ["file_123", "file_456"]
}'
// A robust BrainBox API client for Node.js
class BrainBoxAPI {
constructor(apiKey) {
this.apiKey = apiKey
this.baseUrl = "https://app.brainbox.com.co/api/public/v1"
}
async _request(method, endpoint, body = null) {
const url = `${this.baseUrl}/${endpoint}`
const options = {
method,
headers: {
Authorization: `Bearer ${this.apiKey}`,
"Content-Type": "application/json",
},
}
if (body) {
options.body = JSON.stringify(body)
}
try {
const response = await fetch(url, options)
const data = await response.json()
if (!response.ok || !data.success) {
const error = data.error || { summary: "Unknown API error" }
throw new Error(
`API Error (${error.code}): ${error.summary} - ${error.cause}`
)
}
return data.data
} catch (error) {
console.error(`Request failed: ${error.message}`)
throw error
}
}
// Semantic search with AI ranking (1 intelligence unit)
async searchDocuments(boxId, query, sources = null) {
const endpoint = `boxes/${boxId}/retrieve-documents`
const body = { query }
if (sources) body.sources = sources
return this._request("POST", endpoint, body)
}
// Full document retrieval (FREE - no intelligence units)
async getFullDocuments(boxId, sources) {
if (!sources || sources.length === 0) {
throw new Error("Sources array is required for getFullDocuments.")
}
const endpoint = `boxes/${boxId}/retrieve-full-documents`
return this._request("POST", endpoint, { sources })
}
// Health check
async healthCheck() {
return this._request("GET", "check")
}
}
// --- Usage Example ---
const apiKey = process.env.BRAINBOX_API_KEY
if (!apiKey) {
throw new Error("BRAINBOX_API_KEY environment variable not set.")
}
const client = new BrainBoxAPI(apiKey)
const boxId = "your-box-id"
const fileIds = ["file_123", "file_456"]
async function main() {
try {
console.log("Performing health check...")
const health = await client.healthCheck()
console.log("Health check successful:", health)
console.log("nSearching for documents...")
const searchResults = await client.searchDocuments(
boxId,
"What are the key financial takeaways?",
fileIds
)
console.log(
`Found ${searchResults.documents[0].documents.length} relevant chunks.`
)
console.log(
`Consumed ${searchResults.usage.intelligence_units_consumed} intelligence unit.n`
)
console.log("Retrieving full documents...")
const fullDocs = await client.getFullDocuments(boxId, fileIds)
console.log(
`Retrieved ${fullDocs.usage.documents_retrieved} full documents with ${fullDocs.usage.total_pages} total pages.`
)
fullDocs.documents.forEach((doc) => {
console.log(`- ${doc.fileName} (${doc.pages.length} pages)`)
})
} catch (error) {
console.error(error.message)
}
}
main()
import os
import requests
from typing import List, Optional, Dict, Any
class BrainBoxAPI:
def __init__(self, api_key: str):
if not api_key:
raise ValueError("API key cannot be empty.")
self.api_key = api_key
self.base_url = "https://app.brainbox.com.co/api/public/v1"
self.session = requests.Session()
self.session.headers.update({
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
})
def _request(self, method: str, endpoint: str, json: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
url = f"{self.base_url}/{endpoint}"
try:
response = self.session.request(method, url, json=json)
response.raise_for_status()
data = response.json()
if not data.get('success'):
error = data.get('error', {'summary': 'Unknown API error'})
raise ValueError(f"API Error ({error.get('code')}): {error.get('summary')} - {error.get('cause')}")
return data.get('data') or data
except requests.exceptions.RequestException as e:
raise ConnectionError(f"Request failed: {e}") from e
def search_documents(self, box_id: str, query: str, sources: Optional[List[str]] = None) -> Dict[str, Any]:
"""Search for relevant documents using AI semantic search (1 intelligence unit)."""
payload = {'query': query}
if sources:
payload['sources'] = sources
return self._request('POST', f"boxes/{box_id}/retrieve-documents", json=payload)
def get_full_documents(self, box_id: str, sources: List[str]) -> Dict[str, Any]:
"""Retrieve complete content of specified documents (FREE - no intelligence units)."""
if not sources:
raise ValueError("Sources list cannot be empty for get_full_documents.")
return self._request('POST', f"boxes/{box_id}/retrieve-full-documents", json={'sources': sources})
def health_check(self) -> Dict[str, Any]:
"""Performs a simple health check against the API."""
return self._request('GET', 'check')
# --- Usage Example ---
if __name__ == "__main__":
api_key = os.getenv('BRAINBOX_API_KEY')
if not api_key:
raise ValueError("BRAINBOX_API_KEY environment variable not set.")
client = BrainBoxAPI(api_key)
box_id = 'your-box-id'
file_ids = ['file_123', 'file_456']
try:
print("Performing health check...")
health = client.health_check()
print(f"Health check successful: {health.get('message')}\n")
print("Searching for documents...")
search_results = client.search_documents(box_id, 'What are the key financial takeaways?', file_ids)
print(f"Found {len(search_results['documents'][0]['documents'])} relevant chunks.")
print(f"Consumed {search_results['usage']['intelligence_units_consumed']} intelligence unit.\n")
print("Retrieving full documents...")
full_docs = client.get_full_documents(box_id, file_ids)
print(f"Retrieved {full_docs['usage']['documents_retrieved']} documents with {full_docs['usage']['total_pages']} total pages.")
for doc in full_docs['documents']:
print(f"- {doc['fileName']} ({len(doc['pages'])} pages)")
except (ValueError, ConnectionError) as e:
print(f"Error: {e}")Contáctanos
Si encuentras algún problema o tienes preguntas sobre la API, no dudes en contactar a nuestro equipo de soporte. Visita nuestra página de contacto para más información. For technical support, API troubleshooting, or general inquiries, our team is ready to help you get the most out of the BrainBox API.
Visitar Página de Contacto