Variante en streaming de POST /chat: misma autenticación, mismos parámetros de entrada, mismo procesamiento (IA + búsqueda + persistencia de la conversación) — la diferencia es que la respuesta se entrega como una secuencia de eventos Server-Sent Events (SSE) a medida que el modelo la va generando, en vez de un único JSON al final.
Este endpoint consume tokens de IA de la cuenta del cliente, igual que /chat.
Este endpoint está sujeto a un flag de habilitación del lado del servidor (chatai.streaming). Si está deshabilitado, el endpoint responde con un JSON de error (STREAMING_DISABLED) en vez de abrir el stream — tu integración debe poder hacer fallback a POST /chat ante ese caso.
| Información del recurso | |
|---|---|
| Autenticación | Requerida (Token de API, Bearer) |
| Scope | mapaprop-chat-ai |
| HTTP Method | POST |
| Response | text/event-stream (SSE). Si el streaming está deshabilitado o falla la validación de entrada, application/json |
| Version | 1 |
URL del recurso
https://mapaprop.app/api/action/mapaprop-chat-ai-v1/chat/stream
Parámetros
Idénticos a los de POST /chat: message (requerido), questionId, leadName, leadEmail, leadPhone, sessionId, mode, propertyIds, useVectorSearch, searchCriteria, propertyActive, searchContext, customerSearch, sourceUrl. Ver esa página para el detalle completo de cada uno.
Código de ejemplo
POST /api/action/mapaprop-chat-ai-v1/chat/stream HTTP/1.1
Host: mapaprop.app
Content-Type: application/json
Authorization: Bearer {access_token}
Accept: text/event-stream
{
"message": "¿Tenés departamentos de 2 ambientes en Palermo?",
"questionId": 481203
}
Respuesta
La respuesta es un stream de eventos SSE. Cada evento es una línea data: {json}\n\n. El campo type de cada evento indica cómo interpretarlo:
| type | Cuándo aparece | Campos del payload |
|---|---|---|
text-delta | Turno de chat libre (sin contexto de búsqueda activo). Uno o varios por turno, a medida que el modelo genera texto. | text (string): el fragmento de texto a concatenar. |
bridge | Turno de chat libre: el modelo decidió ofrecer buscar propiedades o derivar a contacto humano, en vez de seguir charlando. | bridgeType (string): switch_to_property_search u offer_human_contact. message (string): texto sugerido para mostrar. |
search-result | Turno de búsqueda/propiedad/sin-resultados (cuando enviaste propertyIds, useVectorSearch o propertyActive). Se emite una sola vez, justo antes del evento done. | payload (object): la respuesta completa, con la MISMA forma que el JSON de POST /chat (response, action, success, propertyIds, buttons, allPropertyIds, hasMoreResults, focusedPropertyId, focusedPropertyCode, searchCriteria, tokensUsed, error). Este payload es la versión autoritativa: si mostraste texto de a poco con los text-delta, reemplazalo por payload.response al recibir este evento. |
done | Siempre el último evento del stream. | questionId (int): el ID de la conversación (puede ser -1 si falló el guardado). turnId (long): el ID de este turno, para dar feedback sobre la respuesta (puede faltar si el turno no se registró). inputTokens (int), outputTokens (int). |
error | Error a nivel del stream. No reintentar automáticamente. | errorCode (string), message (string). |
El evento done trae el questionId y el turnId de este turno — igual que la respuesta de POST /chat. En streaming es la forma de obtenerlos al cerrar el stream (guardá el turnId para poder dar feedback sobre esa respuesta).
Un turno de chat libre es: cero o más text-delta, opcionalmente un bridge, y siempre termina en done. Un turno de búsqueda/propiedad/sin-resultados es: un único search-result seguido de done (no emite text-delta ni bridge).
Gate de validación previo al stream
Si falta el campo message, o si el streaming está deshabilitado del lado del servidor, el endpoint responde con un JSON normal (no SSE) antes de abrir el stream — tu cliente HTTP puede tratarlo como una respuesta de error común.
| Error | Causa |
|---|---|
STREAMING_DISABLED | El modo streaming no está habilitado en este entorno. Hacé fallback a POST /chat. |
REQUIRED_INPUT — "message is required" | Falta el campo message en el body. |
Ejemplo de respuesta
Turno de chat libre:
data: {"type":"text-delta","text":"Hola! "}
data: {"type":"text-delta","text":"En qué puedo ayudarte hoy?"}
data: {"type":"done","questionId":481203,"turnId":481512,"inputTokens":410,"outputTokens":38}
Turno de búsqueda:
data: {"type":"search-result","payload":{"response":"Encontré 3 departamentos de 2 ambientes en Palermo.","action":"show_properties","success":true,"propertyIds":[2601234,2601987,2602111],"hasMoreResults":false,"tokensUsed":{"input":812,"output":143,"total":955}}}
data: {"type":"done","questionId":481203,"turnId":481512,"inputTokens":812,"outputTokens":143}
Respuesta cuando el streaming está deshabilitado (JSON, no SSE):
{
"error": "STREAMING_DISABLED",
"message": "El modo streaming no está habilitado en este entorno."
}