{"openapi":"3.1.0","info":{"title":"mymultas API","version":"0.1.0","description":"Traffic fines lookup API for Brazilian vehicles.\n\n**Base URL:** `https://api.mymultas.com.br`\n\n**Request body:** send `licensePlate` only (Mercosul, 7 characters). JSON field names are in English.\n\n**Auth:** send your key in `Authorization: Bearer <key>` or in the `X-API-Key` header. Prefixes: `mymt_test_*` for sandbox and `mymt_live_*` for production.\n\n**Sandbox:** with a `mymt_test_*` key, use the fictitious plates listed at `GET /docs` (no real lookup is performed). Machine-readable list at `GET /sandbox-test-vehicles.json`."},"servers":[{"url":"https://api.mymultas.com.br","description":"Production"}],"tags":[{"name":"consultations","description":"Single and batch async consultations"},{"name":"violations","description":"Cached violation detail"}],"paths":{"/v1/consultas":{"post":{"tags":["consultations"],"security":[{"ApiKeyAuth":[]}],"summary":"Single consultation","description":"Required: `licensePlate` (7-character Mercosul plate).\n\n**Live:** **202** + `jobId` — async queue (Redis/BullMQ), up to 3 attempts. Poll `GET /v1/jobs/{jobId}`: `status=completed` → `result.schemaVersion` 2, `result.kind` `single`, payload in `result.result` (canonical `outcome.violations[]`; each `id` is used with `GET /v1/violations/{id}/detail`); `result.itemsSummary`, `result.billing.successUnits` (billing only after technical success). `failed` → `error`.\n\n**Sandbox (`mymt_test_*`):** **200** immediate `result` + `environment: test`.\n\n**Webhooks:** `mymultas.job.completed` / `mymultas.job.failed` after `PATCH /v1/me/webhook`.\n\n**Detail fetch** (not billed as a listing call): `GET /v1/violations/{id}/detail` using `outcome.violations[].id`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsultationItem"}}}},"responses":{"200":{"description":"Sandbox: immediate result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsultationPostResponseSandbox"}}}},"202":{"description":"Live: job accepted — poll GET /v1/jobs/{jobId}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsultationJobAccepted"}}}},"402":{"description":"No quota / subscription"}}}},"/v1/violations/{id}/detail":{"get":{"tags":["violations"],"security":[{"ApiKeyAuth":[]}],"summary":"Violation detail (cached)","description":"Use UUID from `outcome.violations[].id` on a completed job (`GET /v1/jobs/:id`). First hit may call scraper or build from cached RENAINF snapshot (API Brasil); repeats use DB cache. Not counted as a billable listing consultation. If SERPRO consultation key expires (410), enqueue a new POST /v1/consultas.\n\n**Response shape:** customer-facing (`ViolationDetailPublic`): canonical RADAR-compatible fields plus optional `renainf` — full RENAINF registro line from API Brasil in English camelCase (see schema). Internal SERPRO-only junk (IDs, PIX flags, histories) stays stripped.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Violation UUID returned in `outcome.violations[].id` of a completed job."}],"responses":{"200":{"description":"Customer-facing detail (filtered).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ViolationDetailResponse"}}}},"404":{"description":"Not found or other customer"},"410":{"description":"Consultation key expired — new POST /v1/consultas"},"502":{"description":"Scraper or upstream error"}}}},"/v1/consultas/batch":{"post":{"tags":["consultations"],"security":[{"ApiKeyAuth":[]}],"summary":"Batch async (up to 50 items)","description":"Up to 50 items. **Billing** (prepaid credits, trial, monthly included quota, or legacy Stripe metered) runs after the job finishes, per successful technical consultation — see `result.billing.successUnits` and `result.itemsSummary` on `GET /v1/jobs/:id`.","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","maxItems":50,"items":{"$ref":"#/components/schemas/ConsultationItem"}}}}}}},"responses":{"202":{"description":"Job created"}}}},"/v1/jobs/{id}":{"get":{"tags":["consultations"],"security":[{"ApiKeyAuth":[]}],"summary":"Job status and result","description":"`schemaVersion` 2. **Single:** `result.kind=single`, `result.result`, `result.itemsSummary`, `result.billing.successUnits` (live). **Batch:** `result.kind=batch`, `result.results[]`, `result.itemsSummary[]` per vehicle (`status` success|failure, `fines` withFines|none|notApplicable). Prepaid/trial/monthly/metered usage matches `billing.successUnits`. Optional webhook mirrors the same payload as `result`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Job UUID returned by POST /v1/consultas or POST /v1/consultas/batch."}],"responses":{"200":{"description":"OK — job status, plus the result payload when completed."}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"mymt_live_* or mymt_test_*"}},"schemas":{"ConsultationJobAccepted":{"type":"object","description":"Returned by POST /v1/consultas (live) and POST /v1/consultas/batch when the job is queued. Poll GET /v1/jobs/{jobId} for the result.","required":["jobId","status"],"properties":{"jobId":{"type":"string","format":"uuid","description":"Job UUID — use with GET /v1/jobs/{jobId}."},"status":{"type":"string","enum":["pending"],"description":"Always `pending` on accept; transitions to `running` then `completed` or `failed`."},"message":{"type":"string","description":"Optional human-readable note (e.g. queue position)."}}},"ViolationPublic":{"type":"object","description":"Canonical listing row returned in `outcome.violations[]`. Internal/raw provider fields are stripped server-side.","required":["reference"],"properties":{"id":{"type":"string","format":"uuid","description":"UUID to use with GET /v1/violations/{id}/detail (only present when the consultation was persisted)."},"reference":{"type":"string","description":"Source reference id (e.g. `numeroAuto` such as 'RA11259981')."},"date":{"type":"string","description":"When the infraction occurred (raw provider format, usually 'DD/MM/YYYY HH:mm')."},"code":{"type":"string","description":"Provider infraction code (e.g. 'RA11259981')."},"description":{"type":"string","description":"Human-readable infraction description."},"amount":{"type":"string","description":"Fine amount as string (currency precision)."},"authority":{"type":"string","description":"Issuing authority name or id."},"location":{"type":"string","description":"Address or place where the infraction occurred."},"status":{"type":"string","description":"Provider status text (e.g. 'NA Gerada', 'NP Gerada')."}}},"ConsultationPostResponseSandbox":{"type":"object","description":"Immediate response returned by POST /v1/consultas when called with a sandbox API key (`mymt_test_*`). No scraper or CAPTCHA runs.","properties":{"environment":{"type":"string","enum":["test"],"description":"Always `test` for sandbox responses."},"result":{"type":"object","description":"The consultation result payload (same shape used inside `result.result` of GET /v1/jobs/{id} for live calls).","properties":{"queryId":{"type":"string","format":"uuid","description":"UUID identifying this consultation (useful for support/correlation)."},"licensePlate":{"type":"string","description":"License plate echoed from the request."},"renavam":{"type":"string","description":"RENAVAM when returned by the upstream provider."},"outcome":{"type":"object","description":"Lookup outcome.","properties":{"violations":{"type":"array","description":"Listing rows mapped to the canonical `ViolationPublic` shape.","items":{"$ref":"#/components/schemas/ViolationPublic"}},"comparison":{"type":"object","description":"Cross-check between vehicle and document channels (only present when both ran).","properties":{"summary":{"type":"string","description":"Plain-language summary of the comparison."},"likelyPairs":{"type":"number","description":"Number of items that likely match across channels."}}}}},"notes":{"type":"array","description":"Live: short outcome text in Portuguese (success / no fines / failure). Sandbox: diagnostic messages may be included.","items":{"type":"string"}}}}}},"ViolationDetailRenainf":{"type":"object","description":"RENAINF `/data/registros[]` row from API Brasil (`tipo=renainf`), mapped to English camelCase strings. Included only when the listing came from API Brasil (`chave`/internal flow `apibrasil`) and omitted if every mapped value is blank. Mirrors provider formatting (Portuguese labels in values, Brazilian dates dd/mm/yyyy).","properties":{"consultDetailHasError":{"type":"string","description":"Provider `consultadetalhe_existe_erro` (e.g. '0' when no lookup error)."},"consultDetailMessage":{"type":"string","description":"Provider `consultadetalhe_mensagem`."},"suspensionAcceptanceIssuerUf":{"type":"string","description":"`dadosdasuspensao_aceite_uf_jurisdicao`."},"suspensionRegistrationDate":{"type":"string","description":"`dadosdasuspensao_data_registro`."},"suspensionOriginCode":{"type":"string","description":"`dadosdasuspensao_origem`."},"suspensionTypeCode":{"type":"string","description":"`dadosdasuspensao_tipo`."},"paymentDetailsText":{"type":"string","description":"`dadosdopagamento_dados_pgmto`."},"paymentRegistrationTimestamp":{"type":"string","description":"`dadosdopagamento_dt_do_registro_do_pgmto`."},"paymentDate":{"type":"string","description":"`dadosdopagamento_dt_pagamento`."},"paymentStateUf":{"type":"string","description":"`dadosdopagamento_uf_pagamento`."},"paymentAmountPaid":{"type":"string","description":"`dadosdopagamento_valor_pago`."},"offenderCnhCondutor":{"type":"string","description":"`dadosinfrator_cnh_condutor`."},"offenderCnhInfractor":{"type":"string","description":"`dadosinfrator_cnh_infrator`."},"providerInfractionDate":{"type":"string","description":"`datadainfracao`."},"vehicleMakeModelDetail":{"type":"string","description":"`detalhe_amrcamodelo`."},"infractionRegistrationDate":{"type":"string","description":"`detalhe_cadastramento_infracao`."},"infractionFullCodeText":{"type":"string","description":"`detalhe_cod_infracao` (code plus description)."},"municipalityCodeEmplacement":{"type":"string","description":"`detalhe_cod_mun_emplacamento`."},"municipalityCodeInfractionLocation":{"type":"string","description":"`detalhe_cod_mun_infracao`."},"penaltyEmissionDate":{"type":"string","description":"`detalhe_dt_emissao_penalidade`."},"infractionOccurredDate":{"type":"string","description":"`detalhe_dt_infracao`."},"infractionNotificationDate":{"type":"string","description":"`detalhe_dt_notificacao_infracao`."},"infractionOccurredTime":{"type":"string","description":"`detalhe_hr_infracao`."},"regulatoryLimitRaw":{"type":"string","description":"`detalhe_limite_permitido`."},"infractionLocationRaw":{"type":"string","description":"`detalhe_local_infracao`."},"measurementConsideredRaw":{"type":"string","description":"`detalhe_medicao_considerada`."},"measurementActualRaw":{"type":"string","description":"`detalhe_medicao_real`."},"ticketNumber":{"type":"string","description":"`detalhe_num_auto_infracao`."},"authorityDescriptionRaw":{"type":"string","description":"`detalhe_orgao_autuador`."},"vehiclePlateRaw":{"type":"string","description":"`detalhe_placa`."},"infractionNoticeTypeCode":{"type":"string","description":"`detalhe_tipo_auto_infracao`."},"vehicleJurisdictionUf":{"type":"string","description":"`detalhe_uf_jurisdicao_veiculo`."},"authorityUf":{"type":"string","description":"`detalhe_uf_orgao_autuador`."},"plateRegistrationUf":{"type":"string","description":"`detalhe_uf_placa`."},"measurementUnitRaw":{"type":"string","description":"`detalhe_unidade_medida`."},"fineAmountRaw":{"type":"string","description":"`detalhe_valor_infracao`."},"enforceabilityRaw":{"type":"string","description":"`exigibilidade`."},"infractionNumericCode":{"type":"string","description":"`infracao` (code digits)."},"ticketNumberAlternate":{"type":"string","description":"`numeroautoinfracao`."},"authorityOrgCode":{"type":"string","description":"`orgao` (orgão autuador code)."}}},"ViolationDetailResponse":{"type":"object","required":["fetchedAt","detail"],"properties":{"fetchedAt":{"type":"string","format":"date-time","description":"When the detail was last fetched from the source (or cache write time)."},"detail":{"$ref":"#/components/schemas/ViolationDetailPublic"}}},"ViolationDetailPublic":{"type":"object","description":"Customer-facing detail for a single violation. SERPRO/RADAR-style canonical fields (English) plus optional `renainf` when the source is API Brasil RENAINF. Internal SERPRO-only noise and empty optional blocks are stripped server-side.","required":["reference","vehicle"],"properties":{"reference":{"type":"string","description":"Source reference id (e.g. numeroAuto 'RD31328027')."},"description":{"type":"string","description":"Human-readable infraction description."},"notes":{"type":"string","description":"Free-text notes attached by the issuing authority."},"ctbArticle":{"type":"string","description":"CTB (Brazilian Traffic Code) article number, e.g. '208'."},"severity":{"type":"string","description":"Severity tier (Leve, Média, Grave, Gravíssima)."},"points":{"type":"integer","description":"Driver's license points debited by this infraction."},"amount":{"type":"string","description":"Fine amount (string for currency precision)."},"amountWithDiscount":{"type":"string","description":"Discounted amount, only present when different from amount."},"date":{"type":"string","description":"When the infraction occurred."},"location":{"type":"string","description":"Address or place where the infraction occurred."},"city":{"type":"string","description":"City of the infraction."},"state":{"type":"string","description":"State (UF) of the infraction."},"authority":{"type":"string","description":"Issuing authority name."},"status":{"type":"string","description":"Current status (e.g. 'NA Gerada')."},"defenseDeadline":{"type":"string","description":"Deadline for filing a defense, when set."},"vehicle":{"type":"object","description":"Vehicle data echoed from the source (the API key holder is the owner, so this is information they already have).","properties":{"licensePlate":{"type":"string","description":"Vehicle license plate."},"renavam":{"type":"string","description":"Vehicle RENAVAM (national registration number)."},"brandModel":{"type":"string","description":"Manufacturer/model string as provided by the source (e.g. 'JTZ/DK160')."},"state":{"type":"string","description":"Vehicle registration UF (state)."}}},"measurement":{"type":"object","description":"Measurement details for radar/breathalyzer/decibel infractions. Omitted entirely when no measurement data is available.","properties":{"measuredValue":{"type":"string","description":"Raw value measured by the device (e.g. '82' km/h)."},"consideredValue":{"type":"string","description":"Value after the legal tolerance is applied — the value used to determine the infraction."},"legalLimit":{"type":"string","description":"Regulatory limit at the location (e.g. '60' km/h)."},"unit":{"type":"string","description":"Unit of measurement (e.g. 'km/h', 'dB', 'mg/L')."},"notes":{"type":"string","description":"Additional notes about the measurement."},"device":{"type":"object","description":"Equipment used to take the measurement.","properties":{"brand":{"type":"string","description":"Device manufacturer."},"model":{"type":"string","description":"Device model."},"serial":{"type":"string","description":"Device serial number."},"testSerial":{"type":"string","description":"Calibration / test certificate serial."}}}}},"renainf":{"$ref":"#/components/schemas/ViolationDetailRenainf"}}},"ConsultationItem":{"type":"object","required":["licensePlate"],"properties":{"licensePlate":{"type":"string","description":"Mercosul plate (7 alphanumeric characters).","example":"ABC1D23"}}}}}}