> ## Documentation Index
> Fetch the complete documentation index at: https://docs.juryo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# API de chat

> Un POST, una respuesta — la forma más rápida de ejecutar tu agente desde tu propio sistema

`POST /api/v1/agent/chat` ejecuta tu agente y responde en una sola llamada. Envías un mensaje con un identificador de conversación; Juryo guarda la conversación y responde. Sin sesión que crear, sin transcripción que gestionar, sin stream que interpretar salvo que quieras los tokens según llegan.

* **Base:** `https://chat.juryo.ai`
* **Autenticación:** `Authorization: Bearer sk_live_…` — una **clave secreta** que creas en el canal API (Ajustes → Integraciones → Canales → API → *Clave secreta*). La clave pública `pk_live_…` del canal — la que inserta el [widget](/es/desarrolladores/widget) y acepta la [API de sesiones](/es/desarrolladores/api) — sigue funcionando aquí para las integraciones existentes; los servidores nuevos deben usar la clave secreta

<Note>
  Medido el 17 de agosto de 2026 con el agente en producción de un cliente: respuesta completa en **unos 3 segundos** (3,2 s en frío, 2,8–3,2 s en caliente), primer token en **unos 2 segundos**. La [API de sesiones](/es/desarrolladores/api) con el mismo agente: 6–11 s hasta la respuesta completa. Elige este endpoint cuando la latencia importa. Usa la [API de sesiones](/es/desarrolladores/api) cuando tu integración necesite que el agente te pregunte o pida aprobaciones a mitad de conversación, trabajos largos, o los controles de cancelar/limpiar/compactar/reiniciar — la tabla comparativa de esa página las muestra lado a lado.
</Note>

## La llamada

```bash theme={null}
curl https://chat.juryo.ai/api/v1/agent/chat \
  -H 'Authorization: Bearer sk_live_TU_CLAVE' \
  -H 'content-type: application/json' \
  -d '{"id": "conv-8841", "text": "Hola, quiero información sobre una reclamación por un accidente de tráfico."}'
```

```json theme={null}
{"id": "conv-8841", "text": "Hola, soy el asistente de tu despacho. Encantado de atenderte.\n\n¿Con quién tengo el gusto?"}
```

Envía el siguiente mensaje con el **mismo `id`** — el agente recuerda la conversación.

| Campo  | Reglas                                                                                                                                                                                         |
| ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`   | Tu identificador de conversación, 1–200 caracteres. Mismo `id` = misma conversación. Usa uno por conversación de usuario final (un número de expediente, un id de chat, un hash del teléfono). |
| `text` | El mensaje del usuario, 1–20.000 caracteres.                                                                                                                                                   |

Juryo es dueño de la transcripción: envía solo el mensaje nuevo, nunca una lista de mensajes.

## Modos de respuesta

Se eligen con la cabecera `Accept`.

| `Accept`                         | Recibes                                                                                                                           | Úsalo para                                                                     |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| *(ninguno)* o `application/json` | `{"id", "text"}` cuando la respuesta está completa — por defecto                                                                  | Integraciones servidor a servidor                                              |
| `text/plain`                     | La respuesta en streaming como texto plano, token a token                                                                         | Interfaces de chat que muestran la respuesta según llega                       |
| `text/event-stream`              | El **stream de eventos**: Server-Sent Events estándar, un evento JSON por línea — deltas de texto, actividad de herramientas, fin | Interfaces de chat más ricas que muestran progreso y actividad de herramientas |

### Streaming

```bash theme={null}
curl -N https://chat.juryo.ai/api/v1/agent/chat \
  -H 'Authorization: Bearer sk_live_TU_CLAVE' \
  -H 'accept: text/plain' \
  -H 'content-type: application/json' \
  -d '{"id": "conv-8841", "text": "¿Qué documentación necesitáis de mí?"}'
```

Lee el cuerpo según llega; la conexión se cierra cuando la respuesta está completa. Envía el siguiente mensaje con el mismo `id` cuando termine.

### Stream de eventos

[Server-Sent Events](https://developer.mozilla.org/es/docs/Web/API/Server-sent_events) estándar: cada línea es `data: ` seguido de un objeto JSON con un `type`; el stream termina con `data: [DONE]`. Cualquier cliente SSE en cualquier lenguaje lo lee — sin librerías.

```bash theme={null}
curl -N https://chat.juryo.ai/api/v1/agent/chat \
  -H 'Authorization: Bearer sk_live_TU_CLAVE' \
  -H 'accept: text/event-stream' \
  -H 'content-type: application/json' \
  -d '{"id": "conv-8841", "text": "¿Qué documentación necesitáis de mí?"}'
```

```
data: {"type":"start"}
data: {"type":"start-step"}
data: {"type":"text-start","id":"0"}
data: {"type":"text-delta","id":"0","delta":"Hola,"}
data: {"type":"text-delta","id":"0","delta":" soy el asistente"}
data: {"type":"text-end","id":"0"}
data: {"type":"finish-step"}
data: {"type":"finish","finishReason":"stop"}
data: [DONE]
```

| `type`                                                           | Significado                                                                                              |
| ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `start` / `finish`                                               | La respuesta empieza / termina. `finish` lleva `finishReason` (`stop`, `length`, `tool-calls`, `error`). |
| `start-step` / `finish-step`                                     | Un paso del modelo; una respuesta que usa herramientas tiene varios.                                     |
| `text-start` / `text-delta` / `text-end`                         | Un segmento de texto: concatena cada `delta` al segmento con ese `id`.                                   |
| `tool-input-start` / `tool-input-delta` / `tool-input-available` | El agente llama a una herramienta: `toolName`, `toolCallId`, y después el `input` completo.              |
| `tool-output-available`                                          | El resultado (`output`) de la herramienta para ese `toolCallId`.                                         |
| `tool-output-error`                                              | La herramienta falló (`errorText`).                                                                      |
| `error`                                                          | El turno falló (`errorText`); el stream termina.                                                         |
| `[DONE]`                                                         | Fin del stream (no es JSON).                                                                             |

Concatena los `text-delta` para obtener el mismo texto que devuelve el modo JSON. Ignora los tipos de evento que no manejes — pueden aparecer nuevos.

### Clientes AI SDK

El stream de eventos es el [protocolo de UI message stream del AI SDK](https://ai-sdk.dev/docs/ai-sdk-ui/stream-protocol) (`x-vercel-ai-ui-message-stream: v1` en la respuesta), así que los clientes del AI SDK funcionan contra este endpoint sin adaptador:

```ts theme={null}
import { DefaultChatTransport } from "ai";

const transport = new DefaultChatTransport({
  api: "https://chat.juryo.ai/api/v1/agent/chat",
  headers: {
    accept: "text/event-stream",
    authorization: `Bearer ${process.env.JURYO_API_KEY}`,
  },
  // Juryo guarda la transcripción en el servidor — envía solo el mensaje nuevo.
  prepareSendMessagesRequest: ({ api, body, headers, id, messages }) => ({
    api,
    body: { ...body, id, message: messages.at(-1) },
    headers,
  }),
});
```

Pasa el transport a `useChat` (React) o a cualquier otro cliente de chat del AI SDK.

## Autenticación y claves

La clave bearer es la que creas en **Configuración → Integraciones → Canales → API**. Una clave está vinculada a un agente — la clave decide qué agente responde — así que crea una clave por cada agente que quieras exponer.

<Warning>
  Guarda la clave secreta en tu servidor — nunca en el navegador ni en una app móvil. Se almacena como hash y se muestra una sola vez, al crearla. Para rotarla, abre el canal y pulsa **Regenerar**: la clave anterior deja de funcionar al instante. La clave pública `pk_live_…` es la del widget y puede aparecer en una página; este endpoint la sigue aceptando para que las integraciones existentes no se rompan, pero no es la clave sobre la que construir una integración nueva de servidor.
</Warning>

## Errores

| Estado | Significado                                                                                                                  |
| ------ | ---------------------------------------------------------------------------------------------------------------------------- |
| `400`  | El cuerpo no es JSON, o falta `id` / `text` o son demasiado largos (detalle en `issues`)                                     |
| `401`  | Clave ausente o desconocida                                                                                                  |
| `403`  | La clave no tiene agente asociado                                                                                            |
| `404`  | El agente de la clave está inactivo                                                                                          |
| `429`  | Límite de peticiones superado — 60 turnos por minuto por clave; espera los segundos de la cabecera `Retry-After` y reintenta |

En los modos de streaming, un fallo a mitad de respuesta cierra el stream antes de tiempo (el stream de eventos envía antes un evento `error`); reintenta con el mismo `id`.

## Conviene saber

* **Memoria:** la conversación se guarda por agente e `id`, y se reproduce en cada turno. Nada más — ni hilo en la bandeja, ni contacto — se crea desde este endpoint hoy.
* **Herramientas:** las integraciones conectadas del agente (calendario, correo vía Composio) y las herramientas HTTP definidas por tu administrador se ejecutan en línea. Las herramientas específicas de WhatsApp (acciones de contacto y pipeline) no están en esta superficie.
* **Modelo y razonamiento** son los que configuraste para el agente en Configuración → Agentes; la misma configuración gobierna ambas APIs.
* Un turno puede durar hasta 300 s cuando hay herramientas; lo típico son 3–5 s.
