Los endpoints de agentes te permiten crear y gestionar agentes de IA, así como enviar mensajes y recibir respuestas.
Endpoints principales
GET /api/agents
Lista todos los agentes de tu organización.
curl https://app.horneross.com/api/agents \
-H "Authorization: Bearer tu_api_key"
Response:
{
"agents" : [
{
"id" : "agent_abc123" ,
"name" : "Asistente de Ventas" ,
"description" : "Ayuda a clientes con consultas de productos" ,
"model" : "gpt-4o-mini" ,
"createdAt" : "2024-01-15T10:30:00Z" ,
"status" : "active"
}
],
"total" : 5 ,
"page" : 1 ,
"limit" : 10
}
POST /api/v2/agent//chat
⭐ Endpoint principal para enviar mensajes a un agente y recibir respuestas.
curl -X POST https://app.horneross.com/api/v2/agent/agent_abc123/chat \
-H "Authorization: Bearer tu_api_key" \
-H "Content-Type: application/json" \
-d '{
"query": "¿Cuáles son los horarios de atención?",
"conversationId": "conv_xyz789",
"streaming": false
}'
Request Body:
Campo Tipo Requerido Descripción querystring ✅ El mensaje del usuario (también podés usar message) conversationIdstring ✅ ID de conversación. Usá un UUID único para nueva conversación streamingboolean ❌ Si es true, usa Server-Sent Events para streaming. Default: true channelstring ❌ Canal de origen: api, web, whatsapp, etc. Default: api attachmentsarray ❌ Archivos adjuntos (imágenes, PDFs, etc.)
Response:
{
"response" : "Nuestros horarios de atención son de Lunes a Viernes de 9:00 a 18:00, y Sábados de 10:00 a 14:00." ,
"conversationId" : "conv_xyz789" ,
"messageId" : "msg_def456" ,
"sources" : [
{
"title" : "Horarios y Contacto" ,
"url" : "https://tuempresa.com/contacto" ,
"excerpt" : "...horarios de atención..."
}
],
"usage" : {
"tokens" : 245 ,
"cost" : 0.00012
}
}
Streaming con Server-Sent Events
Para respuestas en tiempo real con Server-Sent Events:
const response = await fetch (
'https://app.horneross.com/api/v2/agent/agent_abc123/chat' ,
{
method: 'POST' ,
headers: {
'Authorization' : 'Bearer tu_api_key' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
query: 'Contame sobre tus productos' ,
conversationId: 'conv_unique_id' ,
streaming: true
})
}
);
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 = line . slice ( 6 );
if ( data === '[DONE]' ) break ;
try {
const parsed = JSON . parse ( data );
if ( parsed . type === 'text' ) {
process . stdout . write ( parsed . text );
}
} catch ( e ) {
// Ignorar líneas mal formadas
}
}
}
}
POST /api/agents
Crear un nuevo agente programáticamente.
curl -X POST https://app.horneross.com/api/agents \
-H "Authorization: Bearer tu_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Agente de Soporte",
"description": "Asistente de soporte técnico",
"instructions": "Sos un agente de soporte amable...",
"model": "gpt-4o-mini",
"tools": ["datastore_query", "web_search"]
}'
Request Body:
Campo Tipo Requerido Descripción namestring ✅ Nombre del agente descriptionstring ❌ Descripción breve instructionsstring ✅ Instrucciones de sistema (comportamiento del agente) modelstring ❌ Modelo de IA (gpt-4o, gpt-4o-mini, claude-3-5-sonnet). Default: gpt-4o-mini temperaturenumber ❌ Creatividad (0-1). Default: 0.7 toolsarray ❌ Herramientas activas
Herramientas disponibles:
datastore_query - Consultar bases de conocimiento
web_search - Buscar en internet
lead_capture - Capturar información de contactos
http_request - Hacer llamadas HTTP
request_human - Derivar a humano
Response:
{
"id" : "agent_new123" ,
"name" : "Agente de Soporte" ,
"description" : "Asistente de soporte técnico" ,
"model" : "gpt-4o-mini" ,
"status" : "active" ,
"createdAt" : "2024-01-20T15:45:00Z"
}
GET /api/agents/
Obtener detalles de un agente específico.
curl https://app.horneross.com/api/agents/agent_abc123 \
-H "Authorization: Bearer tu_api_key"
Response:
{
"id" : "agent_abc123" ,
"name" : "Asistente de Ventas" ,
"description" : "Ayuda a clientes con consultas" ,
"instructions" : "Sos un asistente de ventas amable..." ,
"model" : "gpt-4o-mini" ,
"temperature" : 0.7 ,
"tools" : [ "datastore_query" , "lead_capture" ],
"datastores" : [ "ds_123" , "ds_456" ],
"status" : "active" ,
"stats" : {
"totalConversations" : 1523 ,
"totalMessages" : 8942 ,
"averageRating" : 4.7
}
}
PUT /api/agents/
Actualizar un agente existente.
await fetch ( 'https://app.horneross.com/api/agents/agent_abc123' , {
method: 'PUT' ,
headers: {
'Authorization' : 'Bearer tu_api_key' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
instructions: 'Nueva instrucción actualizada...' ,
temperature: 0.8
})
});
DELETE /api/agents/
Eliminar un agente.
Esta acción es permanente y eliminará todas las conversaciones asociadas.
curl -X DELETE https://app.horneross.com/api/agents/agent_abc123 \
-H "Authorization: Bearer tu_api_key"
Ejemplos de integración
<! DOCTYPE html >
< html >
< body >
< div id = "chat" >
< div id = "messages" ></ div >
< input id = "input" type = "text" placeholder = "Escribe tu mensaje..." >
< button onclick = " sendMessage ()" > Enviar </ button >
</ div >
< script >
let conversationId = null ;
async function sendMessage () {
const input = document . getElementById ( 'input' );
const message = input . value ;
// Generar conversationId único si es primera vez
if ( ! conversationId ) {
conversationId = 'conv_' + Date . now () + '_' + Math . random (). toString ( 36 ). substr ( 2 , 9 );
}
const response = await fetch (
'https://app.horneross.com/api/v2/agent/agent_abc123/chat' ,
{
method: 'POST' ,
headers: {
'Authorization' : 'Bearer tu_api_key' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
query: message ,
conversationId: conversationId ,
streaming: false
})
}
);
const data = await response . json ();
// Mostrar respuesta
document . getElementById ( 'messages' ). innerHTML +=
`<p><strong>Bot:</strong> ${ data . response } </p>` ;
input . value = '' ;
}
</ script >
</ body >
</ html >
Bot de WhatsApp
from flask import Flask, request
import requests
app = Flask( __name__ )
HORNEROSS_API_KEY = 'tu_api_key'
AGENT_ID = 'agent_abc123'
@app.route ( '/webhook' , methods = [ 'POST' ])
def whatsapp_webhook ():
data = request.json
user_message = data[ 'message' ][ 'text' ]
user_phone = data[ 'from' ]
# Generar conversationId basado en número de teléfono
conversation_id = f 'whatsapp_ { user_phone } '
# Enviar a Horneross
response = requests.post(
f 'https://app.horneross.com/api/v2/agent/ { AGENT_ID } /chat' ,
headers = { 'Authorization' : f 'Bearer { HORNEROSS_API_KEY } ' },
json = {
'query' : user_message,
'conversationId' : conversation_id,
'streaming' : False ,
'channel' : 'whatsapp'
}
)
bot_response = response.json()[ 'response' ]
# Enviar respuesta por WhatsApp
send_whatsapp_message(user_phone, bot_response)
return { 'status' : 'ok' }
Mejores prácticas
Siempre guardá el conversationId entre mensajes para mantener contexto: // ✅ BIEN - Mantiene contexto
let convId = null ;
async function chat ( message ) {
const res = await sendToAgent ( message , convId );
convId = res . conversationId ; // Guardar para próximo mensaje
return res . response ;
}
Manejar errores gracefully
Implementá retry logic y fallbacks: async function sendWithRetry ( message , maxRetries = 3 ) {
for ( let i = 0 ; i < maxRetries ; i ++ ) {
try {
return await sendToAgent ( message );
} catch ( error ) {
if ( i === maxRetries - 1 ) throw error ;
await sleep ( 1000 * Math . pow ( 2 , i )); // Exponential backoff
}
}
}
Usar streaming para mejor UX
Para conversaciones interactivas, usá streaming: const response = await fetch ( agentUrl , {
method: 'POST' ,
body: JSON . stringify ({ query: message , streaming: true })
});
const reader = response . body . getReader ();
while ( true ) {
const { done , value } = await reader . read ();
if ( done ) break ;
updateUI ( value ); // Actualizar UI en tiempo real
}
Próximos pasos