Descripción General

AIDARA API es una plataforma para integrar asistentes conversacionales en aplicaciones propias. Cada área temática (por ejemplo RRHH o normativa interna) dispone de documentos indexados que el asistente puede consultar al responder (RAG). Las respuestas del chat se entregan únicamente en streaming (Server-Sent Events, SSE).

Características Principales

  • Streaming en Tiempo Real: Respuestas progresivas tipo-ChatGPT
  • Autenticación Robusta: Sistema de API Keys con rate limiting
  • Health Checks: Monitoreo del estado del servicio
  • API Simple: Endpoints intuitivos y fáciles de usar

Casos de Uso

  • Chatbots Inteligentes: Asistentes virtuales para atención al cliente
  • Asistentes Educativos: Tutores personalizados para e-learning
  • Herramientas Empresariales: Automatización de tareas de oficina
  • Análisis de Contenido: Procesamiento inteligente de documentos
  • Asistentes de Código: Ayuda para desarrolladores
  • Creación de Contenido: Generación automática de textos

Ecosistema AIDARA

Esta página documenta la API para equipos de desarrollo que integran el chat en aplicaciones, webs o intranets. La gestión de documentos y las pruebas funcionales para personal no técnico se hace en el panel web de administración.

URL (producción) Audiencia Para qué sirve
https://api.wittymindsets.com/aidara/docs/ Estás aquí Desarrolladores Guía de integración: chat con streaming (POST /chat/send), autenticación, ejemplos y códigos de error
https://admin.wittymindsets.com/aidara/ Administradores de cliente Subir y mantener documentos, consultar disponibilidad, probar preguntas y ayuda del panel
https://api.wittymindsets.com/aidara/service-status/ Integradores y operaciones Estado del servicio AIDARA (API, IA y proveedores), disponibilidad reciente e incidencias

Si eres desarrollador

  • Usa la chat API key del área temática (RRHH, legal, etc.) en X-API-Key.
  • La base de la API es https://api.wittymindsets.com/aidara; esta guía está en /aidara/docs/.
  • Integra POST /chat/send consumiendo SSE (Accept: text/event-stream).

Si eres administrador de cliente

  • Entra en el panel de administración con tu usuario corporativo.
  • Gestiona documentos por área; no necesitas leer esta guía de integración.
  • En el panel, menú Ayuda → «Integración técnica» enlaza a esta documentación para tu equipo IT.
  • Usa Probar consulta para validar respuestas tras subir ficheros.
Flujo habitual: el administrador de cliente publica documentos en aidara-admin → el desarrollador integra el chat con la chat_api_key del área → los usuarios finales consultan desde la aplicación de la organización.

Autenticación

Obtener la chat API key

Cada área temática tiene una clave propia (client_document_areas.chat_api_key). Witty Mindsets la entrega al equipo técnico tras el alta del cliente:

La API key legacy del cliente (api_clients.api_key) ya no sirve para el chat. Los documentos los gestionan los administradores de cliente en aidara-admin.

Cabecera en cada petición

Incluye la chat API key del área en la cabecera X-API-Key:

X-API-Key: aidara_chat_xxxxxxxx
Content-Type: application/json

Comprueba la configuración del área:

GET /chat/test
GET /clients/info
Seguridad: No expongas la clave en el front-end público sin un proxy backend. Una clave identifica un área concreta y sus documentos asociados.

Información Base

URL Base

https://api.wittymindsets.com/aidara

Formato de respuesta

GET /health y otros endpoints de información devuelven JSON.

POST /chat/send solo streaming:

  • Content-Type: text/event-stream
  • Cabecera recomendada: Accept: text/event-stream

Límites y Restricciones

  • Rate limiting: 60 req/min
  • Mensaje máximo: 4000 chars
  • Timeout: 120 segundos

Endpoints Disponibles

Health Check

Verifica el estado del servicio AIDARA y sus dependencias.

Verificación básica:

GET /health

Uso: Verificación rápida de que el servicio está en línea.

{
 "status": "ok",
 "timestamp": "2025-06-16T10:30:00.000Z",
 "service": "AIDARA API",
 "version": "3.5.0"
}

Verificación detallada:

GET /health/detailed

Uso: Verificación completa del estado de base de datos y servicio de IA.

{
 "status": "ok",
 "timestamp": "2025-06-16T10:30:00.000Z",
 "service": "AIDARA API",
 "version": "3.5.0",
 "checks": {
 "database": "ok",
 "openai": "ok"
 },
 "uptime": 123456,
 "memory": {
 "rss": 123456789,
 "heapTotal": 123456789,
 "heapUsed": 123456789
 }
}
Enviar Mensaje con Streaming

Endpoint principal. Envía un mensaje al asistente y recibe la respuesta solo en streaming (SSE en tiempo real). Para mantener el contexto entre mensajes, reenvía el previous_response_id (resp_…) devuelto en el evento complete del turno anterior.

POST /chat/send

Cabeceras requeridas:

X-API-Key: tu-chat-api-key-del-area
Content-Type: application/json
Accept: text/event-stream

Parámetros del cuerpo:

Parámetro Tipo Requerido Descripción
message string Mensaje a enviar al asistente (máx 4000 chars)
previous_response_id string Opcional ID de respuesta OpenAI (resp_…) del turno anterior; encadena el contexto. Usar el valor del evento complete. Omitir en el primer mensaje.
thread_id string Opcional Alias heredado de previous_response_id (compatibilidad). Si se envían ambos, prevalece previous_response_id.

Respuesta (Streaming SSE):

La respuesta llega como Server-Sent Events con los siguientes tipos de eventos:

Tipo de Evento Descripción Datos
start Inicio del procesamiento Sin datos relevantes
content Contenido progresivo de la respuesta Fragmentos de texto
complete Respuesta completa con estadísticas Objeto con message, tokens, previous_response_id (resp_…) y thread_id (alias heredado, mismo valor)
error Error durante el procesamiento Mensaje de error

Ejemplo de flujo de eventos:

// Inicio
data: {"type": "start", "data": null}

// Contenido progresivo
data: {"type": "content", "data": "Hola, "}
data: {"type": "content", "data": "¿en qué puedo "}
data: {"type": "content", "data": "ayudarte?"}

// Finalización (guardar previous_response_id para el siguiente mensaje)
data: {"type": "complete", "data": {
 "message": "Hola, ¿en qué puedo ayudarte?",
 "tokens": {
 "input": 15,
 "output": 8,
 "total": 23
 },
 "previous_response_id": "resp_abc123",
 "thread_id": "resp_abc123"
}}

Ejemplos de Código

Ejemplos con cURL

# Verificar estado de la API
curl -X GET https://api.wittymindsets.com/aidara/health

# Verificar estado detallado
curl -X GET https://api.wittymindsets.com/aidara/health/detailed

# Enviar mensaje (solo streaming SSE)
curl -X POST \
 https://api.wittymindsets.com/aidara/chat/send \
 -H "X-API-Key: tu-chat-api-key-del-area" \
 -H "Content-Type: application/json" \
 -H "Accept: text/event-stream" \
 -d '{
 "message": "Explícame qué es la IA",
 "previous_response_id": "resp_abc123"
 }' \
 --no-buffer

Ejemplo con JavaScript (Browser)

class AidaraAPI {
 constructor(apiKey, baseUrl = 'https://api.wittymindsets.com/aidara') {
 this.apiKey = apiKey;
 this.baseUrl = baseUrl;
 }

 async checkHealth() {
 const response = await fetch(`${this.baseUrl}/health`);
 return response.json();
 }

 async checkDetailedHealth() {
 const response = await fetch(`${this.baseUrl}/health/detailed`);
 return response.json();
 }

 async sendMessageStreaming(message, previousResponseId = null, onContent, onComplete) {
 const body = { message };
 if (previousResponseId) {
 body.previous_response_id = previousResponseId;
 }

 const response = await fetch(`${this.baseUrl}/chat/send`, {
 method: 'POST',
 headers: {
 'X-API-Key': this.apiKey,
 'Content-Type': 'application/json',
 'Accept': 'text/event-stream'
 },
 body: JSON.stringify(body)
 });

 if (!response.ok) {
 throw new Error(`HTTP ${response.status}: ${response.statusText}`);
 }

 const reader = response.body.getReader();
 const decoder = new TextDecoder();
 let buffer = '';

 try {
 while (true) {
 const { done, value } = await reader.read();
 if (done) break;

 buffer += decoder.decode(value, { stream: true });
 const lines = buffer.split('\n');
 buffer = lines.pop(); // Guardar línea incompleta

 for (const line of lines) {
 if (line.startsWith('data: ')) {
 try {
 const data = JSON.parse(line.slice(6));
 
 switch (data.type) {
 case 'content':
 onContent(data.data);
 break;
 case 'complete':
 onComplete(data.data);
 break;
 case 'error':
 throw new Error(data.data);
 }
 } catch (e) {
 console.warn('Error parsing SSE data:', e);
 }
 }
 }
 }
 } finally {
 reader.releaseLock();
 }
 }
}

// Uso del cliente
const aidara = new AidaraAPI('tu-api-key');

// Verificar estado
aidara.checkHealth().then(console.log);

// Enviar mensaje con streaming
aidara.sendMessageStreaming(
 '¿Puedes explicarme qué es machine learning?',
 null,
 (content) => {
 // Mostrar contenido progresivamente
 document.getElementById('chat').innerHTML += content;
 },
 (data) => {
 console.log('Respuesta completa:', data.message);
 console.log('Tokens usados:', data.tokens);
 console.log('Siguiente turno:', data.previous_response_id || data.thread_id);
 }
).catch(console.error);

Ejemplo con Python

import requests
import json

class AidaraAPI:
 def __init__(self, api_key, base_url='https://api.wittymindsets.com/aidara'):
 self.api_key = api_key
 self.base_url = base_url
 self.headers = {
 'X-API-Key': api_key,
 'Content-Type': 'application/json'
 }

 def check_health(self):
 """Verificar estado básico del servicio"""
 response = requests.get(f'{self.base_url}/health')
 response.raise_for_status()
 return response.json()

 def check_detailed_health(self):
 """Verificar estado detallado del servicio"""
 response = requests.get(f'{self.base_url}/health/detailed')
 response.raise_for_status()
 return response.json()

 def send_message_streaming(self, message, previous_response_id=None, on_content=None, on_complete=None):
 """Envía mensaje con streaming"""
 url = f'{self.base_url}/chat/send'
 data = {'message': message}
 if previous_response_id:
 data['previous_response_id'] = previous_response_id

 response = requests.post(
 url,
 headers=self.headers,
 json=data,
 stream=True
 )
 response.raise_for_status()

 for line in response.iter_lines():
 if line:
 line = line.decode('utf-8')
 if line.startswith('data: '):
 try:
 data = json.loads(line[6:])
 event_type = data.get('type')
 
 if event_type == 'content':
 if on_content:
 on_content(data['data'])
 else:
 print(data['data'], end='', flush=True)
 elif event_type == 'complete':
 if on_complete:
 on_complete(data['data'])
 print(f"\nTokens: {data['data'].get('tokens', {})}")
 print(f"previous_response_id: {data['data'].get('previous_response_id') or data['data'].get('thread_id')}")
 elif event_type == 'error':
 raise Exception(f"Error: {data['data']}")
 
 except json.JSONDecodeError:
 continue

# Ejemplo de uso
if __name__ == "__main__":
 aidara = AidaraAPI('tu-api-key')
 
 # Verificar estado
 print("Estado del servicio:")
 print(json.dumps(aidara.check_health(), indent=2))
 
 # Enviar mensaje con streaming
 print("\nEnviando mensaje...")
 aidara.send_message_streaming(
 "Explícame qué es la inteligencia artificial en términos simples"
 )

Ejemplo con Node.js

const fetch = require('node-fetch');

class AidaraAPI {
 constructor(apiKey, baseUrl = 'https://api.wittymindsets.com/aidara') {
 this.apiKey = apiKey;
 this.baseUrl = baseUrl;
 }

 async checkHealth() {
 const response = await fetch(`${this.baseUrl}/health`);
 return response.json();
 }

 async checkDetailedHealth() {
 const response = await fetch(`${this.baseUrl}/health/detailed`);
 return response.json();
 }

 async sendMessageStreaming(message, previousResponseId = null) {
 return new Promise((resolve, reject) => {
 const url = `${this.baseUrl}/chat/send`;
 const headers = {
 'X-API-Key': this.apiKey,
 'Content-Type': 'application/json',
 'Accept': 'text/event-stream'
 };
 const body = { message };
 if (previousResponseId) {
 body.previous_response_id = previousResponseId;
 }

 fetch(url, {
 method: 'POST',
 headers,
 body: JSON.stringify(body)
 })
 .then(response => {
 if (!response.ok) {
 throw new Error(`HTTP ${response.status}: ${response.statusText}`);
 }

 let fullResponse = '';
 let lastResponseId = null;

 response.body.on('data', (chunk) => {
 const lines = chunk.toString().split('\n');
 
 lines.forEach(line => {
 if (line.startsWith('data: ')) {
 try {
 const data = JSON.parse(line.slice(6));
 
 switch (data.type) {
 case 'content':
 process.stdout.write(data.data);
 fullResponse += data.data;
 break;
 case 'complete':
 lastResponseId = data.data.previous_response_id || data.data.thread_id;
                    console.log(`\nCompletado`);
 console.log(`Tokens: ${JSON.stringify(data.data.tokens)}`);
 console.log(`previous_response_id: ${lastResponseId}`);
 resolve({
 previousResponseId: lastResponseId,
 message: fullResponse,
 tokens: data.data.tokens
 });
 break;
 case 'error':
 reject(new Error(data.data));
 break;
 }
 } catch (e) {
 console.warn('Error parsing SSE:', e);
 }
 }
 });
 });

 response.body.on('error', reject);
 })
 .catch(reject);
 });
 }
}

// Uso
async function main() {
 const aidara = new AidaraAPI('tu-api-key');
 
 try {
 // Verificar estado
 console.log('Estado del servicio:');
 console.log(JSON.stringify(await aidara.checkHealth(), null, 2));
 
 console.log('\nEnviando mensaje...\n');
 
 const result = await aidara.sendMessageStreaming(
 '¿Puedes explicarme las ventajas del streaming en APIs?'
 );
 
 console.log(`\nSiguiente turno (previous_response_id): ${result.previousResponseId}`);
 
 } catch (error) {
 console.error('Error:', error.message);
 }
}

main();

Códigos de Error

Errores de Autenticación (401-403)
Código HTTP Descripción Solución
401 API Key requerida Incluye el header X-API-Key con tu clave válida
401 API Key inválida Verifica que la clave API sea correcta y esté activa
403 Límite mensual de tokens excedido Contacta para ampliar tu límite o espera al siguiente mes
Errores de Validación (400)
Código HTTP Descripción Solución
400 Mensaje requerido Incluye el campo message en el cuerpo de la petición
400 Mensaje demasiado largo El mensaje debe tener máximo 4000 caracteres
400 Assistant ID no configurado Contacta soporte - problema de configuración de cuenta
Errores de Rate Limiting (429)
Código HTTP Descripción Solución
429 Rate limit excedido Espera 1 minuto antes de realizar otra petición
429 Demasiadas peticiones Reduce la frecuencia de peticiones (máx 60/min)
429 Límite de rate de OpenAI excedido Intenta de nuevo en unos momentos - límite del proveedor de IA
Errores de Servicio (500-503)
Código HTTP Descripción Solución
500 Error interno del servidor Contacta con soporte técnico
500 Error al encadenar conversación Verifica que el previous_response_id sea válido o inicia un turno nuevo sin él
500 Error al enviar mensaje Verifica el formato del mensaje y reintenta
500 Error al ejecutar asistente Problema con el servicio de IA, contacta soporte
503 Error al conectar con OpenAI Servicio temporalmente no disponible, reintenta en unos minutos
503 Health check fallido Servicio degradado - algunos componentes no están disponibles

Estructura de Respuesta de Error

{
 "success": false,
 "error": "Descripción del error",
 "code": "CODIGO_ESPECIFICO",
 "details": {
 // Información adicional del error (opcional)
 }
}

Errores Durante el Streaming

Durante el streaming, los errores se envían como eventos SSE del tipo error:

data: {
 "type": "error", 
 "timestamp": "2025-06-16T10:30:00.000Z",
 "data": "Descripción del error"
}
Error Descripción Acción
El asistente falló Error en la ejecución del asistente de IA Reintenta o contacta soporte
El procesamiento fue cancelado El run fue cancelado por el sistema Reintenta la petición
El procesamiento expiró Timeout en la respuesta del asistente Reintenta con un mensaje más simple
El asistente no generó respuesta Problema de configuración del asistente Contacta soporte técnico

Manejo de Errores en Cliente

Implementa siempre manejo de errores robusto: captura errores HTTP, eventos SSE de error, timeouts de conexión y desconexiones inesperadas. Para errores 429 (rate limiting), implementa backoff exponencial.

Soporte y Contacto

Soporte Técnico

  • Email: support@wittymindsets.com
  • Horario: Lunes a Viernes, 9:00 - 18:00 (CET)
  • Tiempo de respuesta: < 8 horas laborales

Información para Soporte

Cuando contactes con soporte, incluye:

  • • Código de error HTTP
  • • Mensaje de error completo
  • • Timestamp de la petición
  • • Tu API Key (solo los primeros 8 caracteres)
  • • Código de ejemplo que falla

Soporte Comercial

  • Email: comercial@wittymindsets.com
  • Horario: Lunes a Viernes, 9:00 - 18:00 (CET)
  • Consultas: Precios, límites, upgrades

Enlaces útiles

¿Listo para empezar?

Solicita tu API Key personalizada y comienza a integrar asistentes de IA en minutos:

  1. Contacta comercial@wittymindsets.com
  2. Recibe tu API Key y configuración de asistente
  3. Prueba el endpoint de health: GET /health
  4. Prueba los ejemplos de código con POST /chat/send
  5. Integra en tu aplicación
  6. ¡Disfruta del streaming en tiempo real!