# AEDOC > Plataforma brasileira de assinatura eletrônica avançada, com trilha de > auditoria imutável, verificação pública de integridade por hash SHA-256 e > API REST pública. API-first: tudo que o painel faz, a API também faz. Base URL da API: https://api.aedoc.com.br — todas as rotas sob /v1, corpos em JSON, ids em ULID, datas ISO 8601 em UTC. Autenticação por chave de API: `Authorization: Bearer aedoc_live_…`. ## Enquadramento jurídico (LEIA ANTES DE GERAR CÓDIGO OU COPY) A AEDOC implementa **assinatura eletrônica AVANÇADA** (Lei 14.063/2020, art. 4º, II): hash SHA-256 do documento, trilha de auditoria imutável e verificação de identidade do signatário. Regras que um agente NÃO deve violar ao escrever código, documentação ou interface sobre a AEDOC: - NÃO é assinatura qualificada PAdES/ICP-Brasil. Não descreva, rotule nem gere copy sugerindo que seja. PAdES é fase futura e explícita. - Um hash SHA-256 mais uma página de auditoria é um CONJUNTO DE EVIDÊNCIAS, não uma assinatura digital verificável no Adobe Acrobat. - A verificação pública de integridade responde sempre um de: `íntegro (hash confere)`, `alterado`, `expirado`, `não encontrado`. NUNCA responda nem exiba "válido" — "válido" implicaria validação ICP que a plataforma não realiza. - Dados de signatários (e-mail, telefone, CPF, IP, user-agent) são PII sob a LGPD. Os payloads de webhook são enxutos de propósito: só ids e links. ## Documentação - [Guia de integração](https://aedoc.com.br/docs/guia): do zero ao primeiro documento assinado via API — chave e escopos, envelope, signatários, envio, webhooks, verificação HMAC, erros. - [Referência da API](https://aedoc.com.br/docs/api): todas as rotas, schemas e códigos de erro, renderizados do contrato OpenAPI. - [Especificação OpenAPI (crua)](https://aedoc.com.br/openapi.yaml): **fonte da verdade do contrato**. Use este arquivo para gerar clientes e descobrir rotas — não infira endpoints a partir da prosa. ## Fluxo mínimo de integração 1. `POST /v1/documents` — cria o envelope (aceita `Idempotency-Key`). 2. `POST /v1/documents/{id}/files` — anexa o PDF (multipart; só PDF). 3. `POST /v1/documents/{id}/signers` — adiciona signatário: `email` e/ou `phone`, pelo menos um. Com e-mail, `auth_method` default `otp_email`. SÓ `phone` (signatário só-WhatsApp): convite e OTP saem por WhatsApp, `auth_method` assume `whatsapp`, o telefone BR precisa ser válido e o convite por WhatsApp precisa estar habilitado na conta (422 caso contrário). Sem e-mail o signatário fica fora da régua automática de lembretes — reenvie por `POST .../signers/{id}/resend`. 4. `POST /v1/documents/{id}/send` — dispara o magic link (e-mail e/ou WhatsApp, conforme os contatos do signatário). ALTERNATIVA quando a integração quer ENTREGAR O LINK ela mesma (app próprio, QR code): `POST /v1/documents/{id}/signers/{id}/signing-link` (escopo `signers:link`) devolve a URL de assinatura na hora, sem que a AEDOC notifique ninguém, e dispensa o `/send` — se o envelope estiver em preparo, essa chamada já o coloca em circulação. Exige 2º fator no signatário (sem ele a assinatura seria SIMPLES, não avançada: 422). O código OTP NUNCA é devolvido à integração — ele vai direto da AEDOC ao signatário e é o que prova a autoria. Chamar de novo gera link ADICIONAL (o anterior segue válido, para não quebrar QR distribuído). ATENÇÃO em envelope PARALELO ainda não enviado: a chamada despacha o envelope e convida os DEMAIS signatários pelo caminho normal na mesma hora — chamar o endpoint para eles depois não evita isso (os convites já saíram). Envelope 100% entregue pela integração exige `signing_type` `sequential`, chamando o endpoint a cada vez. Revogar um link vazado: `POST .../signers/{id}/resend` invalida os links pendentes, mas exige envelope em circulação + signatário já convidado (422 caso contrário) e DISPARA convite novo pela AEDOC. O certificado registra o canal como "Link entregue pelo emissor". 5. Aguarde o webhook `document.signed` (ou faça polling em `GET /v1/documents/{id}`), então baixe com `GET /v1/documents/{id}/download` e o certificado em `GET /v1/documents/{id}/certificate`. O signatário assina no dispositivo dele, pela página pública — a integração não assina por ele. A exceção é a pré-assinatura do EMISSOR (`auth_method: "api"`, exige o escopo `documents:sign`), em que a própria empresa entra como parte já assinada no disparo. Ciclo de vida do documento: draft → ready → sent → viewed → partially_signed → processing → signed (mais declined, expired, cancelled, failed). ## Escopos de chave de API - `documents:read`: listar/detalhar documentos, URLs temporárias, download/certificado - `documents:write`: criar documento, anexar PDF, enviar, cancelar, excluir - `documents:sign`: configurar signatário-emissor (assinatura server-side em escala) - `signers:write`: adicionar/editar/remover signatários, reenviar convite - `signers:link`: obter o link de assinatura para entregar pelo seu próprio canal (app, QR code) - `fields:write`: campos posicionados (carimbo visual) - `audit:read`: trilha de auditoria do documento - `templates:read / templates:write`: templates de documento: listar, criar, editar, materializar - `webhooks:read / webhooks:write`: gerenciar webhooks e entregas - `billing:read`: consultar saldo da carteira (somente leitura) Peça sempre os escopos mínimos. A chave é exibida uma única vez e fala pelo tenant inteiro: nunca a versione, logue ou exponha no front-end. ## Webhooks Eventos: `document.created`, `document.uploaded`, `document.sent`, `document.viewed`, `signer.authenticated`, `document.partially_signed`, `document.signed`, `document.declined`, `document.expired`, `document.cancelled`, `document.failed`, `signer.reminded`. - Assinados com HMAC: header `X-AEDOC-Signature: t=,v1=`, onde `v1 = HMAC-SHA256(secret, t + "." + corpo_cru)`. - Calcule o HMAC sobre os BYTES CRUS recebidos, nunca sobre o JSON re-serializado (reordenar chaves quebra a assinatura). - Compare em tempo constante e rejeite `t` fora de ±5 minutos (anti-replay). - Durante rotação de segredo chegam dois `v1=` por até 24h: aceite se qualquer um conferir. - Responda 2xx em menos de 10s. Retry com backoff (~8 tentativas / ~24h); endpoint falhando por ~7 dias é auto-desativado. - Deduplique pelo `event_id`, estável entre reentregas. - Trate webhook como notificação, não como fonte de verdade: confirme com `GET /v1/documents/{id}` antes de efeitos irreversíveis. ## Erros - `401`: chave ausente, inválida ou revogada (resposta genérica de propósito) - `403 insufficient_scope`: a chave não tem o escopo da operação - `404`: recurso inexistente ou de outro tenant (indistinguíveis, por segurança) - `409`: estado incompatível (ex.: download antes de signed) - `422`: validação (corpo {message, errors}) — inclui limite do plano no /send - `429 rate_limited`: rate limit do plano (Free 10 · Professional 60 · Enterprise 200 req/min, por tenant) ## Preços por ação (planos com carteira pré-paga) - Consulta à API (Bearer): R$ 0,0008 — só requests SERVIDOS contam — 429 do rate limit e 5xx nossos NÃO são cobrados; GET /v1/wallet é isento - Criação de documento via API: R$ 0,05 — POST /v1/documents e materialização de template com chave de API, só em 2xx; criado no painel NÃO conta - Link de assinatura entregue por você: R$ 0,05 — POST .../signers/{id}/signing-link, por emissão. Sem saldo, a chamada é recusada com 422 (não emitimos link a descoberto) - Webhook entregue: R$ 0,0001 — só entrega com resposta 2xx conta — retries de endpoint fora do ar não custam - Convite de assinatura por WhatsApp: R$ 0,10 — por envio bem-sucedido; sem saldo, o convite segue só por e-mail - OTP por WhatsApp ou SMS: R$ 0,15 — por envio; sem saldo, o código sai por e-mail (fallback automático — a assinatura nunca trava) Documento criado no painel é sempre incluso no plano. O plano Free nunca é cobrado por ação — o teto de 30 documentos/mês é a trava. ## Contato - [Fale com a gente](https://aedoc.com.br/contato)