POST
/api/mod/ventas/{espacio}/conversations/Conversa con un cliente
Mandas lo que escribió tu cliente y recibes la respuesta del agente de ventas: resuelve dudas con tus documentos, cotiza el envío, arma el pedido y lo cierra. Reusa el session_id en cada mensaje del mismo chat.
- PERMISOlee (vale cualquier clave)
- CRÉDITOSgasta créditos
- AUTENTICACIÓNBearer bth_…
En un espacio con Ventas, POST conversations del núcleo también llega a este agente, con question, session_id y consent; msg_id solo existe aquí.
PARÁMETROS
| CAMPO | TIPO | REQUERIDO | QUÉ ES |
|---|---|---|---|
| espacio | string | SÍ | El id del espacio (sale en GET /api/companies). Tiene que tener el módulo Ventas. |
CUERPO · JSON
| CAMPO | TIPO | REQUERIDO | QUÉ ES |
|---|---|---|---|
| question | string | SÍ | Lo que escribió tu cliente, tal cual. De 1 a 4000 caracteres: fuera de ese rango no da error, responde 1001 con tu refusal_fuera_dominio. |
| session_id | string | SÍ, EN LA PRÁCTICA | Tu identificador de la conversación: uno por chat (el número del cliente en tu canal, el id del hilo…). Sin él responde 400. Con él, Ventas recuerda el carrito, la ciudad, el método de pago y el pedido abierto. |
| consent | boolean | no | true si tu cliente autorizó el seguimiento comercial. Solo así se guarda su contacto, y seudonimizado. Por defecto false. |
| msg_id | string | no | El id del mensaje en tu canal. Si llega dos veces con el mismo session_id (un reintento de tu webhook, un doble toque), la segunda devuelve la misma respuesta sin volver a ejecutar el turno: no agrega dos veces al carrito ni crea dos pedidos. |
RESPUESTA 200
| CAMPO | TIPO | QUÉ ES |
|---|---|---|
| response | string | El mensaje para tu cliente, entero. Úsalo si tu canal manda un solo mensaje. |
| responses | string[] | El mismo texto en uno o dos mensajes (por ejemplo, lo que cambió en el carrito y luego la respuesta). Si tu canal admite varios mensajes seguidos, mándalos en orden. |
| status_code | "1000" | "1001" | "1000" respondió. "1001" no tenía información para eso o el mensaje no se pudo atender; response trae tu refusal_fuera_dominio. |
| estado | string | En qué punto va la conversación: ver estados. |
| cotizacion | object | null | Las cifras de la cotización de este turno, como texto decimal: total, coste_envio, recargos[] y, según el caso, lineas[], subtotal, descuento o tiempo_entrega_dias. null si el turno no cotizó. |
| handoff | boolean | true: no puede seguir solo (no hay tarifa, pidieron una persona, falló un pago…). Pásale la conversación a alguien de tu equipo. |
| aviso_privacidad | string | null | Solo en el primer turno: tu aviso de privacidad. Enséñaselo a tu cliente. |
| opciones | [{ id, nombre }] | Cuando duda entre 2 o 3 productos parecidos y activaste los botones: las opciones, para mostrarlas como botones. El texto de response ya las nombra. |
| lead_id | string | null | El id del lead si este turno lo registró. Guárdalo con tu conversación. |
| sources | string[] | Los documentos del espacio en los que se apoyó. Para ti, no para tu cliente. |
| session_id · tenant_id | string | La sesión que mandaste y el espacio. |
ESTADOS DE LA CONVERSACIÓN
| CAMPO | TIPO | QUÉ ES |
|---|---|---|
| saludo | inicio | Primer contacto: aún no hay nada que atender. |
| descubrimiento | conversando | Charla o preguntas generales, sin intención de compra clara. |
| rag_producto | conversando | Respondió sobre un producto con lo que dicen tus documentos. |
| recoleccion_slots | conversando | Le faltan datos para seguir (producto, cantidad, ciudad, método de pago, datos de envío) y los está pidiendo. |
| cotizacion | venta | Acaba de cotizar: la cifra está en cotizacion. |
| cierre | venta | Cerrando la compra: confirma el pedido, pide el pago o sigue un pedido abierto. |
| handoff | persona | Conviene que siga una persona: mira handoff. |
ERRORES DE ESTA RUTA · SIEMPRE {"detail": …}
| STATUS | CUÁNDO | DETAIL LITERAL |
|---|---|---|
| 400 | Falta session_id | session_id es obligatorio. |
| 403 | El espacio no tiene el módulo Ventas | módulo no habilitado para este espacio. |
| 402 | La cuenta agotó sus créditos del ciclo | La cuenta de este espacio agotó sus créditos de este ciclo. |
| 422 | Falta un campo obligatorio o uno no es de su tipo (detail es una lista) | — |
| 429 | El espacio mandó demasiadas peticiones seguidas: espera unos segundos | Demasiadas solicitudes; intenta en un momento. |
| 502 | Ventas no respondió a tiempo o no está disponible: reintenta con espera creciente | — |
Y los de cualquier ruta —clave inválida, cuenta no al día, IP, límites—, en Errores, límites y créditos.
CONVIENE SABER
- Ninguna cifra la inventa: precios, envíos y totales salen de tu catálogo, tus tarifas o tus reglas. Si no puede cotizar, lo dice y marca
handoff. - Vale con cualquier clave, también una
lee: conversar no cambia nada de tu espacio, aunque el agente sí crea pedidos y leads cuando el cliente compra. - Un turno puede tardar varios segundos, más si cotiza o cierra un pedido. Pon el timeout de tu cliente en 90 s o más; si Ventas no termina a tiempo, responde 502.
- La sesión recuerda el carrito, la ciudad y el pedido abierto. Tras unas 48 h sin mensajes empieza de cero; para hacerlo antes, reiníciala.
- Copia la ruta tal cual, con su barra final. Sin ella la respuesta es un 307 sin destino, no la conversación.