Agentes
Crear agentes, consultarlos y configurar captura de leads
Un agente (agent) combina una persona, un subconjunto de fuentes (opcional) y la configuración de canales. Cada tenant puede tener varios agentes — por ejemplo uno de soporte y uno de ventas, con fuentes distintas.
Listar agentes
curl https://api.kelova.app/agents \
-H "Authorization: Bearer <token>"[
{
"id": "a1b2c3...",
"tenant_id": "t9f8e7...",
"tenant_slug": "tuempresa",
"name": "Soporte",
"persona": "Eres el asistente de soporte de TuEmpresa...",
"welcome_msg": "Hola, ¿en qué te puedo ayudar?",
"status": "active",
"allowed_origins": ["https://tuempresa.com"],
"cite_sources": true,
"active_channels": ["web"],
"lead_capture_enabled": false,
"lead_notification_email": "",
"plan": "pro",
"store_transcripts": false,
"transcript_retention_days": 30,
"created_at": "2026-06-01T09:00:00Z"
}
]Crear un agente
curl -X POST https://api.kelova.app/agents \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Ventas",
"persona": "Eres el asistente de ventas de TuEmpresa. Responde con precios y disponibilidad solo si están en los documentos indexados.",
"welcome_msg": "¡Hola! Cuéntame qué buscas.",
"cite_sources": true,
"lead_capture_enabled": true,
"lead_notification_email": "ventas@tuempresa.com"
}'Respuesta (201): el mismo shape que GET /agents (un solo objeto, no array). Requiere rol admin.
lead_notification_email es obligatorio y debe ser un email válido cuando lead_capture_enabled: true — si no, 400 INVALID_AGENT_CONFIG.
Actualizar un agente
PUT /agents/{id} acepta actualización parcial — solo los campos enviados se modifican; null/omitido deja el valor actual sin cambios (excepto strings vacíos en name/persona/welcome_msg, que también se ignoran).
curl -X PUT https://api.kelova.app/agents/{id} \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"status": "inactive",
"allowed_origins": ["https://tuempresa.com", "https://app.tuempresa.com"]
}'status acepta active o inactive. transcript_retention_days, cuando se envía, debe ser 7, 30 o 90.
Eliminar un agente
curl -X DELETE https://api.kelova.app/agents/{id} \
-H "Authorization: Bearer <token>"Responde 204 No Content. 404 AGENT_NOT_FOUND si el agente no existe o no es de tu tenant.
Alcance de fuentes (source scoping)
Por defecto un agente consulta todas las fuentes del tenant. Puedes limitarlo a un subconjunto:
# Ver el alcance actual
curl https://api.kelova.app/agents/{id}/sources \
-H "Authorization: Bearer <token>"
# Reemplazar el alcance — array vacío = todas las fuentes (comportamiento por defecto)
curl -X PUT https://api.kelova.app/agents/{id}/sources \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"source_ids": ["3f2e1a...", "9c8b7a..."]}'Ambos devuelven {"source_ids": [...]}. PUT reemplaza el conjunto completo — no es incremental.
Consultar al agente
curl -X POST https://api.kelova.app/agent/query \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"query": "¿Cuál es el precio del plan Pro?",
"agent_id": "a1b2c3..."
}'agent_id es opcional — si lo omites, Kelova usa la configuración por defecto del tenant. session_id es opcional y se usa para la captura de leads en dos turnos (ver abajo). También existe POST /agents/{id}/query, equivalente pero con el agent_id tomado de la URL en vez del body.
Respuesta (200):
{
"answer": "El plan Pro cuesta $299/mes e incluye hasta 5000 documentos indexados y 10000 consultas mensuales.",
"sources": [
{
"source_file": "Catálogo 2026.pdf",
"page_or_row": "4",
"section_title": "Planes y precios",
"synced_at": "2026-07-08T10:15:00Z",
"similarity": 0.87
}
],
"model": "anthropic"
}El campo con las fuentes usadas en la respuesta se llama sources — no uses otro nombre en tu integración. Cada entrada trae synced_at — úsalo para mostrar qué tan fresca es la información, según las reglas de badge de frescura (verde <7 días, amarillo 7–30 días, rojo >30 días).
Si no hay chunks relevantes indexados, el agente nunca inventa una respuesta — devuelve exactamente "No encontré información sobre esto en los documentos indexados." con "sources": [].
Límites: query máximo 1000 caracteres. 402 si tu plan Free alcanzó el límite de consultas; 429 si excedes el rate limit por tenant.
Captura de leads
La captura de leads (lead_capture_enabled + lead_notification_email, configurados en el agente) no tiene endpoints propios — corre automáticamente dentro del pipeline de POST /agent/query en dos turnos: el primero detecta intención de compra y crea el lead sin datos de contacto, el segundo detecta datos de contacto en la conversación y notifica al lead_notification_email configurado (por email + notificación in-app en el dashboard). No hay POST /leads — los leads se consultan desde el dashboard, no desde esta API pública.