Quick Start
Setup mínimo para captura autenticada em 5 minutos.
Pré-requisitos
Seção intitulada “Pré-requisitos”- Acesso ao Admin Console (solicite à equipe Provvi)
- API Key (
pvv_api_*) — gerada na seção “API Keys” do cliente no Admin Console - License Key (
pvv_live_*oupvv_sand_*) — gerada na seção “Licenças” do contrato no Admin Console
Credenciais de teste: Use License Keys com prefixo
pvv_sand_*(ambiente Sandbox) durante o desenvolvimento. O comportamento é idêntico à produção, sem cobrança.
1. Criar sessão (backend)
Seção intitulada “1. Criar sessão (backend)”Seu backend cria a sessão e recebe um token. A API Key nunca deve ser exposta no frontend.
// Node.js / Express — exemploapp.post('/captura/iniciar', async (req, res) => { const response = await fetch('https://api.provvi.com.br/web/sessions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': process.env.PROVVI_API_KEY, // segredo do backend }, body: JSON.stringify({ reference_id: req.body.referenceId, // ID do anúncio, veículo, etc. redirect_uri: 'https://seusite.com/captura/retorno', webhook_url: 'https://seusite.com/api/provvi/webhook', profile: 'vehicle_inspection', }), });
const { token, expires_at } = await response.json(); res.json({ token, expires_at });});Consulte API Backend para detalhes completos de todos os endpoints.
2. Iniciar captura (frontend)
Seção intitulada “2. Iniciar captura (frontend)”Escolha uma das opções abaixo.
Opção A — Android SDK
Seção intitulada “Opção A — Android SDK”// build.gradle — adicionar .aarimplementation(files("libs/provvi-sdk-release.aar"))// Uma vez no startup (configure/provision são suspend — rode numa coroutine).// A licença é validada dentro de configure(); identidade do app é derivada// internamente (você não informa bundleId/cert).lifecycleScope.launch { ProvviSDK.configure( context = applicationContext, licenseKey = "pvv_live_SuaChaveAqui", operatorId = operatorId, // UUID do operador (onboarding) captureProfile = CaptureProfile.VEHICLE_INSPECTION, ) ProvviSDK.provisionDeviceIfNeeded()}
// Por captura — abre a tela de captura do SDK (registre um ActivityResultLauncher):ProvviSDK.startSecureCapture(launcher, this, MaskConfig(shape = MaskShape.RECTANGLE))
// No callback do launcher — leia o resultado uma vez:when (val outcome = ProvviSDK.consumeLastCaptureOutcome()) { is CaptureOutcome.Success -> { Log.d("Provvi", "Sessão: ${outcome.result.sessionId}") // outcome.result.authenticatedJpegBytes → JPEG com manifesto ICP-Brasil embutido } is CaptureOutcome.LicenseError -> { /* licença inválida */ } is CaptureOutcome.PermissionDenied -> { /* câmera/GPS negados */ } else -> { /* outros erros — ver errors.md */ }}Consulte Android SDK para a API completa.
Opção B — iOS SDK
Seção intitulada “Opção B — iOS SDK”import ProvviSDK
// Uma vez no startup. A licença é validada em configure(); Bundle ID + Team ID// são derivados internamente (você não os informa).try await ProvviSDK.configure( licenseKey: "pvv_live_SuaChaveAqui", operatorId: operatorId, // UUID do operador (onboarding) captureProfile: .vehicleInspection)_ = await ProvviSDK.provisionDeviceIfNeeded()
// Por captura — tela de captura SwiftUI do SDK:ProvviCaptureScreen( capturedBy: "operador-123", referenceId: "VIN-9BWZZZ377VT004251") { outcome in switch outcome { case .success(let result, _): print("Sessão: \(result.sessionId)") // result.authenticatedJpegData → JPEG com manifesto ICP-Brasil embutido case .licenseError(let reason): print("Erro de licença: \(reason)") case .permissionDenied: print("Permissão de câmera/GPS negada") default: break // outros erros — ver errors.md }}Consulte iOS SDK para a API completa.
Opção C — Web SDK (Web Component)
Seção intitulada “Opção C — Web SDK (Web Component)”Integração direta na sua página via Web Component.
<script type="module"> import { useProvviCamera, EVENTS } from '/js/provvi-camera.es.js';
const camera = useProvviCamera({ licenseKey: 'pvv_live_SuaChaveAqui', });
camera.addEventListener(EVENTS.UPLOADED, (e) => { const { result } = e.detail.capture; console.log('Captura autenticada:', result.session_id); console.log('JPEG assinado:', result.authenticated_jpeg_url); });
camera.addEventListener(EVENTS.ERROR, (e) => { console.error('Erro:', e.detail.error.message); });
// token vem do seu backend camera.open({ token: 'TOKEN_DA_SESSAO' });</script>Consulte Web SDK para a API completa.
Opção D — Hosted Flow (redirect)
Seção intitulada “Opção D — Hosted Flow (redirect)”A forma mais simples: redirecione o usuário para a página de captura Provvi.
// Frontend — após receber o token do seu backendconst token = await fetch('/captura/iniciar', { method: 'POST', ... }).then(r => r.json());
window.location.href = `https://capture.provvi.com.br?token=${token.token}`;Após a captura, o usuário é redirecionado de volta para o redirect_uri com os parâmetros:
provvi_session_token— token originalprovvi_session_id— ID da sessão para consulta
Consulte Hosted Flow para configurações avançadas.
3. Receber webhook (backend)
Seção intitulada “3. Receber webhook (backend)”// Endpoint de webhook no seu backendapp.post('/api/provvi/webhook', (req, res) => { const { session_id, reference_id, status, authenticated_jpeg_url, // JPEG com manifesto C2PA + ICP-Brasil EMBUTIDOS signing_mode, recapture_risk, } = req.body;
// Armazene as URLs e associe ao seu registro console.log(`Captura ${session_id} concluída para ${reference_id}`); console.log(`JPEG assinado: ${authenticated_jpeg_url}`); console.log(`Risco de recaptura: ${recapture_risk}`);
res.sendStatus(200);});4. Consultar resultados (backend)
Seção intitulada “4. Consultar resultados (backend)”// Após receber o webhook ou o redirectconst results = await fetch(`https://api.provvi.com.br/web/session-results/${token}`);const data = await results.json();
// data.photos[] contém cada foto com:// - authenticated_jpeg_url (JPEG com manifesto C2PA + ICP-Brasil embutidos)// - frame_hash_hex (SHA-256 do frame original)// - gps_lat, gps_lon, gps_accuracy5. Testando a integração
Seção intitulada “5. Testando a integração”Verifique cada etapa com os comandos abaixo:
Testar API Key:
curl -X POST https://api.provvi.com.br/web/sessions \ -H "Content-Type: application/json" \ -H "x-api-key: SUA_API_KEY_AQUI" \ -d '{"reference_id":"teste","redirect_uri":"https://seusite.com","webhook_url":"https://seusite.com/webhook","profile":"demo"}'Resposta esperada: {"token":"uuid-v4","expires_at":"..."} (HTTP 201)
Testar License Key (Web SDK): Abra a página com o Web SDK no navegador. O console deve exibir a versão do SDK sem erros de licença.
Testar webhook:
Use um serviço como webhook.site como webhook_url na criação da sessão. Após captura, o payload deve aparecer lá.
Verificar captura:
Acesse verify.provvi.com.br e informe o session_id retornado para ver os detalhes da autenticação.
Comportamento importante
Seção intitulada “Comportamento importante”- Sessões expiram em 30 minutos — crie uma nova sessão se o token expirar
- URLs das imagens expiram em 7 dias — baixe e armazene as imagens no seu backend
- Webhooks não têm retry — use
GET /web/session-results/:tokencomo fallback se o webhook falhar
Próximos passos
Seção intitulada “Próximos passos”- API Backend — endpoints completos, headers, erros
- Erros — tabela completa de códigos de erro
- Licenciamento — ambientes, volume, cache