Skip to main content
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:
CampoTipoRequeridoDescripción
querystringEl mensaje del usuario (también podés usar message)
conversationIdstringID de conversación. Usá un UUID único para nueva conversación
streamingbooleanSi es true, usa Server-Sent Events para streaming. Default: true
channelstringCanal de origen: api, web, whatsapp, etc. Default: api
attachmentsarrayArchivos 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:
CampoTipoRequeridoDescripción
namestringNombre del agente
descriptionstringDescripción breve
instructionsstringInstrucciones de sistema (comportamiento del agente)
modelstringModelo de IA (gpt-4o, gpt-4o-mini, claude-3-5-sonnet). Default: gpt-4o-mini
temperaturenumberCreatividad (0-1). Default: 0.7
toolsarrayHerramientas 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

Chat widget personalizado

<!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;
}
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
    }
  }
}
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