Skip to content

HTTP sin streaming

Un turno de agente desde tu backend: mandas un mensaje, esperas, y recibes la respuesta completa de una vez. Sin SSE y sin navegador.

Es la vía para procesos batch, webhooks de otros sistemas o bots de mensajería — cualquier cosa que no sea la pantalla de un usuario final.

No está en el OpenAPI

A diferencia del resto de /api/*, estos dos endpoints no aparecen en /api/openapi.json ni en el navegador de /api/docs de tu instancia. Esta página es su referencia.

Diferencias con el canal público

/embed/* (widget y SDK)POST /api/agents/…/invoke
AutenticaciónNingunaAccess token
RespuestaStreaming, token a tokenCompleta, de una vez
IdentidadLa genera el navegadorLa eliges tú (subjectId)
Desde el navegadorNo — no hay CORS
Errores del modeloMensaje de catálogoEl error real
HilosCanal widget / js_sdkCanal api, separado

Ese último punto importa: las conversaciones que abras por aquí no comparten hilo con las del widget o el SDK, aunque uses el mismo subjectId.

GET /api/agents/{identifier}

Comprueba que el agente existe y que tu token puede usarlo.

bash
curl https://ur.tuempresa.com/api/agents/soporte \
  -H "Authorization: Bearer $UR_TOKEN"
json
{ "name": "Soporte", "identifier": "soporte" }

Aquí va el slug, no el UUID

En el widget y el SDK puedes usar indistintamente el identifier o el id del agente. En estos dos endpoints solo se resuelve por identifier.

POST /api/agents/{identifier}/invoke

bash
curl -X POST https://ur.tuempresa.com/api/agents/soporte/invoke \
  -H "Authorization: Bearer $UR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "¿Cuál es el plazo de devolución?",
    "subjectId": "usuario-4821"
  }'

Cuerpo

CampoTipoDescripción
messagestringObligatorio. No puede estar vacío.
subjectIdstringObligatorio. Identidad estable de tu usuario final.

subjectId es lo que da memoria a la conversación

Es lo que permite reanudar el hilo entre llamadas: manda el mismo valor y el agente recuerda lo hablado; manda uno nuevo y empieza de cero. Lo natural es el id de usuario de tu sistema.

No es opcional a propósito — sin él no habría forma de continuar una conversación.

Respuesta

json
{
  "agent": "soporte",
  "threadId": "01931f2c-...",
  "response": [{ "type": "text", "text": "El plazo de devolución es de 30 días..." }],
  "toolCalls": [
    { "name": "documentacion", "args": { "query": "devoluciones" }, "result": "..." }
  ]
}
CampoDescripción
agentEl identifier del agente
threadIdId del hilo. El mismo subjectId devuelve siempre el mismo
responseBloques de contenido de la respuesta. El texto está en los de type: "text"
toolCallsTools invocadas en este turno, con sus argumentos y su resultado
noticeSolo en el primer mensaje de un hilo, si el agente tiene mensaje automático

Cuando el mensaje se bloquea

Un mensaje filtrado por seguridad devuelve 200, no un error, con un campo extra:

json
{
  "agent": "soporte",
  "threadId": "01931f2c-...",
  "response": [{ "type": "text", "text": "No puedo ayudarte con eso." }],
  "toolCalls": [],
  "security": { "blocked": true, "checkType": "forbidden_words" }
}

Esta es la única vía donde puedes distinguir un bloqueo programáticamente: por el canal público es indistinguible de una respuesta normal, a propósito.

Errores

CódigoCuándo
400Falta message o subjectId, JSON mal formado, o el agente no tiene modelo configurado
401Token ausente o inválido
403El token no tiene permiso sobre este agente
404No existe ningún agente con ese identifier
429Superado el límite de 60 peticiones por minuto
502Falló el modelo

Aquí sí ves el error real

Al contrario que el canal público —que devuelve siempre un mensaje de catálogo para no filtrar detalles internos—, este canal es para desarrolladores y el 502 trae el mensaje de error real del proveedor. La excepción es cuando el proveedor está saturado: ahí se usa el mensaje del catálogo.

Los límites por agente también aplican

Recorte de longitud, límite por hora, ráfaga y filtros de contenido se aplican igual que en el canal público. Aquí la identidad para contar es el subjectId que tú mandas.

Ver Seguridad y límites.