v3.0.0 Entrar no sistema OpenAPI

API UniValidar

Valide assinaturas eletrônicas de documentos PDF (ICP-Brasil e gov.br) com o serviço oficial VALIDAR do ITI, receba os dados de cada assinante e o Relatório de Conformidade em PDF, tudo em uma única chamada.

URL base{{BASE}}

Visão geral

A API recebe o PDF assinado, consulta o VALIDAR do ITI e devolve um resultado padronizado: se o documento é válido, quem assinou, o certificado usado, a data da assinatura e o Relatório de Conformidade oficial.

1Crie sua chaveEntre no sistema UniValidar e crie uma chave em Chaves de API (ou peça ao administrador da conta).
2Envie o PDFPOST /validar com o arquivo e o token no cabeçalho.
3Use o resultadoConfira valido, os assinantes e guarde o id como protocolo.

Todas as respostas são em JSON (UTF-8). Datas seguem o formato devolvido pelo ITI (dd/mm/aaaa hh:mm:ss BRT).

Autenticação

Envie o token em todas as chamadas, por um destes cabeçalhos:

Cabeçalhos
X-API-Key: uvt_seu_token_aqui
# ou
Authorization: Bearer uvt_seu_token_aqui

O token dá acesso à sua cota. Guarde no servidor (variável de ambiente ou cofre de segredos) e nunca exponha em páginas públicas ou aplicativos instalados no celular do cliente.

Cada token pode ter limite diário, limite mensal e data de validade. Peça um token por sistema para acompanhar o uso separadamente.

Validar um PDF

POST/validarmultipart/form-data

Envie o arquivo no campo file. Os demais parâmetros vão na URL (query string) e são opcionais.

ParâmetroTipoPadrãoDescrição
fileobrigatórioarquivo-PDF assinado, até 15 MB.
relatorio_conformidadebooleantrueAnexa o PDF oficial do Relatório de Conformidade do ITI em relatorio_conformidade_base64. Use false para uma resposta mais leve e mais rápida.
comprovantepdf | png-Anexa a tela de resultado do VALIDAR como PDF ou imagem em comprovante_base64.
cachebooleantrueReaproveita o resultado se o mesmo arquivo foi validado nas últimas 24 horas. false força uma consulta nova.
completobooleanfalseInclui o relatório técnico completo do ITI em relatorio_iti.
curl -X POST "{{BASE}}/validar" \
  -H "X-API-Key: $TOKEN" \
  -F "file=@procuracao.pdf"
import httpx

TOKEN = "uvt_..."

with open("procuracao.pdf", "rb") as f:
    r = httpx.post(
        "{{BASE}}/validar",
        headers={"X-API-Key": TOKEN},
        files={"file": ("procuracao.pdf", f, "application/pdf")},
        timeout=180,
    )

dados = r.json()
if not dados["sucesso"]:
    print(dados["codigo"], dados["erro"])
else:
    print(dados["status_label"])
    for a in dados["assinaturas"]:
        print(a["nome"], a["cpf"], a["status"])
import { readFile } from "node:fs/promises";

const form = new FormData();
form.append("file", new Blob([await readFile("procuracao.pdf")], { type: "application/pdf" }), "procuracao.pdf");

const r = await fetch("{{BASE}}/validar", {
  method: "POST",
  headers: { "X-API-Key": process.env.TOKEN },
  body: form,
  signal: AbortSignal.timeout(180_000),
});
const dados = await r.json();
if (!dados.sucesso) throw new Error(`${dados.codigo}: ${dados.erro}`);
console.log(dados.status_label, dados.assinaturas);
<?php
$ch = curl_init('{{BASE}}/validar');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['X-API-Key: ' . getenv('TOKEN')],
    CURLOPT_POSTFIELDS     => ['file' => new CURLFile('procuracao.pdf', 'application/pdf')],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 180,
]);
$dados = json_decode(curl_exec($ch), true);
curl_close($ch);

if (!$dados['sucesso']) {
    echo $dados['codigo'] . ': ' . $dados['erro'];
} elseif ($dados['valido']) {
    echo 'Assinatura aprovada';
}

Resposta

Exemplo de resposta de uma validação aprovada (o PDF do relatório foi encurtado):

200 OK
{
  "id": 1532,
  "sucesso": true,
  "valido": true,
  "status": "aprovada",
  "status_label": "Assinatura aprovada",
  "total_assinaturas": 1,
  "assinaturas": [
    {
      "nome": "FULANO DE TAL",
      "cpf": "***.123.456-**",
      "autoridade": "ICP-Brasil",
      "data": "16/10/2026 15:34:16 BRT",
      "status": "aprovada",
      "status_texto": "Assinatura aprovada",
      "tipo_assinatura": "Destacada",
      "motivo": "ASSINA POR PROCURAÇÃO",
      "certificado": {
        "tipo": "RFB e-CPF A1",
        "emissor": "AC SAFEWEB RFB v5",
        "valido_de": "04/03/2026 11:39:48 BRT",
        "valido_ate": "04/03/2027 11:39:48 BRT",
        "numero_serie": "0x44f3...",
        "revogado": false,
        "expirado": false
      },
      "cadeia_certificados": ["FULANO DE TAL", "AC SAFEWEB RFB v5", "AC Secretaria da Receita Federal do Brasil v4", "Autoridade Certificadora Raiz Brasileira v5"],
      "cadeia_valida": true,
      "integridade_ok": true,
      "carimbos_tempo": [{ "emissor": "SAFEWEB 50160", "referencia": "16/10/2026 15:34:32 BRT", "status": "aprovada" }],
      "algoritmo": "RSA",
      "alertas": []
    }
  ],
  "documento": {
    "nome": "procuracao.pdf",
    "hash": "70562c78d196...a163859",
    "tipo_arquivo": "PDF",
    "data_validacao": "17/10/2026 20:07:27 BRT",
    "conformidade": "MP 2.200-2/2001"
  },
  "arquivo": { "nome": "procuracao.pdf", "tamanho_bytes": 669924, "sha256": "70562c78d196...a163859" },
  "tempo_ms": 6230,
  "cache": false,
  "relatorio_conformidade": { "disponivel": true, "tamanho_bytes": 48211, "baixar": "/validacoes/1532/relatorio-conformidade" },
  "relatorio_conformidade_base64": "JVBERi0xLjQKJ...",
  "relatorio_texto": "Informações gerais do arquivo: ..."
}

Campos principais

CampoTipoDescrição
idnúmeroProtocolo da validação. Guarde para consultar depois ou baixar o relatório.
sucessobooleantrue quando a consulta foi concluída (mesmo que a assinatura seja reprovada).
validoboolean | nulltrue só quando todas as assinaturas foram aprovadas.
statustextoResultado geral. Veja Resultado da assinatura.
status_labeltextoResultado pronto para mostrar ao usuário.
total_assinaturasnúmeroQuantidade de assinaturas encontradas (o carimbo do tempo não conta como assinatura).
assinaturaslistaUma entrada por assinatura, com os campos da tabela abaixo.
documentoobjetoDados do documento segundo o ITI: nome, hash, tipo, data da validação e norma de conformidade.
arquivoobjetoNome, tamanho e SHA-256 do arquivo enviado.
tempo_msnúmeroTempo total da validação, em milissegundos.
cachebooleantrue quando o resultado veio de uma validação recente do mesmo arquivo.
relatorio_conformidadeobjetodisponivel, tamanho_bytes e o caminho baixar do PDF.
relatorio_conformidade_base64textoPDF oficial do Relatório de Conformidade, em base64.
seloslistaSelos do resultado: nome, tipo, titulo, assinatura, situacao e o caminho png. Veja Selos em PNG.
comprovante_base64textoTela de resultado do VALIDAR (quando pedido o comprovante), com o tipo em comprovante_tipo.
relatorio_textotextoResumo do resultado em texto, como exibido pelo ITI.
relatorio_itilistaRelatório técnico completo do ITI (só com completo=true).

Cada assinatura

CampoTipoDescrição
nometextoTitular do certificado.
cpftextoCPF (ou CNPJ) do titular, mascarado como o ITI exibe.
autoridadetextoICP-Brasil ou Gov.br.
datatextoData e hora da assinatura.
statustextoaprovada, reprovada ou indeterminada.
tipo_assinaturatextoPor exemplo Destacada ou Anexada.
motivotextoMotivo declarado na assinatura, por exemplo "ASSINA POR PROCURAÇÃO".
certificadoobjetotipo, emissor, valido_de, valido_ate, numero_serie, revogado, expirado.
cadeia_certificadoslistaDo titular até a autoridade raiz.
cadeia_validabooleanCadeia de confiança aprovada pelo ITI.
integridade_okbooleanO documento não foi alterado depois de assinado.
carimbos_tempolistaCarimbos do tempo da assinatura: emissor, referencia, status.
alertaslistaAvisos registrados pelo ITI que não invalidam o documento.

Resultado da assinatura

statusvalidoSignificado
aprovadatrueTodas as assinaturas foram aprovadas pelo ITI.
reprovadafalseAo menos uma assinatura é inválida (documento alterado, certificado revogado, cadeia não confiável, entre outros).
indeterminadafalseO ITI não conseguiu concluir a análise. Comum quando o programa que assinou não segue todos os requisitos.
sem_assinaturafalseO PDF não tem assinatura eletrônica.
desconhecidonullResultado não reconhecido. Tente de novo com cache=false.

Relatório de Conformidade

É o PDF oficial emitido pelo VALIDAR, com todas as informações técnicas da validação. Vem anexado por padrão em relatorio_conformidade_base64.

import base64

if dados["relatorio_conformidade"]["disponivel"]:
    with open(f"relatorio-{dados['id']}.pdf", "wb") as saida:
        saida.write(base64.b64decode(dados["relatorio_conformidade_base64"]))
import { writeFile } from "node:fs/promises";

if (dados.relatorio_conformidade?.disponivel) {
  await writeFile(`relatorio-${dados.id}.pdf`, Buffer.from(dados.relatorio_conformidade_base64, "base64"));
}
if ($dados['relatorio_conformidade']['disponivel']) {
    file_put_contents("relatorio-{$dados['id']}.pdf", base64_decode($dados['relatorio_conformidade_base64']));
}

O PDF também pode ser baixado depois, pelo protocolo:

GET/validacoes/{id}/relatorio-conformidadeapplication/pdf

Se o relatório não estiver disponível, relatorio_conformidade.disponivel vem false e o restante do resultado continua válido. Para respostas mais rápidas quando o relatório não for necessário, envie relatorio_conformidade=false.

Selos em PNG

Cada validação gera selos prontos para exibir no seu sistema ou anexar ao processo: um selo de assinatura para cada assinante (qualificada, avançada ou eletrônica, com a situação e o protocolo) e um selo de carimbo do tempo quando a assinatura tiver carimbo. As imagens têm 880 × 392 px, fundo transparente nos cantos.

GET/validacoes/{id}/seloslista dos selos
GET/validacoes/{id}/selos/{nome}.pngimage/png

Os nomes seguem o padrão assinatura-1, carimbo-1, assinatura-2... A resposta de /validar já traz a lista em selos. Para receber as imagens na mesma chamada, envie selos_base64=true e leia selos[].png_base64.

curl -H "X-API-Key: $TOKEN" -o selo-assinatura.png \
  "{{BASE}}/validacoes/1532/selos/assinatura-1.png"
for selo in dados["selos"]:
    png = requests.get(BASE + selo["png"], headers=CAB, timeout=30).content
    open(f"{selo['nome']}.png", "wb").write(png)

Validar por URL

POST/validar/urlapplication/json

Para PDFs que já estão publicados em um endereço acessível pela internet.

CampoTipoPadrãoDescrição
urlobrigatóriotexto-Endereço do PDF (http ou https).
relatorio_conformidadebooleantrueAnexa o Relatório de Conformidade.
comprovantepdf | png-Anexa a tela de resultado.
cachebooleantrueReaproveita resultado recente.
completobooleanfalseInclui o relatório técnico completo.
cURL
curl -X POST "{{BASE}}/validar/url" \
  -H "X-API-Key: $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://exemplo.com.br/documento.pdf"}'

Validar em lote

POST/validar/lotemultipart/form-data

Até 10 PDFs por chamada, repetindo o campo files. Aceita os mesmos parâmetros de /validar. Cada arquivo que não vier do cache consome uma unidade da cota.

cURL
curl -X POST "{{BASE}}/validar/lote?relatorio_conformidade=false" \
  -H "X-API-Key: $TOKEN" \
  -F "files=@contrato.pdf" \
  -F "files=@procuracao.pdf"
200 OK
{
  "total": 2,
  "aprovadas": 1,
  "com_erro": 0,
  "resultados": [ { "id": 1533, "status": "aprovada", ... }, { "id": 1534, "status": "reprovada", ... } ]
}

Os itens de resultados seguem a mesma ordem dos arquivos enviados e têm o mesmo formato da resposta de /validar.

Consultar depois

GET/validacoes/{id}JSON

Devolve de novo o resultado de uma validação feita antes, pelo id. Cada token só enxerga as próprias validações. Aceita completo=true.

GET/validacoes/{id}/relatorio-conformidadePDF
cURL
curl -H "X-API-Key: $TOKEN" "{{BASE}}/validacoes/1532"

curl -H "X-API-Key: $TOKEN" -o relatorio.pdf \
  "{{BASE}}/validacoes/1532/relatorio-conformidade"

Cota de uso

Quando o token tem limite, as respostas de validação trazem os cabeçalhos:

CabeçalhoDescrição
X-Cota-Restante-DiaValidações restantes hoje (horário de Brasília).
X-Cota-Restante-MesValidações restantes no mês.
GET/contaJSON
200 OK
{
  "nome": "Sistema de Procurações",
  "limite_dia": 500, "usado_dia": 37, "restante_dia": 463,
  "limite_mes": null, "usado_mes": 0, "restante_mes": null
}

Limite null significa sem limite. Ao esgotar a cota a API responde 429 com o código COTA_ESGOTADA.

Cache

O mesmo arquivo (mesmo conteúdo, identificado pelo SHA-256) validado nas últimas 24 horas devolve o resultado na hora, com "cache": true, e não consome cota. O Relatório de Conformidade também volta anexado.

Para forçar uma consulta nova ao ITI, envie cache=false.

Erros

Todo erro devolve "sucesso": false, um codigo fixo para tratar no seu sistema e uma mensagem em erro.

429 Too Many Requests
{
  "sucesso": false,
  "codigo": "COTA_ESGOTADA",
  "erro": "Limite diário atingido (500 validações)"
}
HTTPcodigoQuando aconteceO que fazer
400ARQUIVO_INVALIDOO arquivo enviado não é um PDF.Envie o PDF original assinado.
401TOKEN_INVALIDOToken ausente ou incorreto.Confira o cabeçalho X-API-Key.
403TOKEN_BLOQUEADOToken desativado ou vencido.Fale com o administrador da conta.
404NAO_ENCONTRADOProtocolo inexistente ou de outro token; relatório não disponível.Confira o id.
413ARQUIVO_GRANDEArquivo acima de 15 MB ou lote com mais de 10 arquivos.Divida o envio.
422PARAMETRO_INVALIDOCampo obrigatório ausente ou valor inválido. A lista vem em campos.Corrija a chamada.
422URL_INACESSIVELNão foi possível baixar o PDF da URL informada.Confira se o endereço é público.
429COTA_ESGOTADALimite diário ou mensal do token atingido.Aguarde a renovação ou peça aumento.
502SERVICO_INDISPONIVELO serviço do ITI está fora do ar ou não respondeu a tempo.Tente de novo em alguns minutos. O id fica registrado.

Boas práticas

Tempo de esperaConfigure o cliente HTTP para aguardar até 180 segundos. A maioria das validações responde em poucos segundos, mas o ITI pode demorar em horários de pico.
Nova tentativaEm SERVICO_INDISPONIVEL, aguarde alguns minutos e tente de novo, com intervalos crescentes. Não repita em sequência imediata.
ProtocoloGrave o id junto do documento no seu sistema. Ele permite reconsultar o resultado e baixar o relatório depois.
Resposta leveSe não precisa do PDF do relatório, envie relatorio_conformidade=false: a resposta fica menor e mais rápida.
Arquivo originalEnvie sempre o PDF exatamente como foi assinado. Qualquer alteração (mesmo reimprimir ou salvar de novo) invalida a assinatura.
SegurançaChame a API a partir do seu servidor. Se precisar chamar direto de uma página web (front-end), peça ao administrador para liberar o endereço do seu site.

Disponibilidade

GET/healthsem token
200 OK
{ "ok": true, "produto": "UniValidar", "versao": "3.0.0" }

A referência técnica gerada automaticamente (OpenAPI) está em /docs.