Documentación de la API
Una guía completa para integrarse con la API de BrainBox
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]
Conceptos Principales
Unidades de Inteligencia
Algunas operaciones consumen unidades para tareas intensivas de IA. Tu plan incluye una cuota mensual.
/retrieve-documents: 1 Unidad/retrieve-full-documents: 0 Unidades (Gratis)
Control de Acceso
El acceso a la API está vinculado a los permisos del usuario para un box específico.
- Rol Requerido: Propietario y Administrador
VieweryEditorno pueden usar la API.
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 |
Encabezados de Límite de Velocidad
Encabezados HTTP devueltos por la API para ayudarte a monitorear y administrar tus límites de solicitudes.
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
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
B3002Error de Autenticación: Clave de API inválida, expirada o faltante, o permisos insuficientes.
B3107Cuota Excedida: Unidades de inteligencia insuficientes.
B1004Parámetros Inválidos: Parámetros de solicitud faltantes o inválidos.
B1000Error Desconocido: Error inesperado del servidor.
Ejemplos de Código
# 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.