API Reference

Documentación.

Todo lo que necesitas para consumir la API: endpoints, formato del webhook y códigos de error.

Quickstart

  1. 1

    Crea tu cuenta en dashboard.multasmx.com/register

  2. 2

    Copia tu API key desde el dashboard principal.

  3. 3

    Llama a los endpoints con el header x-api-key.

  4. 4

    Prueba gratis con la placa PRUEBA-ADEUDOS antes de comprar créditos.

Base URL

https://api.multasmx.com

La especificación completa está en openapi.json (OpenAPI 3.1, con un operationId por endpoint y los webhooks), y el resumen para agentes en llms.txt. Esta página también se puede pedir en Markdown: docs.md, o con el header Accept: text/markdown.

Autenticación

Todas las rutas requieren el header x-api-key con tu API key del dashboard.

x-api-key: sk_live_22f5757d-26c9-4f63-...

Pruebas sin costo

Para integrar sin gastar créditos, usa una placa de prueba con tu API key de siempre. La consulta es gratis y devuelve datos ficticios con la misma forma que una consulta real: el 201 con su requestId, los webhooks firmados y GET /lookup/:requestId. Sirve con cualquier estado o servicio de GET /states.

plate · niv (REPUVE) Qué devuelve
PRUEBA-ADEUDOS
PRUEBA0000000002
Con hallazgos
Multas y adeudos por pagar. En REPUVE, un reporte de robo.
PRUEBA-LIMPIA
PRUEBA0000000001
Todo en orden
Sin multas, adeudos ni reportes de robo.
PRUEBA-NOREG
PRUEBA0000000003
No registrada
El servicio no tiene la placa en su padrón.
PRUEBA-FALLA
PRUEBA0000000004
Sin respuesta
El servicio no contestó. Así llega un resultado pendiente.
request.sh
$ curl -X POST https://api.multasmx.com/lookup \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{"plate":"PRUEBA-ADEUDOS","states":["cdmx","edomex"]}'
201 Created
{ "requestId": "9ce8ceb8-...", "status": "PROCESSING", "plate": "PRUEBA-ADEUDOS", "creditsCharged": 0, "creditsBreakdown": { "cdmx": 0, "edomex": 0 }, "states": [ … ], "skipped": [], "sandbox": true }
Cómo se comporta
  • sandbox: true en la respuesta de POST /lookup, en GET /lookup/:requestId y en la raíz de cada webhook. Las consultas reales no lo traen
  • creditsCharged: 0: no cambia tu saldo, y funciona aunque tu saldo esté en 0
  • Los webhooks state_completed y completed llegan a tus URLs con la misma firma X-Multas-Signature que los reales: sirven para probar tu endpoint
  • El resultado se puede consultar con GET /lookup/:requestId durante 7 días. No aparece en el historial del dashboard
  • Un estado que en ese momento no está dando servicio se salta en skipped[], igual que en una consulta real
  • Hasta 200 consultas de prueba por día por cuenta (429 sandbox_limit_exceeded). Cuentan para tu límite por minuto
  • Toda placa que empiece con PRUEBA es de prueba: si no está en la tabla, la respuesta es 400 unknown_test_plate, y combinar una de prueba con una real da 400 test_identifier_mismatch
Servicio PRUEBA-LIMPIA
Todo en orden
PRUEBA-ADEUDOS
Con hallazgos
PRUEBA-NOREG
No registrada
Multas Sin infracciones Multas o adeudos pendientes Sin infracciones. En sinaloa, extra.plateRegistryStatus; en cdmx, extra.circulationCardStatus "Placa no localizada"
Tenencia (EdoMex) Sin adeudos Con adeudo found: false
Tenencia (Chihuahua, Guanajuato, Aguascalientes) Placa no registrada Adeudo en debts[] Placa no registrada
Vigencia de placa VIGENTE VENCIDA found: false
Verificación (EdoMex) Verificó en el semestre found: false found: false
Verificación (Jalisco) Aprobada y vigente Aprobada, ya vencida found: false
REPUVE Sin reportes Con reporte de robo No inscrito

Con PRUEBA-FALLA, cada estado termina en QUEUED_RETRY con errorCode: "scrape_failed" y la consulta en PARTIAL. En pruebas no se reintenta.

Construye sobre los campos base. En varios estados de multas, cada infracción de prueba trae sólo folio, date, amount, unit y status. Una respuesta real puede traer además descripción, artículo o datos del vehículo cuando el portal del estado los publica: trátalos como opcionales (ver Resultado de multas).

Si reenvías placas que escriben tus usuarios, una que empiece con PRUEBA devuelve datos de prueba: revisa el campo sandbox antes de mostrarlos.

Créditos y costos

Cada consulta descuenta créditos según su tipo. Un POST /lookup puede combinar varios estados y servicios: el cargo es la suma de sus costos, y se aplica antes de ejecutar la consulta. Las consultas con placas de prueba no cuestan.

Consulta stateCode Créditos
Multa estatal edomex, cdmx, guadalajara, … 1
Tenencia tenencia-edomex, tenencia-chihuahua, tenencia-guanajuato, tenencia-aguascalientes 1
Vigencia de placa vigencia-edomex 1
Verificación vehicular verificacion-edomex, verificacion-jalisco 1
REPUVE (reporte de robo) repuve 3

El costo vigente siempre se puede consultar en vivo: GET /billing/pricing lo devuelve en creditCosts, y GET /states incluye el campo creditCost en cada estado.

Caducidad

Los créditos vencen 12 meses después de la compra. El consumo es FIFO por caducidad: se gastan primero los que están más próximos a vencer, de modo que ningún lote se pierda mientras haya uso.

GET /billing/balance
{ "credits": 147, "nextExpiry": { "credits": 47, "expiresAt": "2027-03-14T00:00:00.000Z" }, "expiryMonths": 12, "lots": [ … ] }

nextExpiry es el lote que vence antes, que es el próximo en consumirse. Es null si no tienes saldo. Cada respuesta de POST /lookup incluye también el saldo restante en balance.

Saldo insuficiente

Si el saldo no cubre el costo del request, se rechaza completo con 402 y no se ejecuta ninguna consulta. La respuesta dice cuántos créditos faltaban:

402 Payment Required
{ "error": "insufficient_credits", "message": "Esta consulta cuesta 4 créditos y tu saldo disponible es de 2. Te faltan 2.", "required": 4, "available": 2, "missing": 2, "breakdown": { "edomex": 1, "repuve": 3 } }

POST /lookup

Solicita la consulta de una placa en uno o más estados. La respuesta es inmediata con un requestId. El resultado completo llega vía webhook.

request.sh
$ curl -X POST https://api.multasmx.com/lookup \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{"plate":"ABC1234","states":["cdmx","edomex"]}'
201 Created
{ "requestId": "05f4c751-...", "status": "PROCESSING", "creditsCharged": 2, "states": [ { "stateCode": "cdmx", "status": "PENDING" }, { "stateCode": "edomex", "status": "PENDING" } ], "skipped": [] }
Body
  • plate — alfanumérico, 1–16 caracteres
  • states — array de stateCodes únicos, al menos uno, de los que lista GET /states
Cada estado se cobra según su costo en créditos: 1 crédito los estados de multas, la tenencia, la vigencia y la verificación; 3 créditos REPUVE. El total del request es la suma, y viene desglosado en creditsBreakdown. Estados en DOWN / MAINTENANCE aparecen en skipped[] y no se cobran.

GET /lookup/:requestId

Consulta el estado actual de un request. Útil para poll si no usas webhooks.

200 OK
{ "requestId": "05f4c751-...", "plate": "ABC1234", "status": "COMPLETED", "creditsCharged": 2, "webhookSent": true, "results": [ { "state": "edomex", "status": "SUCCESS", "hasInfractions": true, "totalDebt": "905", "consultedAt": "2026-04-22T16:30:12.000Z" } ] }

status puede ser PROCESSING, COMPLETED, PARTIAL o QUEUED_RETRY.

GET /states

Lista de los estados y servicios disponibles ahora: los que en este momento no están dando servicio no aparecen.

{ "states": [ { "stateCode": "campeche", "stateName": "Campeche", "type": "infracciones", "creditCost": 1 }, { "stateCode": "repuve", "stateName": "REPUVE", "type": "repuve", "creditCost": 3 }, { "stateCode": "tenencia-edomex", "stateName": "Tenencia — Estado de México", "type": "tenencia", "creditCost": 1 }, … ], "count": 22 }
Campos de cada estado
  • stateCode — el código que va en states[] de POST /lookup
  • stateName — nombre legible del estado o servicio
  • type — tipo de consulta: tenencia, vigencia, verificacion o repuve; en los estados de multas varía según el estado (p. ej. infracciones)
  • creditCost — créditos que cuesta consultarlo (ver Créditos y costos)
count es el número de entradas de states. La respuesta puede traer campos adicionales que no forman parte del contrato: no dependas de ellos, pueden cambiar o desaparecer sin aviso.

Resultado de multas

Cada estado de multas entrega en data.infractions[] una entrada por infracción, pendiente o pagada. Los campos opcionales sólo aparecen cuando el portal del estado publica ese dato.

results[0].data.infractions[0]
{ "folio": "PRUEBA/00000001/2026", "date": "2026-08-22T15:42:53Z", "amount": 905, "unit": "MXN", "status": "pending", "type": "Mexibús — Invasión al carril confinado", "article": "Art. 90 fracc. VII; Art. 90 fracc. VII y 118 fracc. IV", "description": "Por no sujetarse a los límites físicos señalados para los carriles… Por invadir el carril confinado…", "articles": [ { "article": "Art. 90 fracc. VII", "description": "Por no sujetarse a los límites físicos…" }, { "article": "Art. 90 fracc. VII y 118 fracc. IV", "description": "Por invadir el carril confinado…" } ], "regulation": "ESTATAL" }
Campos de cada infracción
  • folio · date (ISO 8601) · amount + unit — importe y su unidad ("MXN" por defecto; CDMX usa "UC")
  • status — "pending" o "paid". Las pagadas también se entregan: es el historial completo
  • description — el porqué de la infracción: texto del reglamento, tal como lo publica el portal
  • article — artículo y fracción. Si la infracción cita varios, vienen unidos con "; "
  • articles[] — los mismos artículos por separado, cada uno con su description (cuando hay más de uno)
  • type — clasificación del portal (programa y conducta) · regulation — ámbito del reglamento · paymentDate — fecha de pago, si está pagada
En edomex, description, article y articles[] se entregan para las tres infracciones más recientes de la placa; las anteriores llevan folio, fecha, importe y type. Un campo ausente significa que el dato no está disponible, nunca que esté vacío.

Datos extra de CDMX y Sinaloa

Las consultas de multas de cdmx y sinaloa entregan, además, datos del vehículo que publica el portal del estado. Van en data.extra, sin costo adicional, y cada clave aparece sólo cuando el portal publica ese dato.

cdmx · results[0].data.extra
{ "fotocivicaPoints": 10, "circulationCardStatus": "Vigente", "circulationCardValidUntil": "2027-03-31" }
sinaloa · results[0].data.extra
{ "plateRegistryStatus": "deregistered", "plateRegistryMessage": "Su vehículo presenta un estatus de baja." }
Ciudad de México · cdmx
  • fotocivicaPoints — puntos de fotocívicas de la placa, de 0 a 10
  • circulationCardStatus — estatus de la tarjeta de circulación: "Vigente", "Vencida" o "Placa no localizada" (el portal de CDMX no localizó la placa; es lo habitual con placas de otros estados)
  • circulationCardValidUntil — fecha ISO del fin de vigencia de la tarjeta de circulación (ya pasada si está "Vencida"). No viene con "Placa no localizada"
Sinaloa · sinaloa
  • plateRegistryStatus — "deregistered" si la placa está dada de baja; "not_registered" si no está en el padrón vehicular del estado. Son casos distintos: estar fuera del padrón no significa estar dado de baja
  • plateRegistryMessage — el aviso del portal, tal cual
En los dos casos el resultado de sinaloa es exitoso y sin adeudos: revisa plateRegistryStatus antes de leer "sin adeudos" como "al corriente".
data.extra puede traer otras claves. Sólo las documentadas aquí forman parte del contrato; las demás pueden cambiar o dejar de enviarse.

Vigencia de placa (Estado de México)

Además de multas, puedes verificar la vigencia de una placa de EdoMex usando el pseudo-estado vigencia-edomex en el mismo POST /lookup. Cuesta 1 crédito y es combinable con estados de multas en el mismo request.

request.sh
$ curl -X POST https://api.multasmx.com/lookup \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{"plate":"PRUEBA-LIMPIA","states":["vigencia-edomex"]}'
results[0].data
{ "source": "edomex-controlv", "plate": "PRUEBA-LIMPIA", "found": true, "plateStatus": "VIGENTE", "validityStart": "2025-10-14", "validityEnd": "2030-10-14", "previousPlate": null, "message": "¡Estimado contribuyente, ..." }
Campos del resultado
  • found — false si la placa no está registrada en el padrón (respuesta definitiva del portal, no un error)
  • plateStatus — VIGENTE · VENCIDA · INACTIVA · EN_PROCESO
  • validityStart / validityEnd — fechas ISO de inicio y fin de vigencia (la placa dura 5 años)
  • previousPlate — placa anterior si hubo reemplacamiento
En este servicio hasInfractions y totalDebt vienen en null: no es una consulta de multas.

Verificación vehicular (Estado de México)

Consulta si un vehículo ya cumplió con la verificación del semestre usando el pseudo-estado verificacion-edomex en el mismo POST /lookup. Cuesta 1 crédito y es combinable con estados de multas en el mismo request. Devuelve el holograma obtenido, la fecha, el folio del certificado y el verificentro.

request.sh
$ curl -X POST https://api.multasmx.com/lookup \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{"plate":"PRUEBA-LIMPIA","states":["verificacion-edomex"]}'
results[0].data
{ "source": "edomex-verificacion", "plate": "PRUEBA-LIMPIA", "found": true, "verifiedThisSemester": true, "verification": { "center": "CU-000 VERIFICENTRO DE PRUEBA S.A. DE C.V.", "date": "2026-08-07", "certificate": "Cero", "reason": "Normal", "folio": "PRUEBA0001", "vin": "PRUEBA0000000001" }, "message": "El vehículo tiene una verificación en el semestre." }
Campos del resultado
  • found — false si no hay verificaciones registradas para la placa (respuesta definitiva del portal, no un error). En ese caso verification viene en null
  • verifiedThisSemester — true si la verificación del semestre en curso ya está hecha
  • verification.certificate — holograma obtenido, tal como lo publica el portal ("Cero", "Doble Cero", …)
  • verification.date — fecha ISO de la verificación · folio — folio del certificado · center — verificentro · reason — motivo · vin — número de serie
En este servicio hasInfractions y totalDebt vienen en null: no es una consulta de multas. Suele tardar más que el resto de consultas de EdoMex: el resultado llega por webhook cuando termina.

Verificación vehicular (Jalisco)

Consulta la verificación vehicular registrada para una placa en Jalisco usando el pseudo-estado verificacion-jalisco en el mismo POST /lookup. Cuesta 1 crédito y es combinable con estados de multas en el mismo request. Devuelve el resultado, la fecha, hasta qué mes es válida y los datos básicos del vehículo.

request.sh
$ curl -X POST https://api.multasmx.com/lookup \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{"plate":"PRUEBA-LIMPIA","states":["verificacion-jalisco"]}'
results[0].data
{ "source": "jalisco-verificacion", "plate": "PRUEBA-LIMPIA", "consultedAt": "2026-09-28T17:05:12.000Z", "found": true, "current": true, "verification": { "result": "APROBADO", "date": "2026-03-12", "validUntil": "2027-02", "type": "Extemporánea", "center": "0000" }, "vehicle": { "brand": "NISSAN", "model": "VERSA", "year": 2019, "fuel": "GASOLINA" }, "message": null }
Campos del resultado
  • found — false si no hay verificación registrada para la placa (respuesta definitiva del portal, no un error). En ese caso current, verification y vehicle vienen en null y message dice "Sin verificación registrada"
  • current — true si la verificación está aprobada y su validUntil no ha pasado; false si no fue aprobada o ya venció. Para evaluarla con tu propia fecha de corte, usa verification.validUntil
  • verification.result — "APROBADO" o "NO APROBADO", tal como lo publica el portal
  • verification.date — fecha ISO de la verificación · validUntil — mes hasta el que es válida, "AAAA-MM" (el portal no publica el día) · type — tipo de verificación, tal como lo publica el portal · center — clave del verificentro. Cualquiera puede venir en null si el dato no está disponible
  • vehicle — marca, modelo, año y combustible
found:false no significa que el vehículo no haya verificado. La verificación no es obligatoria en todos los municipios de Jalisco, hay vehículos exentos, y un vehículo que cambió de placa puede tener su verificación registrada con la placa anterior.
A diferencia de verificacion-edomex, no incluye holograma, folio del certificado ni número de serie. En este servicio hasInfractions y totalDebt vienen en null: no es una consulta de multas.

Adeudo de tenencia (Estado de México)

Consulta si una placa de EdoMex tiene adeudos de tenencia usando el pseudo-estado tenencia-edomex en el mismo POST /lookup. Cuesta 1 crédito y es combinable con estados de multas en el mismo request. Además del adeudo, devuelve datos del vehículo (NIV, clave vehicular, factura) y la vigencia de la placa.

¿Placas de la Ciudad de México? No hay un tenencia-cdmx: la tenencia de CDMX viene incluida en la consulta de multas cdmx, en data.debts[] junto a las infracciones, sin costo adicional.
¿Chihuahua, Guanajuato o Aguascalientes? Tienen su propio pseudo-estado de tenencia, con otra forma de respuesta: ver Tenencia en Chihuahua, Guanajuato y Aguascalientes.
request.sh
$ curl -X POST https://api.multasmx.com/lookup \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{"plate":"PRUEBA-LIMPIA","states":["tenencia-edomex"]}'
results[0].data
{ "source": "edomex-tenencia", "plate": "PRUEBA-LIMPIA", "found": true, "hasDebt": false, "debtDescription": "SIN ADEUDOS", "totalDebt": 0, "vehicle": { "model": "2019", "description": "NISSAN VERSA 4PTAS SENSE 4Cil", "vin": "PRUEBA0000000001" }, "plateValidityStart": "2025-10-14", "plateValidityEnd": "2030-10-14" }
Campos del resultado
  • found — false si la placa no existe en el padrón vehicular o está dada de baja (respuesta definitiva del portal, no un error)
  • plateStatus — "registered", "not_registered" o "deregistered" (dada de baja); con found:false, message trae el aviso del portal
  • hasDebt — true si la placa tiene adeudos de tenencia pendientes
  • debtDescription — texto del portal tal cual (p.ej. "SIN ADEUDOS")
  • totalDebt — monto total del adeudo en MXN (dentro de data)
  • vehicle — modelo, descripción, NIV, clave vehicular, cilindros, fecha e importe de factura
  • plateValidityStart / plateValidityEnd — vigencia de la placa (fechas ISO)
En este servicio los campos hasInfractions y totalDebt del resultado (nivel superior) vienen en null: no es una consulta de multas.

Tenencia en Chihuahua, Guanajuato y Aguascalientes

Tres pseudo-estados consultan el adeudo vehicular estatal de cada entidad en el mismo POST /lookup. Cada uno cuesta 1 crédito y es combinable con estados de multas en el mismo request.

stateCode Qué consulta
tenencia-chihuahua Tenencia y revalidación vehicular del Gobierno del Estado.
tenencia-guanajuato Tenencia y refrendo vehicular del Gobierno del Estado.
tenencia-aguascalientes Derechos de control vehicular del Gobierno del Estado. Es estatal: las multas de aguascalientes son las del municipio.

A diferencia de tenencia-edomex, el resultado tiene la misma forma que una consulta de multas: si el portal publica un adeudo, llega en data.debts[] con sus totales, e infractions[] viene vacío. El nivel de detalle depende de lo que publique cada portal.

request.sh
$ curl -X POST https://api.multasmx.com/lookup \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{"plate":"PRUEBA-NOREG","states":["tenencia-chihuahua"]}'
results[0].data · placa no encontrada
{ "state": "Tenencia — Chihuahua", "plate": "PRUEBA-NOREG", "consultedAt": "2026-09-28T17:05:12.000Z", "hasInfractions": false, "infractions": [], "totalInfractionDebt": 0, "hasDebts": false, "debts": [], "totalDebtAmount": 0, "totalDebt": 0, "totalPendingDebt": 0, "extra": { "plateRegistryStatus": "not_registered", "plateRegistryMessage": "La placa o folio del Permiso Provisional no se encuentra registrado(a) en el Padron." } }
Campos del resultado
  • hasDebts / debts[] — el adeudo que publica el portal. Cada entrada trae concept, amount + unit, total y status ("pending" o "paid"), más year y surcharges cuando el portal los da
  • totalDebt / totalPendingDebt — suma de los adeudos y de los pendientes, dentro de data
  • extra.plateRegistryStatus — "not_registered": el portal no dio información de la placa;extra.plateRegistryMessage trae su aviso tal cual. En ese caso debts[] viene vacío, y no significa "sin adeudo"
  • extra.paymentStatus — sólo tenencia-aguascalientes: "al_corriente" si el portal indica que la placa está al corriente de pagos, con su aviso en extra.paymentMessage
  • extra.plateReplacementRequired — sólo tenencia-guanajuato: true si el portal indica que la placa debe canjearse
En estos servicios los campos hasInfractions y totalDebt del resultado (nivel superior) vienen en null: no son consultas de multas. El adeudo se lee dentro de data.

REPUVE — reporte de robo (nacional)

Consulta el Registro Público Vehicular con el pseudo-estado repuve en el mismo POST /lookup. Cuesta 3 créditos —es la consulta más costosa de servir— y es combinable con estados de multas en el mismo request. Devuelve si el vehículo tiene reporte de robo (FGJ, OCRA y Robo USA/CAN) más sus datos de registro.

Es el único servicio que acepta placa o NIV: manda el campo niv —con o sin plate— y podrás consultar vehículos que todavía no tienen placa. La cobertura es nacional, no estatal.

request.sh
$ curl -X POST https://api.multasmx.com/lookup \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{"plate":"PRUEBA-ADEUDOS","states":["repuve"]}' # o por número de serie (NIV), sin placa: $ curl -X POST https://api.multasmx.com/lookup \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{"niv":"PRUEBA0000000002","states":["repuve"]}'
results[0].data
{ "source": "repuve", "queriedBy": "plate", "registered": true, "hasTheftReport": true, "vehicle": { "marca": "NISSAN", "modelo": "VERSA", "anioModelo": 2019, "niv": "PRUEBA0000000002", "entidadEmplaco": "ESTADO DE MEXICO" }, "fgj": { "status": "con_reporte", "records": [{ "estatus": "ROBADO", "fechaRobo": "23/06/26" }] }, "ocra": { "status": "sin_reporte" }, "roboUsaCan": { "status": "sin_reporte" } }
Campos del resultado
  • registered — false si el vehículo no está inscrito en el registro (respuesta definitiva del portal, no un error)
  • hasTheftReport — atajo: true si alguna de las tres fuentes reporta robo, false si FGJ y OCRA respondieron sin reporte, y null si ninguna reporta robo pero FGJ u OCRA no respondieron (no se puede confirmar)
  • complete — false si alguna sección no respondió; missingSections dice cuáles y nextRetryAt cuándo se vuelven a consultar
  • vehicle — marca, modelo, año, clase, tipo, NIV, placa, entidad de emplacamiento, armadora y más
  • fgj — Fiscalía General de Justicia, con el detalle de cada reporte en records[] (estatus, entidad, fecha de robo y de recuperación)
  • ocra — Oficina Coordinadora de Riesgos Asegurados
  • roboUsaCan — robo reportado en Estados Unidos o Canadá
  • avisosMinisteriales — avisos por delitos distintos del robo
Cada sección trae un status: con_reporte, sin_reporte, requiere_niv (esa fuente necesita el NIV para responder), pendiente (esa fuente no respondió y la volvemos a consultar: el valor va a cambiar) o desconocido (no respondió en ninguno de los reintentos). Trata pendiente y desconocido como dato ausente, no como vehículo limpio; el message de la sección lo explica.
Si el resultado llega con secciones pendiente (complete: false), lo volvemos a consultar en las siguientes horas sin costo y la consulta queda como PARTIAL. Cuando se completa recibes otra vez el webhook completed, con el mismo requestId, el resultado actualizado y la consulta en COMPLETED. Si al final una sección no responde, pasa a desconocido, también te avisamos por webhook y, si las que faltan son FGJ u OCRA, se te devuelven los créditos de esa consulta.
REPUVE no reporta multas, así que hasInfractions y totalDebt del resultado (nivel superior) vienen en null.

Webhook

Cuando un request completa, la API hace un POST a cada URL de webhookUrls configurada en el dashboard (hasta 3 endpoints: producción, staging, un colector interno…). Todos reciben el mismo payload, firmado con HMAC-SHA256 usando tu webhookSecret.

webhook.http
POST {client.webhookUrls[n]} Content-Type: application/json X-Multas-Signature: c6f2...3e89 X-Multas-Request-Id: 05f4c751-... { "requestId": "05f4c751-...", "plate": "ABC1234", "status": "COMPLETED", "results": [ { "state": "edomex", "totalDebt": "905", "data": { "vehicle": { "brand": "DODGE", "model": "RAM 700" }, "infractions": [ { "folio": "EDX-2024-00012345", "amount": 905 } ] } } ] }

Verificar la firma (Node.js)

verify.ts
import crypto from 'crypto'; const expected = crypto .createHmac('sha256', process.env.WEBHOOK_SECRET) .update(rawBody) .digest('hex'); const ok = crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(signature) );

Si tu endpoint responde con error, reintentamos 3 veces con backoff (0s, 2s, 6s). Después de eso webhookSent = false y puedes recuperar los datos con GET /lookup/:id.

Rate limits

Default 60 req/min por API key, en una ventana fija de 60 s que empieza con la primera petición. Si necesitas más, escríbenos a contacto@multasmx.com.

Cada respuesta autenticada dice cuánto te queda, con las cabeceras de draft-ietf-httpapi-ratelimit-headers. Léelas para espaciar tus peticiones en vez de esperar al 429.

200 OK
RateLimit-Policy: "api-key";q=60;w=60 RateLimit: "api-key";r=59;t=42
Cabeceras
  • RateLimit-Policy — tu cuota: q peticiones por ventana de w segundos
  • RateLimit — cómo vas: te quedan r peticiones y la ventana se reinicia en t segundos
  • Retry-After — sólo en el 429: segundos que debes esperar antes de reintentar. Es el mismo valor que retryAfterSeconds del cuerpo
GET /billing/pricing no lleva API key y no cuenta para el límite.
429 Too Many Requests
Retry-After: 23 RateLimit-Policy: "api-key";q=60;w=60 RateLimit: "api-key";r=0;t=23 { "error": "rate_limit_exceeded", "message": "max 60 req/min", "retryAfterSeconds": 23 }

Códigos de error

Status Código Descripción
400 invalid_body / unknown_states Payload inválido o estado no reconocido.
400 unknown_test_plate · test_identifier_mismatch Placa o NIV de prueba que no existe, o combinado con uno real (ver Pruebas sin costo).
401 Missing / Invalid API key Header x-api-key ausente o incorrecto.
402 insufficient_credits · trial_expired Saldo insuficiente (incluye required, available, missing y el desglose por estado). trial_expired sólo aparece en cuentas con el periodo de prueba anterior.
404 request_not_found El requestId no existe o no pertenece a tu cuenta.
429 rate_limit_exceeded Superaste el límite de requests por minuto.
429 sandbox_limit_exceeded Superaste el límite diario de consultas de prueba.
502 scrape_failed Error interno al comunicarse con el portal del estado.
503 sandbox_disabled Las consultas de prueba no están disponibles en este momento.

Disponibilidad del servicio

Multas MX es un servicio best-effort. No ofrecemos garantía de disponibilidad ni SLA.

La API depende de portales gubernamentales de terceros que no controlamos. Esos portales pueden cambiar su estructura, entrar en mantenimiento, bloquear el acceso o dejar de responder sin previo aviso. Cuando eso ocurre, el estado afectado se marca como DOWN, MAINTENANCE o BLOCKED y deja de aparecer en GET /states hasta que se recupera.

No garantizamos tiempos de respuesta, tasas de éxito, ni la cobertura continua de un estado en particular. Diseña tu integración asumiendo que cualquier estado puede no estar disponible en un momento dado: revisa siempre skipped[] en la respuesta de POST /lookup y el estado de cada resultado en el webhook.

Los estados que no se pudieron procesar no se cobran.

Pruebas gratis

Empieza a consultar
hoy mismo.

Crea tu cuenta y consulta placas de prueba sin pagar nada. Compras créditos cuando vayas a consultar placas reales.

No pedimos tarjeta para crear la cuenta.