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 .

Base URL

https://api.multasmx.com

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-...

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.

Consulta stateCode Créditos
Multa estatal edomex, cdmx, guadalajara, … 1
Tenencia tenencia-edomex 1
Verificación / vigencia de placa vigencia-edomex 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 — el próximo que se consumirá. 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 1 a 16 stateCodes únicos
Cada estado se cobra según su costo en créditos: 1 crédito los estados de multas, la tenencia y la vigencia; 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, "fromCache": false, "responseTimeMs": 43120 } ] }

status puede ser PROCESSING, COMPLETED, PARTIAL o QUEUED_RETRY.

GET /states

Lista de estados activos (oculta los que están en DOWN o MAINTENANCE).

{ "states": [ { "stateCode": "cdmx", "stateName": "Ciudad de México", "captchaType": "image_flat", "avgResponseMs": 24300, "isHealthy": true } ], "count": 9 }

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":"MNB806C","states":["vigencia-edomex"]}'
results[0].data
{ "source": "edomex-controlv", "plate": "MNB806C", "found": true, "plateStatus": "VIGENTE", "validityStart": "2025-10-14", "validityEnd": "2030-10-14", "previousPlate": null, "message": "¡Estimado contribuyente, ..." }
Campos del resultado
  • foundfalse si la placa no está registrada en el padrón (respuesta definitiva del portal, no un error)
  • plateStatusVIGENTE · 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.

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.

request.sh
$ curl -X POST https://api.multasmx.com/lookup \ -H "x-api-key: sk_live_..." \ -H "Content-Type: application/json" \ -d '{"plate":"MNB806C","states":["tenencia-edomex"]}'
results[0].data
{ "source": "edomex-tenencia", "plate": "MNB806C", "found": true, "hasDebt": false, "debtDescription": "SIN ADEUDOS", "totalDebt": 0, "vehicle": { "model": "2022", "description": "HYUNDAI ELANTRA 4PTAS GLS IVT 4Cil", "vin": "5NPLM4AG0..." }, "plateValidityStart": "2025-10-14", "plateValidityEnd": "2030-10-14" }
Campos del resultado
  • foundfalse si la placa no existe en el padrón vehicular (respuesta definitiva del portal, no un error)
  • hasDebttrue 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.

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":"TNL508C","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":"LSGKB52H8JV205562","states":["repuve"]}'
results[0].data
{ "source": "repuve", "queriedBy": "plate", "registered": true, "hasTheftReport": true, "vehicle": { "marca": "CHEVROLET", "modelo": "CAVALIER", "anioModelo": 2018, "niv": "LSGKB52H8JV205562", "entidadEmplaco": "PUEBLA" }, "fgj": { "status": "con_reporte", "records": [{ "estatus": "ROBADO", "fechaRobo": "23/06/26" }] }, "ocra": { "status": "sin_reporte" }, "roboUsaCan": { "status": "sin_reporte" } }
Campos del resultado
  • registeredfalse si el vehículo no está inscrito en el registro (respuesta definitiva del portal, no un error)
  • hasTheftReport — atajo booleano: true si alguna de las tres fuentes reporta robo
  • 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) o desconocido. Trata desconocido como dato ausente, no como vehículo limpio: significa que esa fuente no respondió.
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. Sliding window de 60s. Si necesitás más, escribinos a contacto@multasmx.com.

429 Too Many Requests
{ "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.
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) o trial expirado.
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.
502 scrape_failed Error interno al comunicarse con el portal del estado.

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.

Primeros 10 créditos gratis

Empieza a consultar
hoy mismo.

Registra tu cuenta en segundos y haz tu primera consulta. Sin contratos, sin tarjeta de crédito.

Sin tarjeta · 10 créditos gratis · 7 días de trial