Innova Prime · API de Certificados
v1

API de Certificados

Peça o certificado digital (e-CPF) do seu cliente à Innova Prime e receba cada mudança de etapa no seu sistema.

Visão geral

A integração tem duas partes:

1. PedidoSeu sistema envia os dados do cliente e o documento com foto. O pedido entra na hora na fila de atendimento da Innova.
2. AtendimentoA Innova fala com o cliente pelo WhatsApp, agenda a videoconferência de validação e emite o certificado.
3. AvisosA cada mudança de etapa, a Innova faz um POST assinado no seu endereço de webhook. Você também pode consultar quando quiser.

Convenções: HTTPS obrigatório, JSON em UTF-8, datas em ISO 8601 com fuso de Brasília (-03:00), CPF só com dígitos e telefone no formato internacional.

Ambientes

Comece pelo ambiente de teste. A chave de produção é entregue depois que os seus testes forem aprovados.

AmbienteEndereço baseObservação
Testehttps://teste.innovaprimecertificados.com.brDados fictícios. Nenhuma mensagem sai para ninguém.
Produçãohttps://plataforma.innovaprimecertificados.com.brPedidos reais.

Chave da API, segredo do webhook e endereço de webhook são diferentes em cada ambiente.

Autenticação

Toda chamada leva a sua chave no cabeçalho X-API-Key.

X-API-Key: ip_test_3Hq9...

Criar pedido

POST/api/certificados/v1/pedidos

O corpo é multipart/form-data, com três partes:

ParteTipoObrigatóriaConteúdo
dadostexto (JSON)SimOs campos da tabela abaixo
documentoarquivoSimDocumento com foto do cliente (CNH ou RG): PDF, JPG ou PNG, até 15 MB
certidaoarquivoNãoCertidão complementar, mesmos formatos e limite

Campos de dados:

CampoTipoObrigatórioRegra
referenciatexto, até 60SimNúmero da operação no seu sistema. Uma operação pode ter vários pedidos, um por cliente. Volta em todos os avisos.
nometexto, até 200SimNome completo, como no documento
cpf11 dígitosSimConferido pelo dígito verificador
telefoneE.164SimCelular com código do país, ex.: +5519999990000
emailtextoSimE-mail do cliente
observacoestexto, até 500NãoEx.: melhor horário para contato

Exemplo de dados:

{
  "referencia": "OP-2026-000123",
  "nome": "Fulano de Tal",
  "cpf": "52998224725",
  "telefone": "+5519999990000",
  "email": "fulano@exemplo.com",
  "observacoes": "Prefere contato de manhã"
}

Resposta 201 Created:

{
  "pedido_id": "c7f1e2a09b3d4e5f8a9b0c1d2e3f4a5b",
  "referencia": "OP-2026-000123",
  "nome": "Fulano de Tal",
  "cpf": "52998224725",
  "etapa": "CONTATO_INICIADO",
  "criado_em": "2026-10-20T10:15:00-03:00"
}

Guarde o pedido_id: é ele que identifica o cliente em cada aviso.

CPF e telefone não se repetem

Enquanto um pedido seu estiver aberto (antes de INSTALADO, SEM_RETORNO ou CANCELADO):

Essas regras valem só entre os seus próprios pedidos. Se o mesmo cliente tiver pedido com outro parceiro da Innova, os pedidos seguem separados e nenhum parceiro recebe qualquer informação do outro.

Consultar pedido

Para quando um aviso não chegou, ou para conferir a situação:

GET/api/certificados/v1/pedidos/{pedido_id}

Um pedido, com a etapa atual e o histórico.

GET/api/certificados/v1/pedidos?referencia=OP-2026-000123

Todos os pedidos daquela operação, um por cliente (lista; vazia se não houver nenhum).

Resposta 200 OK:

{
  "pedido_id": "c7f1e2a09b3d4e5f8a9b0c1d2e3f4a5b",
  "referencia": "OP-2026-000123",
  "nome": "Fulano de Tal",
  "cpf": "52998224725",
  "etapa": "AGENDADO",
  "agendado_para": "2026-10-21T14:00:00-03:00",
  "criado_em": "2026-10-20T10:15:00-03:00",
  "historico": [
    {"etapa": "CONTATO_INICIADO", "ocorrido_em": "2026-10-20T10:15:00-03:00"},
    {"etapa": "AGENDADO", "ocorrido_em": "2026-10-20T11:02:40-03:00"}
  ]
}

Um pedido_id que não foi criado com a sua chave responde 404, igual a um pedido que não existe.

Etapas do pedido

O campo etapa tem sempre um destes seis valores. A lista pode crescer em versões futuras: trate valor desconhecido sem erro.

etapaRótuloSignificadoCampo extra
CONTATO_INICIADOContato iniciadoPedido recebido; a Innova envia a mensagem de boas-vindas ao cliente
AGENDADOAgendadoVideoconferência de validação marcada (ou remarcada)agendado_para
APROVADOAprovadoValidação aprovada
INSTALADOInstaladoCertificado emitido e instalado
SEM_RETORNOSem retornoO cliente não respondeu aos contatos
CANCELADOCanceladoPedido encerrado sem emissãomotivo, quando houver

INSTALADO, SEM_RETORNO e CANCELADO são finais na maior parte dos casos, mas um pedido SEM_RETORNO pode voltar para AGENDADO se o cliente responder depois.

Webhook de etapas

A cada mudança de etapa, a Innova faz POST no seu endereço de webhook, com o corpo em JSON e uma assinatura HMAC no cabeçalho.

Configuração

Informe à Innova um endereço HTTPS público por ambiente. A Innova devolve o segredo do webhook, usado só para conferir a assinatura. Ele não é a chave da API.

Corpo

{
  "evento_id": "ev_9a1c0d7e5b2f4a6c8d0e",
  "tipo": "certificado.etapa",
  "pedido_id": "c7f1e2a09b3d4e5f8a9b0c1d2e3f4a5b",
  "referencia": "OP-2026-000123",
  "nome": "Fulano de Tal",
  "cpf": "52998224725",
  "etapa": "AGENDADO",
  "etapa_rotulo": "Agendado",
  "agendado_para": "2026-10-21T14:00:00-03:00",
  "motivo": null,
  "ocorrido_em": "2026-10-20T11:02:40-03:00"
}

O aviso traz pedido_id, referencia, nome e cpf, para identificar o cliente dentro da operação sem precisar consultar nada. Telefone e documentos não voltam: você já tem esses dados.

Cabeçalhos

CabeçalhoConteúdo
Content-Typeapplication/json
X-Innova-EventoIgual a evento_id
X-Innova-TimestampMomento do envio, em segundos desde 1970 (Unix)
X-Innova-Assinaturasha256= + HMAC-SHA256 em hexadecimal de <timestamp>.<corpo exato>, com o segredo do webhook

Conferir a assinatura

Calcule o HMAC sobre o corpo exatamente como chegou, antes de qualquer conversão de JSON, compare em tempo constante e recuse aviso com mais de 5 minutos.

import hashlib, hmac, time

def aviso_valido(corpo: bytes, timestamp: str, assinatura: str, segredo: str) -> bool:
    if abs(time.time() - int(timestamp)) > 300:
        return False
    esperado = hmac.new(segredo.encode(), f"{timestamp}.".encode() + corpo,
                        hashlib.sha256).hexdigest()
    return hmac.compare_digest(f"sha256={esperado}", assinatura)
const crypto = require("crypto");

function avisoValido(corpo, timestamp, assinatura, segredo) {
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
  const esperado = "sha256=" + crypto.createHmac("sha256", segredo)
    .update(`${timestamp}.`).update(corpo).digest("hex");
  const a = Buffer.from(esperado), b = Buffer.from(assinatura || "");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Resposta e reenvio

Erros e limites

Toda resposta de erro vem em JSON, com uma mensagem em português e, quando for o caso, o campo que causou o erro:

{"erro": "CPF inválido: confira os dígitos.", "campo": "cpf"}
CódigoQuandoO que fazer
200Já existe pedido seu aberto para o mesmo CPFUsar o pedido devolvido
201Pedido criado
400Corpo fora do formato (JSON inválido, parte faltando)Corrigir a requisição
401Chave ausente ou inválidaConferir X-API-Key e o ambiente
404Pedido não encontradoConferir o pedido_id
413Arquivo acima de 15 MBEnviar arquivo menor
415Formato de arquivo não aceitoEnviar PDF, JPG ou PNG
422Campo inválido ou faltando, ou telefone já usado por outro CPF num pedido seu abertoVer campo e erro
429Muitas chamadas seguidasEsperar os segundos de Retry-After
5xxFalha da InnovaTentar de novo depois; o pedido não duplica

Limite: 60 chamadas por minuto por chave.

Teste rápido

No ambiente de teste, com a sua chave de teste:

curl -X POST https://teste.innovaprimecertificados.com.br/api/certificados/v1/pedidos \
  -H "X-API-Key: $CHAVE_DE_TESTE" \
  -F 'dados={"referencia":"TESTE-001","nome":"Fulano de Tal","cpf":"52998224725","telefone":"+5519999990000","email":"fulano@exemplo.com"}' \
  -F "documento=@cnh-ficticia.jpg"

curl "https://teste.innovaprimecertificados.com.br/api/certificados/v1/pedidos?referencia=TESTE-001" \
  -H "X-API-Key: $CHAVE_DE_TESTE"

Andar com o pedido pelas etapas (só no teste)

Para ver cada aviso chegando no seu webhook sem esperar ninguém, mova o seu pedido de teste:

POST/api/certificados/v1/teste/pedidos/{pedido_id}/etapa
curl -X POST https://teste.innovaprimecertificados.com.br/api/certificados/v1/teste/pedidos/$PEDIDO_ID/etapa \
  -H "X-API-Key: $CHAVE_DE_TESTE" -H "Content-Type: application/json" \
  -d '{"etapa": "AGENDADO"}'

# CANCELADO aceita um motivo:
#   -d '{"etapa": "CANCELADO", "motivo": "Cliente desistiu"}'
Esta rota não existe em produção: lá quem move o pedido é o atendimento da Innova.

Histórico de versões

VersãoDataMudança
v112/10/2026Primeira versão: criar e consultar pedido, webhook de etapas, rota de teste

Mudanças que quebram a integração só entram numa versão nova (/v2), avisada com antecedência. Campos e etapas novos podem aparecer na v1: ignore o que não conhecer.