Contrato de handoff.
El Contrato de handoff v1 es la interfaz que tu CRM implementa para recibir leads de Jataí: tres rutas HTTP autenticadas por token (health, recibir lead y consultar estado) y una ruta de retorno, del lado de Jataí, para el desenlace. El lead llega con la organización, la persona, los números, el motivo y el historial de la conversación. Nunca trae etapa de pipeline.
Lo que la Entrega (handoff) envía a tu CRM, campo por campo. Versionado: el v1 sigue funcionando cuando salga el v2.
Visión general.
Jataí no escribe un adaptador para cada CRM. Publica un contrato, y cada plataforma lo implementa en su propio repositorio, corriendo la suite de conformidad hasta que quede en verde. Quien conecta una marca no necesita a nadie de Jataí en el medio — y Jataí no necesita conocer el CRM.
Para un sistema legado que no va a implementar ninguna ruta, existe el adaptador genérico: mapea los campos por configuración, sin código nuevo, y se niega a escribir cualquier campo que delate una etapa de pipeline.
Las rutas.
| Ruta | Quién la implementa | Para qué |
|---|---|---|
POST {base}/health | tu CRM | declara las versiones del contrato que habla ({ "versoes": ["v1"], "ok": true }). Sin esto, Jataí tendría que adivinar el formato. |
POST {base}/leads | tu CRM | recibe el lead entregado. Idempotente por externalId: la misma clave dos veces produce un solo lead, y la reentrega responde duplicado: true, no error. |
GET {base}/leads/{externalId} | tu CRM | conciliación, no sincronización: dice si conoce el lead y en qué resultado está. Una clave desconocida responde 200 con `conhecido: false`, nunca 404. |
POST /handoff/retorno | Jataí | el único camino por el cual el desenlace entra a Jataí. Tu CRM llama a esta ruta, autenticada con la clave de API de la marca. |
Todas exigen token. La ruta que recibe datos de personas reales de una marca, sin token, sería pública — y la suite rechaza la plataforma que acepta una entrega sin autenticación.
El lead: `POST {base}/leads`.
| Campo | Qué es |
|---|---|
versao | siempre "v1" |
externalId | la clave de idempotencia (hasta 120 caracteres) |
entregueEm | el instante de la entrega, en ISO 8601 |
gatilho | por qué el lead se entrega ahora: resposta_positiva, selecao_em_lote, envio_individual o temperatura |
organizacao | nome, site, tipo, pais, cidade e identificadores (un mapa: CNPJ, dominio…) |
pessoa | nome, cargo y contatos[]: cada uno con tipo (email o whatsapp), valor, confianca (0 a 1) y verificadoEm |
fit | un entero de 0 a 100: cuánto encaja la organización con el perfil de la marca |
jataiTemperatura | un entero de 0 a 100: la señal de prioridad, para el vendedor. Va al campo jatai_temperatura |
valorEstimado | número o null |
porQue | la frase que el operador leyó en la fila: por qué este lead llegó aquí |
angulo | el ángulo usado en el contacto, o null |
historico[] | hasta 50 mensajes: de (nos o eles), canal, assunto, corpo y em |
atributos | un objeto libre para lo que la marca quiera llevar junto |
{
"versao": "v1",
"externalId": "lead-8f3a2c",
"entregueEm": "2026-09-18T09:20:00-03:00",
"gatilho": "resposta_positiva",
"organizacao": {
"nome": "Instituto Horizonte de Formação",
"site": "https://exemplo.org.br",
"tipo": "instituto",
"pais": "BR",
"cidade": "Goiânia",
"identificadores": { "cnpj": "••.•••.•••/••••-••" }
},
"pessoa": {
"nome": "Helena Prado",
"cargo": "Coordinación pedagógica",
"contatos": [
{ "tipo": "email", "valor": "helena@exemplo.org.br", "confianca": 0.9, "verificadoEm": null }
]
},
"fit": 84,
"jataiTemperatura": 82,
"valorEstimado": null,
"porQue": "Respondió pidiendo precios; el comité se reúne el día 22.",
"angulo": "Grupo nuevo en febrero: decisión de material didáctico hasta noviembre.",
"historico": [
{ "de": "nos", "canal": "email", "assunto": "Grupo de febrero", "corpo": "…", "em": "2026-09-15T09:00:00-03:00" },
{ "de": "eles", "canal": "email", "assunto": "Re: Grupo de febrero", "corpo": "…", "em": "2026-09-18T09:12:00-03:00" }
],
"atributos": {}
}El campo que nunca existirá.
Etapa de pipeline. Jataí escribe actividad y jatai_temperatura, nunca etapa. Dos autores en el mismo campo destruyen la confianza del equipo en el CRM, y eso no se recupera. Por eso el contrato no tiene el campo — no es un null permanente, es la ausencia —, y la suite rechaza la plataforma que exige etapa para aceptar un lead.
El retorno: `POST /handoff/retorno`.
Jataí no consulta tu CRM. Quien avisa es él, cuando algo le pasa a un lead entregado.
| Campo | Qué es |
|---|---|
versao | siempre "v1" |
externalId | la clave del lead entregado |
resultado | virou_cliente, perdido, duplicado o atividade_humana |
em | cuándo pasó, en ISO 8601 |
detalhe | texto libre opcional (hasta 1,000 caracteres) |
`atividade_humana` es el retorno más importante. Después de la entrega, Jataí sigue siendo dueño del canal automatizado y tu vendedor es dueño de la conversación directa: un mensaje automático encima de una conversación humana quema el lead y la marca. Este retorno pausa toda Rota (secuencia) automática de ese lead, y solo se reanuda si el lead se marca como perdido o se enfría.
Una clave desconocida responde 200 con conhecido: false: puede ser la reentrega de un retorno antiguo, y un 4xx haría que la plataforma reintentara para siempre.
La suite de conformidad.
La suite corre contra tu implementación real, con datos de prueba — escribe en la plataforma, con externalId prefijado por conformance- para que puedas encontrarlo y borrarlo después. Sale con código 1 cuando algo falla, para poder ser un paso de CI. Son ocho verificaciones:
- health declara la versión — sin esto, Jataí tendría que adivinar el formato.
- acepta un lead válido — es la ruta que recibe el trabajo de toda la máquina.
- la misma clave dos veces produce un solo lead — Jataí reenvía cada vez que no recibe el ACK, y va a reenviar.
- sabe informar el estado de un lead conocido — así es como Jataí concilia cuando sospecha que perdió un retorno.
- una clave desconocida devuelve 200 con `conhecido: false` — un 404 es indistinguible de una ruta caída.
- rechaza un payload inválido con 4xx, y no lo acepta en silencio — un lead aceptado y perdido es peor que un lead rechazado.
- rechaza a quien no tiene el token.
- no exige etapa de pipeline.
jatai-conformance --url https://sua-plataforma/jatai --token SEU_TOKEN
# el token también puede venir de JATAI_TOKENLa suite es el paquete @jatai/conformance, entregado a quien va a conectar una plataforma. Pídela en tu invitación.
Versionado.
El campo versao dice qué contrato sigue el lead, y el health dice cuáles habla tu CRM. Romper un contrato es lo más caro que existe cuando muchos consumidores dependen de él — por eso el v1 sigue funcionando cuando salga el v2.
Preguntas frecuentes
¿Qué pasa si mi CRM no responde al lead?
Jataí reenvía — por eso la ruta es idempotente. El mismo externalId dos veces produce un solo lead, y la reentrega responde duplicado: true, no error.
¿Jataí cambia la etapa del lead en mi CRM?
Nunca. El contrato no tiene el campo. Jataí escribe actividad y temperatura; la etapa es de tu vendedor.
¿Cómo sabe Jataí que el lead se volvió cliente?
Tu CRM avisa, llamando a POST /handoff/retorno con resultado: "virou_cliente". Jataí no consulta el CRM.
¿Y si mi sistema no puede implementar las rutas?
Para un sistema legado, el adaptador genérico mapea los campos por configuración — sin código nuevo — y se niega a escribir cualquier campo que delate una etapa de pipeline.