BETA

Este es el webservice principal del modo Full Stack. Recibe el mensaje del visitante, orquesta internamente la IA, la búsqueda semántica sobre el inventario del cliente y arma la respuesta lista para mostrar. Guarda el mensaje del visitante y la respuesta de la IA en la conversación (no hace falta llamar a otro endpoint para persistirlos).

Este endpoint consume tokens de IA de la cuenta del cliente (customer_ai_config). Antes de invocarlo podés chequear el saldo disponible con GET /api/action/mapaprop-chat-ai-v1/validate.

Información del recurso
AutenticaciónRequerida (Token de API, Bearer)
Scopemapaprop-chat-ai
HTTP MethodPOST
ResponseJSON
Version1

URL del recurso

https://mapaprop.app/api/action/mapaprop-chat-ai-v1/chat

Parámetros

El cuerpo de la petición es un JSON. customerId y websiteId no se envían: se derivan del token de autenticación.

KeyTypeRequiredDescripción
messagestringEl mensaje del visitante.
questionIdintnoEl ID de la conversación a continuar. Si se omite, se crea una conversación nueva y el questionId asignado viene en la respuesta (campo questionId). Reenvialo en cada turno siguiente. También podés obtenerlo de una llamada previa a POST /init.
leadNamestringnoNombre del visitante. Default Visitante. Si la conversación ya tiene un contacto asociado y no se envía, se conserva el existente.
leadEmailstringnoEmail del visitante. Si se envía y la conversación todavía no tiene contacto asociado, se crea o vincula un contacto en el CRM del cliente.
leadPhonestringnoTeléfono del visitante.
sessionIdstringnoIdentificador de sesión del visitante (para trazabilidad). Si no se envía, se genera un UUID automáticamente.
modestringnochat (default), search o semantic. Ver "Modo de búsqueda" más abajo.
propertyIdsarray de objetos {id: int}noIDs de propiedades pre-filtradas (por ejemplo, obtenidas de una búsqueda previa por tu cuenta). El modelo decide si el mensaje es una consulta factual ("¿cuál es más cara?") o semántica ("¿cuál tiene pileta?") sobre este conjunto.
useVectorSearchbooleannoFuerza una búsqueda semántica (vectorial) sobre las propiedades del cliente para armar el contexto de la respuesta. Se activa automáticamente si se envía propertyIds o mode=semantic.
searchCriteriaobjectnoFiltro de búsqueda clásico (operation, type, zone, priceMin, priceMax, currency) usado solo cuando mode=search y no se envió propertyIds. Modo legacy: se recomienda propertyIds o useVectorSearch.
propertyActiveobject {propertyId: int, ...}noIndica que la conversación es sobre UNA propiedad puntual (el visitante está viendo su ficha). Tiene prioridad sobre cualquier otro modo de búsqueda.
searchContextobjectnoContexto del flujo guiado (operación / tipo / zona ya elegidos por el visitante mediante botones). Uso avanzado, reservado para reproducir el flujo del widget oficial.
customerSearchobjectnoDatos de búsquedas/favoritos/consultas previas del visitante, usados para enriquecer el contacto creado en el CRM. Uso avanzado.
sourceUrlstringnoURL de la página donde el visitante está conversando. Se guarda en la conversación.

Modo de búsqueda

  • Si enviás propertyIds, la IA responde en base a ese conjunto (con re-ranking semántico si además mandás useVectorSearch=true).
  • Si enviás useVectorSearch=true (o mode=semantic) sin propertyIds, se busca semánticamente sobre todo el inventario del cliente.
  • Si enviás propertyActive, la respuesta se enfoca en esa única propiedad (tiene prioridad sobre todo lo demás).
  • Sin ninguno de los anteriores, es una conversación libre (chat sin contexto de búsqueda).

Código de ejemplo

POST /api/action/mapaprop-chat-ai-v1/chat HTTP/1.1
Host: mapaprop.app
Content-Type: application/json
Authorization: Bearer {access_token}

{
    "message": "¿Tenés departamentos de 2 ambientes en Palermo?",
    "questionId": 481203,
    "leadName": "Juan Pérez",
    "leadEmail": "juan@example.com",
    "sessionId": "b6d1c6b0-2f2a-4e2e-9a4a-8e0a2a2f2a11",
    "useVectorSearch": true
}

Respuesta

La respuesta incluye el questionId de la conversación (el asignado si era nueva, o el que enviaste) — guardalo y reenvialo en cada turno siguiente para mantener el hilo — y el turnId de esta respuesta puntual, que usás para dar feedback sobre ella. También devuelve el consumo de tokens del período (totalTokensUsed / tokensRemaining).

ObjetoCampoTipoRequeridoDescripción
ResponseresponsestringEl texto de la respuesta de la IA, listo para mostrar.
questionIdintID de la conversación (el asignado si era nueva, o el que enviaste). Reenvialo en el siguiente turno.
turnIdlongnoID de este turno. Usalo para dar feedback sobre esta respuesta con POST /feedback o POST /signal. Puede faltar si el turno no se registró.
actionstringnoAcción sugerida por el modelo. Valores posibles: greeting, show_properties, confirm_search, request_info, contact. Puede venir vacío.
successbooleanfalse cuando el turno no pudo procesarse (ver "Errores controlados" más abajo).
propertyIdsarray de intnoIDs de las propiedades referenciadas en esta respuesta (solo presente en modo búsqueda).
buttonsarray de objetosnoBotones sugeridos para el visitante (solo presente en algunos flujos).
allPropertyIdsarray de intnoTodos los IDs del resultado de búsqueda (antes de recortar a los mostrados). Solo modo búsqueda.
hasMoreResultsbooleantrue si hay más resultados de búsqueda de los mostrados en propertyIds.
focusedPropertyIdintnoID de la propiedad en foco (modo propiedad única).
focusedPropertyCodestringnoCódigo de la propiedad en foco.
searchCriteriaobjectnoCriterio de búsqueda interpretado por el modelo (modo búsqueda).
tokensUsedobjectDetalle de tokens consumidos en este turno: {input, output, total}.
totalTokensUsedintnoTokens de IA consumidos por la cuenta en el período actual (tras este turno).
tokensRemainingintnoTokens de IA restantes en el período actual.
errorstringnoPresente solo cuando success == false. Ver tabla de abajo.

Errores controlados (success: false, HTTP 200)

Estos escenarios no lanzan una excepción: la respuesta llega con success: false, un response en español listo para mostrarle al visitante, y un error con el motivo.

ErrorCausa
TOKEN_LIMIT_EXCEEDEDEl cliente alcanzó el límite mensual de tokens de IA de su plan.
INSUFFICIENT_TOKENSNo quedan tokens suficientes en el período actual para procesar este mensaje puntual.
CONVERSATION_LIMIT_EXCEEDEDEsta conversación (questionId) ya consumió el máximo de tokens permitido por conversación. Hay que iniciar una conversación nueva.
USER_MESSAGE_TOO_LONGEl mensaje enviado supera el largo máximo permitido (~300 tokens, ~225 palabras).
(mensaje en español, no un código corto)Falla interna del motor de IA (proveedor caído, error de parseo, etc.). El campo error en este caso contiene el mismo texto que response, no un código corto.

Errores de validación (se corta la request, no llega success: false)

ErrorCausa
REQUIRED_INPUT — "Message is required"Falta el campo message en el body.

Ejemplo de respuesta

{
    "response": "Sí, tenemos 3 departamentos de 2 ambientes en Palermo. Te comparto los más relevantes.",
    "questionId": 481203,
    "turnId": 481512,
    "action": "show_properties",
    "success": true,
    "propertyIds": [2601234, 2601987, 2602111],
    "hasMoreResults": false,
    "tokensUsed": {
        "input": 812,
        "output": 143,
        "total": 955
    },
    "totalTokensUsed": 18420,
    "tokensRemaining": 81580
}

Ejemplo de error controlado (límite de tokens del período):

{
    "response": "Lo siento, se ha alcanzado el limite de uso mensual del chat. El limite se reiniciara el 2026-09-01.",
    "action": "",
    "success": false,
    "hasMoreResults": false,
    "tokensUsed": {
        "input": 0,
        "output": 0,
        "total": 0
    },
    "error": "TOKEN_LIMIT_EXCEEDED"
}