{"removeAttribution":false,"l10n":{"translations":{"default_locale":{"translation":{}}},"defaultLocale":"default_locale","locales":[{"code":"default_locale","name":"default_locale"}]},"logo":{"image":"/assets/logo.4a21835e35b73240d412896f3d5efa76a091a6fd7e6b2b046d5c7970963ce92f.9c1bb791.svg","link":"/"},"navbar":{"items":[{"type":"link","fsPath":"index.page.tsx","metadata":{},"label":"Início","link":"/","linePosition":"top","routeSlug":"/"},{"type":"group","label":"Parceiros","items":[{"type":"link","fsPath":"parceiros/guides/index.md","metadata":{"type":"markdown"},"label":"Guias","link":"/parceiros/guides","linePosition":"top","routeSlug":"/parceiros/guides"},{"type":"link","fsPath":"parceiros/casos-de-uso/index.md","metadata":{"type":"markdown"},"label":"Casos de uso","link":"/parceiros/casos-de-uso","linePosition":"top","routeSlug":"/parceiros/casos-de-uso"},{"type":"link","fsPath":"parceiros/tutorials/index.md","metadata":{"type":"markdown"},"label":"Tutoriais","link":"/parceiros/tutorials","linePosition":"top","routeSlug":"/parceiros/tutorials"},{"type":"link","fsPath":"apis/parceiros/openapi.yaml","metadata":{"type":"openapi","title":"Movvia Arrecada+ — API de Integração para Parceiros (v2)","description":"API REST pública da Movvia para integração de parceiros (OEMs, operadoras\nde tag, seguradoras, frotistas) com o ecossistema Arrecada+ de pedágio\neletrônico free flow.\n\n# 0. Primeiros Passos\n\n1. **Comece com usuário e senha.** A Movvia fornece as credenciais no\n   onboarding. Toda chamada usa **HTTP Basic Auth**.\n2. **Descubra o seu `parceiroId`** chamando [`GET /me`](#/operations/me).\n   O retorno traz o `parceiroId` associado ao usuário autenticado. Use\n   esse valor no header `x-parceiro-id` das demais chamadas.\n3. **Opere os demais recursos** (webhooks, placas, pedidos) usando o\n   `parceiroId` descoberto.\n\n> **Use [`GET /me`](#/operations/me) se você ainda não sabe qual é o\n> `parceiroId` daquele usuário.** O endpoint existe justamente para\n> permitir que o parceiro descubra sozinho, sem depender do suporte.\n\n> **Versão 2.0.0.** Esta spec acomoda o modelo **liquidante por parceiro**,\n> introduz os endpoints `POST /pedidos/{id}/confirmar` e `POST /pedidos/{id}/cancelar`\n> e padroniza os eventos de webhook no formato `pe.<módulo>.<evento>`.\n> A v1 permanece operante em `/am-gateway-api/v1/` até **2026-12-02** (janela de 6 meses após GA da v2).\n>\n> **Nota sobre URLs.** A partir de 2026-Q2 o serviço foi renomeado de\n> `am-gateway-api` para `gestao-webhooks-api`. Endpoints deste contrato\n> são servidos em `/gestao-webhooks-api/v1/...`. O `v1` no path é a\n> versão da API HTTP do serviço; o `v2.0.0` do `info.version` refere-se\n> ao contrato semântico (modelo liquidante, eventos canônicos). Os dois\n> números variam independentemente.\n\n# 1. Modos de Operação\n\n| Modo | Descrição | Cadastro de Placas |\n|------|-----------|--------------------|\n| **Filtrado** | Parceiro recebe apenas passagens de placas cadastradas via `POST /placas` | Obrigatório |\n| **Total** | Parceiro recebe **todas** as passagens capturadas pelo sistema | Não necessário |\n\nO modo é definido na configuração do parceiro (chave `MODO_PUBLICACAO`:\n`FILTRADO` ou `TOTAL`).\n\n# 2. Modelo Liquidante\n\nCada parceiro possui uma configuração **`LIQUIDANTE`** que define **quem debita\no valor** quando um pedido é pago:\n\n| Valor de `LIQUIDANTE` | Quem liquida | Efeito em `POST /pedidos` |\n|---|---|---|\n| ausente / próprio `parceiroId` | O próprio parceiro (externo) | Pedido criado em `CRIADO`; PE aguarda `POST /pedidos/{id}/confirmar` |\n| `parceiroId` do **Pedágio Eletrônico** | Pedágio Eletrônico | Saldo da conta PE do parceiro é debitado automaticamente; pedido transita para `CONFIRMADO` |\n| outro `parceiroId` cadastrado | Parceiro-terceiro (publisher) | Pedido criado em `CRIADO`; o parceiro-terceiro é quem confirma via `POST /pedidos/{id}/confirmar` |\n\nQuando `LIQUIDANTE` aponta para o Pedágio Eletrônico, o parceiro **precisa\nter conta PE vinculada**. A configuração do liquidante é definida pela\nMovvia no onboarding do parceiro.\n\n# 3. Ciclo de Vida do Pedido\n\n```mermaid\nstateDiagram-v2\n    [*] --> CRIADO: POST /pedidos\n    CRIADO --> CONFIRMADO: liquidação automática (liquidante=PE)\n    CRIADO --> CONFIRMADO: POST /pedidos/{id}/confirmar (liquidante externo)\n    CRIADO --> CANCELADO: POST /pedidos/{id}/cancelar\n    CRIADO --> EXPIRADO: TTL atingido (default 30 min)\n    CRIADO --> ERRO: falha interna de processamento\n    CONFIRMADO --> [*]\n    CANCELADO --> [*]\n    EXPIRADO --> [*]\n    ERRO --> [*]\n```\n\nEstados terminais: `CONFIRMADO`, `CANCELADO`, `EXPIRADO`, `ERRO`. Não há\nmais estado `PROCESSANDO` nem `PAGO` no banco de pedidos em v2 — esses\nnomes continuam existindo apenas como **eventos legados** (ver seção 4).\n\n# 4. Convenção de Eventos de Webhook\n\nEventos v2 seguem o formato **`pe.<módulo>.<evento>`**:\n\n| Evento v2 | Quando dispara | Evento legado (v1) emitido em paralelo |\n|-----------|----------------|----------------------------------------|\n| `pe.pedido.criado` | `POST /pedidos` retorna 201 (qualquer liquidante) | `PEDIDO_PROCESSANDO` |\n| `pe.pedido.confirmado` | Liquidação concluída (automática pelo PE ou via `POST /confirmar`) | `PEDIDO_PAGO` |\n| `pe.pedido.cancelado` | `POST /pedidos/{id}/cancelar` ou cancelamento interno | `PEDIDO_CANCELADO` |\n| `pe.pedido.expirado` | TTL do pedido atingido sem confirmação | `PEDIDO_EXPIRADO` |\n| `pe.pedido.erro` | Falha irrecuperável no processamento | `PEDIDO_ERRO` |\n| `pe.transacao.recebida` | Nova passagem capturada para placa monitorada | `TRANSACAO_RECEBIDA` |\n| `pe.transacao.atualizada` | Passagem atualizada (valor/categoria) | `TRANSACAO_ATUALIZADA` |\n| `pe.transacao.cancelada` | Passagem cancelada pela concessionária | `TRANSACAO_CANCELADA` |\n\n### Modelo de cadastro\nA partir da v2, **cada evento é cadastrado como um webhook independente**\n(não há mais os tipos agregados `TRANSACOES`/`PEDIDOS`). O parceiro pode\napontar URLs diferentes por evento ou reusar a mesma URL em vários\ncadastros. O catálogo completo de eventos cadastráveis (com rótulo e\ndescrição) está em `GET /webhook/eventos`.\n\n## 4.1 Dual-emit (retrocompatibilidade)\n\nDurante **6 meses a partir do GA da v2 (até 2026-12-02)**, cada transição\nde estado dispara **dois webhooks**: o legado (v1) e o novo (v2). Isso\npermite que parceiros v1 sigam funcionando enquanto os novos adotam o\npadrão v2.\n\n**Recomendação para parceiros novos:** escute apenas os eventos `pe.*` e\nignore os legados. A partir de 2026-12-02, apenas os eventos v2 serão\nemitidos.\n\n## 4.2 `origem_confirmacao` em `pe.pedido.confirmado`\n\nO evento `pe.pedido.confirmado` carrega o campo `origem_confirmacao`:\n\n- `DETECTADO_AUTOMATICAMENTE` — liquidação via débito do PE (liquidante=PE).\n- `PARCEIRO_CONFIRMOU` — liquidação externa confirmada via `POST /pedidos/{id}/confirmar`.\n\n## 4.3 Idempotência de parceiro ao processar\n\nEventos podem ser entregues mais de uma vez (retry, dual-emit). O parceiro\ndeve idempotentizar por `pedidoId` + transição de estado. Dois eventos\nsucessivos representando a mesma transição (mesmo `pedidoId`, mesmo estado\nterminal) devem ter efeito único.\n\n# 5. Autenticação e Segurança\n\nTodas as chamadas do parceiro para a API usam **HTTP Basic Auth**:\n\n```\nAuthorization: Basic {base64(usuario:senha)}\n```\n\nCredenciais fornecidas pela Movvia no onboarding. Validade: 1 ano com\nrenovação automática.\n\n## 5.1 Headers obrigatórios\n\n| Header | Descrição |\n|--------|-----------|\n| `Authorization` | Basic Auth |\n| `Content-Type` | `application/json` |\n| `x-parceiro-id` | Identificador único do parceiro |\n\n## 5.2 Webhooks (Movvia → Parceiro) — HMAC-SHA256\n\nWebhooks enviados pela Movvia incluem assinatura no header\n`x-parceiro-assinatura`:\n\n```\nx-parceiro-assinatura: sha256={hmac_hash}\n```\n\nCálculo: `HMAC-SHA256(chaveSecreta, request_body_bruto)`. Chave secreta é\na fornecida no `POST /webhook` ao cadastrar o endpoint.\n\n## 5.3 Retry policy\n\n- Timeout por tentativa: **30 s**\n- Tentativas: **3 retries** além da inicial (máximo 4 tentativas totais)\n- Backoff exponencial: **1 s → 2 s → 4 s → 8 s (cap)** com **jitter 0.5**\n- Condições de retry: HTTP **5xx**, `ConnectException`, `TimeoutException`\n- HTTP **4xx** NÃO dispara retry — erro do parceiro (URL inválida, auth, etc.)\n- Falha final: entrega marcada como `FALHA` (não bloqueia o PE)\n- Parceiro deve responder **HTTP 2XX** para confirmar recebimento\n- `POST /webhook/teste-conectividade` é **síncrono** e **sem retry**\n  (1 tentativa, mesmo timeout de 30 s)\n\n# 6. Rate Limiting\n\n- 1.000 requisições/minuto por credencial\n- 10.000 requisições/hora por credencial\n- Headers de resposta: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`\n\n# 7. Política de Versionamento\n\n- **v1 (deprecated)** — base `/am-gateway-api/v1/`. Congelada em 2026-06-02.\n  Nenhum incremento será aplicado após essa data. Sunset: **2026-12-02**.\n- **v2 (current)** — base `/gestao-webhooks-api/v1/` (serviço renomeado\n  mantendo semântica v2 deste contrato). Endpoints aditivos e schemas\n  evoluídos. Webhooks fazem dual-emit durante a janela de sunset.\n- A partir de v2, cada mudança de contrato é registrada em\n  `docs/specs/versoes/CHANGELOG.md` seguindo Keep a Changelog.\n\n# 8. Tratamento de Erros\n\nRespostas de erro em v2 seguem o envelope consistente com a v1\n(`{ success: false, error: { code, message, details }, meta }`) acrescido\ndo campo `error.type` (URI) para discriminação formal no estilo RFC 7807.\nNovos casos ganham novos URIs — ver `#/components/schemas/ProblemType`.\n"},"label":"Referência da API","link":"/apis/parceiros/openapi","linePosition":"top","routeSlug":"/apis/parceiros/openapi"}],"linePosition":"top"},{"type":"group","label":"Estabelecimentos Comerciais","items":[{"type":"link","fsPath":"estabelecimentos-comerciais/guides/index.md","metadata":{"type":"markdown"},"label":"Guias","link":"/estabelecimentos-comerciais/guides","linePosition":"top","routeSlug":"/estabelecimentos-comerciais/guides"},{"type":"link","fsPath":"estabelecimentos-comerciais/casos-de-uso/index.md","metadata":{"type":"markdown"},"label":"Casos de uso","link":"/estabelecimentos-comerciais/casos-de-uso","linePosition":"top","routeSlug":"/estabelecimentos-comerciais/casos-de-uso"},{"type":"link","fsPath":"estabelecimentos-comerciais/tutorials/index.md","metadata":{"type":"markdown"},"label":"Tutoriais","link":"/estabelecimentos-comerciais/tutorials","linePosition":"top","routeSlug":"/estabelecimentos-comerciais/tutorials"},{"type":"link","fsPath":"apis/estabelecimentos-comerciais/openapi.yaml","metadata":{"type":"openapi","title":"Movvia Arrecada+ — API para Concessionárias","description":"Spec em construção. Escopo será preenchido conforme roadmap CSG.\n"},"label":"Referência da API","link":"/apis/estabelecimentos-comerciais/openapi","linePosition":"top","routeSlug":"/apis/estabelecimentos-comerciais/openapi"}],"linePosition":"top"},{"type":"group","label":"Vision Dados","items":[{"type":"link","fsPath":"vision-dados/guides/index.md","metadata":{"type":"markdown"},"label":"Guias","link":"/vision-dados/guides","linePosition":"top","routeSlug":"/vision-dados/guides"},{"type":"link","fsPath":"vision-dados/casos-de-uso/index.md","metadata":{"type":"markdown"},"label":"Casos de Uso","link":"/vision-dados/casos-de-uso","linePosition":"top","routeSlug":"/vision-dados/casos-de-uso"},{"type":"link","fsPath":"vision-dados/tutorials/index.md","metadata":{"type":"markdown"},"label":"Tutoriais","link":"/vision-dados/tutorials","linePosition":"top","routeSlug":"/vision-dados/tutorials"},{"type":"link","fsPath":"apis/vision-dados/openapi.yaml","metadata":{"type":"openapi","title":"Movvia Vision Dados — API de Ingestão para Concessionárias","description":"API REST pública da Movvia para **ingestão de imagens de passagem\nveicular** por concessionárias de pedágio eletrônico. Base do produto\n**Vision Dados**, que transforma o acervo de imagens obrigatório por\nlei em fluxo de receita recorrente — Movvia comercializa o acesso\npara seguradoras, bancos, frotistas e órgãos de investigação.\n\nEsta spec cobre **apenas a ingestão** (concessionária → Movvia). O\nconsumo pelos clientes finais B2B roda em canal separado.\n\n# 0. Primeiros Passos\n\n1. **Use as credenciais fornecidas pela Movvia no onboarding.** Toda\n   chamada usa **HTTP Basic Auth**.\n2. **Descubra o seu `concessionariaId`** chamando\n   [`GET /me`](#/operations/me). Guarde esse valor.\n3. **Envie passagens** com [`POST /passagens-visuais`](#/operations/enviarPassagemVisual),\n   incluindo o header `x-concessionaria-id` e o payload\n   `multipart/form-data` com os campos `image` e `metadata`.\n\n> Use [`GET /me`](#/operations/me) sempre que não souber qual é o\n> `concessionariaId` daquele usuário — existe justamente para\n> integrador descobrir sozinho, sem depender do suporte.\n\n# 1. Campos da passagem visual\n\n| Campo | Obrigatório | Observação |\n|---|---|---|\n| `image` (binário) | ✅ | JPEG, PNG ou WEBP. Máx 15 MB. |\n| `externalId` | ✅ | Único por concessionária; chave de idempotência. |\n| `capturedAt` | ✅ | ISO-8601 UTC (offset `Z`). Janela: até 7 dias passado. |\n| `latitude` / `longitude` | ✅ | WGS-84 decimal. |\n| `placa` | ✅ | String livre 1–20 chars (sem regex Mercosul). |\n| `sentido` | ◻️ | Enum: CRESCENTE, DECRESCENTE, NORTE, SUL, LESTE, OESTE. |\n| `faixa` | ◻️ | Inteiro >= 0. |\n| `velocidadeKmh` | ◻️ | Inteiro >= 0. |\n| `tipoVeiculo` | ◻️ | Enum: AUTO, MOTO, CAMINHAO, ONIBUS, OUTRO. |\n| `equipamentoId` | ◻️ | String livre até 100 chars. |\n| `rodovia` / `km` | ◻️ | String (ex.: \"BR-116\") e número decimal. |\n| `pracaId` | ◻️ | String até 50 chars (quando operar com praça). |\n| `classificacaoEixos` | ◻️ | Inteiro >= 1. |\n\n# 2. Idempotência\n\nRequisições duplicadas com o mesmo `(concessionariaId, externalId)`\nretornam `200 OK` com o `id` interno já gerado. A imagem binária **não\né re-armazenada**. Use sempre o `externalId` do seu sistema — ele é\na chave natural de deduplicação.\n\n# 3. Exemplo de envio (curl)\n\n```bash\ncurl -X POST https://api.pedagioeletronico.com.br/vision-dados/v1/passagens-visuais \\\n  -u \"$USUARIO:$SENHA\" \\\n  -H \"x-concessionaria-id: 42\" \\\n  -F \"image=@/caminho/para/imagem.jpg;type=image/jpeg\" \\\n  -F 'metadata={\"externalId\":\"passagem-2026-04-24-000123\",\"capturedAt\":\"2026-04-24T12:34:56Z\",\"latitude\":-23.550520,\"longitude\":-46.633308,\"placa\":\"ABC1D23\"};type=application/json'\n```\n\n# 4. Ciclo de vida da passagem\n\n```mermaid\nstateDiagram-v2\n    [*] --> RECEBIDA: POST /passagens-visuais\n    RECEBIDA --> PROCESSADA: indexação + dedup server-side\n    PROCESSADA --> EXCLUIDA: DELETE /passagens-visuais/{id} (LGPD)\n    RECEBIDA --> EXCLUIDA: DELETE /passagens-visuais/{id} (LGPD)\n    RECEBIDA --> REJEITADA: validação pós-upload falhou\n    EXCLUIDA --> [*]\n    REJEITADA --> [*]\n```\n\n# 5. LGPD\n\nA concessionária é **controladora** dos dados pessoais capturados na\npassagem (placa, imagem do veículo/condutor). A Movvia é **operadora**\n— armazena e disponibiliza o dado conforme contrato.\n\nQuando um titular exercer o direito à eliminação (LGPD Art. 18, V), a\nconcessionária deve acionar\n[`DELETE /passagens-visuais/{id}`](#/operations/excluirPassagemVisual).\nA Movvia apaga a imagem binária em até 72h e mantém apenas metadados\nanonimizados (ULID + hash) para fins de auditoria (LGPD Art. 16).\n\n# 6. Observabilidade\n\nTodo response carrega `meta.requestId` (UUID). **Informe esse valor ao\nabrir chamado de suporte** (`api@movvia.com.br`) — acelera o diagnóstico.\n\n# 7. Rate limiting\n\nA API é sujeita a limite de requisições por concessionária, definido\nno onboarding conforme volume esperado. Quando excedido, retornamos\n`429 Too Many Requests` com o header `Retry-After` (segundos)\nindicando quanto tempo aguardar.\n\n# 8. Versionamento\n\n- **SemVer** em `info.version`.\n- Path versioning em `/vision-dados/v1/`.\n- Breaking changes bumpam major, vão para `/vision-dados/v2/` e a\n  versão anterior permanece em `archive/openapi-vN.yaml` com\n  `x-v{N}-sunset-date` (janela típica: 6 meses).\n- Mudanças não-breaking (novo campo opcional, novo endpoint, novo\n  código de erro) incrementam minor/patch.\n"},"label":"Referência da API","link":"/apis/vision-dados/openapi","linePosition":"top","routeSlug":"/apis/vision-dados/openapi"}],"linePosition":"top"},{"type":"group","label":"Recursos","items":[{"type":"link","fsPath":"compartilhado/sandbox.md","metadata":{"type":"markdown"},"label":"Sandbox","link":"/compartilhado/sandbox","linePosition":"top","routeSlug":"/compartilhado/sandbox"},{"type":"link","fsPath":"compartilhado/sdks.md","metadata":{"type":"markdown"},"label":"SDKs","link":"/compartilhado/sdks","linePosition":"top","routeSlug":"/compartilhado/sdks"},{"type":"link","fsPath":"compartilhado/status.md","metadata":{"type":"markdown"},"label":"Status","link":"/compartilhado/status","linePosition":"top","routeSlug":"/compartilhado/status"},{"type":"link","fsPath":"compartilhado/seguranca/index.md","metadata":{"type":"markdown"},"label":"Segurança","link":"/compartilhado/seguranca","linePosition":"top","routeSlug":"/compartilhado/seguranca"},{"type":"link","fsPath":"changelog.md","metadata":{"type":"markdown"},"label":"Changelog","link":"/changelog","linePosition":"top","routeSlug":"/changelog"}],"linePosition":"top"}]},"footer":{"copyrightText":"© Movvia. Todos os direitos reservados.","items":[{"type":"link","fsPath":"legal/termos-api.md","metadata":{"type":"markdown"},"label":"Termos da API","link":"/legal/termos-api","linePosition":"top","routeSlug":"/legal/termos-api"},{"type":"link","fsPath":"legal/uso-responsavel.md","metadata":{"type":"markdown"},"label":"Uso responsável","link":"/legal/uso-responsavel","linePosition":"top","routeSlug":"/legal/uso-responsavel"}]},"markdown":{"toc":{"depth":2,"header":"On this page"},"frontMatterKeysToResolve":["image","links"],"partialsFolders":["**/_partials/**"],"lastUpdatedBlock":{"format":"timeago"},"editPage":{}},"mcp":{"hide":false,"docs":{"hide":false,"name":"MCP server","ignore":[]}},"banner":[],"breadcrumbs":{"prefixItems":[]},"userMenu":{"hide":true},"auth":{"idpsInfo":[]},"search":{},"entitiesCatalog":{},"apiProducts":{},"mcpData":{"docs":{"enabled":true,"name":"MCP server"}},"searchFeatures":{"advanced":{"enabled":false},"ai":{"enabled":true}},"analytics":{"ga":{"trackingId":"","exclude":[],"trackers":{}}}}