Tasvalúo SAI

Seguir el avance

Cómo saber cuándo termina la lectura y la evaluación de un avalúo.

Crear un avalúo no devuelve el resultado: la lectura del PDF y la evaluación tardan unos minutos. Hay tres formas de enterarte de cuándo terminan.

CasoUsa
Pantalla de detalle abierta, o un proceso que espera el resultadoStream en tiempo real (SSE)
Integración sencilla, sin conexiones abiertasConsulta periódica del avalúo
Lista con muchos avalúosEstados en lote

Cuándo ha terminado

Sea cual sea la vía, el avalúo terminó su recorrido automático cuando se cumple una de estas condiciones:

SituaciónCondición
El PDF no sirviódocument.estado es completed y document.errores no está vacío
La evaluación terminólatest_evaluation.estado es completed
Algo fallóstatus es error, o document.estado / latest_evaluation.estado es error
function termino(avaluo) {
  const doc = avaluo.document;
  const ev = avaluo.latest_evaluation;
  if (avaluo.status === 'error' || doc?.estado === 'error' || ev?.estado === 'error') return true;
  if (doc?.estado === 'completed' && doc.errores.length > 0) return true;
  return ev?.estado === 'completed';
}

Stream en tiempo real (SSE)

GET/v1/avaluos/{folio}/streamavaluos:read

Flujo SSE del estado del avalúo (tiempo real)

Abre una conexión que recibe el avalúo completo —el mismo objeto que GET /v1/avaluos/{folio}— cada vez que cambia.

curl -N "$API_URL/v1/avaluos/AVL-2026-000123/stream" \
  -H "x-api-key: $API_KEY" \
  -H "Accept: text/event-stream"
Lo que llega
data: {"folio":"AVL-2026-000123","status":"processing","document":{"estado":"processing",…},…}

data: {"folio":"AVL-2026-000123","status":"processing","document":{"estado":"completed",…},"latest_evaluation":{…}}

event: ping
data: keepalive

data: {"folio":"AVL-2026-000123","status":"requires_correction",…}
MensajeQué es
data: {…}El avalúo completo. Llega al conectar, en cada cambio y en una revisión cada 30 s. Nunca se repite un mensaje idéntico al anterior.
event: pingMantiene viva la conexión cada 20 s. Ignóralo.

Consúmelo desde tu servidor

La llave va en la cabecera x-api-key, y el EventSource nativo del navegador no puede enviar cabeceras. Abre el stream desde tu backend y reenvíalo a tu interfaz, sin exponer la llave.

Si el folio no existe, la respuesta es 404 en JSON y el stream no llega a abrirse: comprueba res.ok antes de leer eventos.

Ejemplo en Node.js

const res = await fetch(`${API_URL}/v1/avaluos/${folio}/stream`, {
  headers: { 'x-api-key': API_KEY, Accept: 'text/event-stream' },
});
if (!res.ok) throw new Error(`No se pudo abrir el stream: ${res.status}`);

const decoder = new TextDecoder();
let buffer = '';

for await (const chunk of res.body) {
  buffer += decoder.decode(chunk, { stream: true });
  const mensajes = buffer.split('\n\n');
  buffer = mensajes.pop(); // el último puede estar incompleto

  for (const mensaje of mensajes) {
    if (mensaje.startsWith('event: ping')) continue;
    const data = mensaje.split('\n').find((l) => l.startsWith('data: '));
    if (!data) continue;

    const avaluo = JSON.parse(data.slice(6));
    console.log(avaluo.status, avaluo.document?.estado, avaluo.latest_evaluation?.estado);
    if (termino(avaluo)) process.exit(0);
  }
}

Si la conexión se corta, vuelve a abrirla: el primer mensaje trae el estado actual, así que no pierdes nada.

Consulta periódica

GET/v1/avaluos/{folio}avaluos:read

Estado completo del avalúo

curl "$API_URL/v1/avaluos/AVL-2026-000123" -H "x-api-key: $API_KEY"

Devuelve el mismo objeto que el stream. Consulta cada 10–15 segundos y para cuando termino() sea verdadero. Un intervalo más corto no acelera el proceso y consume tu cuota de peticiones.

async function esperar(folio) {
  for (;;) {
    const res = await fetch(`${API_URL}/v1/avaluos/${folio}`, { headers: { 'x-api-key': API_KEY } });
    if (res.status === 404) throw new Error(`El folio ${folio} no existe`);
    const avaluo = await res.json();
    if (termino(avaluo)) return avaluo;
    await new Promise((r) => setTimeout(r, 12_000));
  }
}

Estados en lote

POST/v1/avaluos/estadosavaluos:read

Estados ligeros de varios folios

Para una lista, pide el estado de varios folios en una sola llamada en vez de uno por uno.

curl -X POST "$API_URL/v1/avaluos/estados" \
  -H "x-api-key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"folios":["AVL-2026-000123","AVL-2026-000124"]}'
200 OK
{
  "estados": [
    {
      "folio": "AVL-2026-000123",
      "status": "approved",
      "document": {
        "version": 2,
        "estado": "completed",
        "created_at": "2026-03-10T14:00:00.000Z",
        "procesado_at": "2026-03-10T14:01:12.000Z"
      },
      "latest_evaluation": {
        "id": "e1a2b3c4-0000-4000-8000-000000000001",
        "estado": "completed",
        "result": "aprobado",
        "created_at": "2026-03-10T14:02:00.000Z",
        "started_at": "2026-03-10T14:02:01.000Z",
        "completed_at": "2026-03-10T14:05:40.000Z"
      }
    }
  ]
}
  • Los folios que no existen no aparecen en la respuesta; no hay error.
  • El orden de estados no está garantizado: búscalos por folio.
  • folios no puede ir vacío (400).

Diagnóstico: los jobs

Cuando algo parece detenido, puedes ver el trabajo interno de cada fase.

GET/v1/avaluos/{folio}/jobsavaluos:read

Progreso de los jobs de etapa

El progreso de cada etapa de la última evaluación:

200 OK
{
  "folio": "AVL-2026-000123",
  "evaluacion_id": "e1a2b3c4-0000-4000-8000-000000000001",
  "estado": "en_progreso",
  "resultado": null,
  "etapas": [
    {
      "tipo": "documental",
      "orden": 1,
      "estado": "completed",
      "job": { "job_id": "…", "status": "completed", "progress": 100, "error": null, "started_at": "…", "completed_at": "…" }
    }
  ]
}

Valores en español en este endpoint

A diferencia del resto del contrato, el estado de la evaluación usa valores en español (pendiente, en_progreso, completada, fallida, cancelada) y resultado usa rechazado en lugar de no_aprobado. etapas[].estado sí usa los valores habituales. Para la lógica de tu integración usa GET /v1/avaluos/{folio}.

Si el avalúo aún no tiene evaluación, responde evaluacion_id, estado y resultado en null y etapas vacío.

GET/v1/avaluos/{folio}/jobavaluos:read

Job de procesamiento más reciente

El trabajo más reciente del avalúo, con status (received, dispatched, running, completed, failed), progress, error y latency_ms. Puede ser null.

On this page