Como Enviar um Documento para Assinatura via API
Enviar um documento para assinatura via API parece simples — e pode ser — mas há decisões importantes em cada etapa: como subir o PDF de forma segura e escalável, como adicionar signatários com o perfil de autenticação correto, como definir a ordem de assinatura e a expiração, e como disparar os convites. Este guia prático percorre todo o envio passo a passo, com requisições e respostas JSON reais e um exemplo de upload por presigned URL.
Vamos focar na etapa de envio do documento — o momento em que um arquivo sai do seu sistema e entra no fluxo de coleta de assinaturas. Se você ainda está montando o ambiente, vale conferir antes o panorama de como funciona uma API de assinatura digital e o guia primeiros passos com a API em 5 minutos.
Ao final, você saberá escolher entre os dois caminhos de envio do SignDocs — os envelopes (fluxos multi-signatário) e a Assinatura Expressa (uma chamada → link de assinatura hospedado) — e terá o código necessário para colocar o primeiro documento no ar.
Visão geral: o que significa "enviar um documento" via API
Enviar um documento para assinatura é, na prática, criar um recurso na plataforma que reúne três elementos: o arquivo a ser assinado, a lista de signatários com seus métodos de autenticação, e as regras de fluxo (perfil de autenticação, ordem, expiração). Quando esse recurso é confirmado, a plataforma dispara os convites e passa a emitir eventos de ciclo de vida.
O envio se decompõe em quatro grandes passos:
- Preparar o PDF — garantir um arquivo válido, leve e padronizado.
- Subir o arquivo — inline em base64 (até 10 MB) ou por presigned URL, direto para o armazenamento de objetos.
- Montar o fluxo — sessão única (Assinatura Expressa) ou envelope com uma sessão por signatário, cada um com seu perfil de autenticação.
- Disparar os convites — deixar a plataforma notificar os signatários ou distribuir os links você mesmo.
api-hml.signdocs.com.br — lembrando que entidades de HML têm TTL de 7 dias.
Passo 1: preparar o PDF para assinatura
O PDF é o formato canônico para assinatura digital porque suporta o padrão PAdES, em que a assinatura fica embutida no próprio arquivo, preservando aparência e validade jurídica. Antes de subir o documento, alguns cuidados evitam problemas adiante:
- Achatar formulários (flatten): campos de formulário AcroForm não preenchidos podem conflitar com o posicionamento das assinaturas. Achate o que for conteúdo fixo.
- Remover proteção por senha: PDFs criptografados ou com restrições de edição não podem receber assinatura. Desbloqueie antes do envio.
- Conferir o tamanho: arquivos muito grandes (alta resolução de imagens escaneadas) tornam o upload e a verificação mais lentos. Comprima quando possível.
- Validar antes de enviar: a plataforma roda uma checagem de qualidade no PDF durante o upload — arquivos corrompidos ou protegidos são rejeitados nesse momento, e diagnosticar isso cedo evita retrabalho.
Documentos em outros formatos também podem ser assinados, mas via container CAdES no padrão PKCS#7/CMS, que gera um arquivo de evidência separado. Para entender quando usar cada padrão, veja o detalhamento sobre PAdES, CAdES e contêineres PKCS#7/CMS. Na maioria dos casos, converter para PDF antes do envio entrega o melhor resultado: um documento assinado autocontido e fácil de verificar publicamente.
Passo 2: subir o arquivo com presigned URL
Existem duas formas de levar os bytes do documento até a plataforma: inline em base64 dentro do JSON da chamada de criação (limite de 10 MB), ou upload por presigned URL. Para arquivos maiores ou volume de produção, a segunda é a abordagem recomendada. No SignDocs, o fluxo de presigned URL é ancorado na transação: você cria a sessão sem o documento e sobe o arquivo em seguida.
Por que presigned URL?
Uma presigned URL é um endereço temporário e assinado que autoriza o upload direto para o armazenamento de objetos, sem que o arquivo trafegue pelo corpo da requisição da API. Isso traz vantagens concretas:
- Escala: a API não precisa receber nem reencaminhar megabytes; os bytes vão direto ao storage.
- Segurança: a URL expira em poucos minutos e é válida apenas para aquele objeto e método (PUT).
- Performance: sem overhead de base64 (que infla o payload em ~33%) e sem pressão de memória no seu backend.
- Confiabilidade: uploads grandes não esbarram em limites de tamanho de requisição da API.
2.1 — Criar a sessão sem o documento
Primeiro você cria a sessão de assinatura normalmente — apenas sem o campo document. A transação subjacente nasce no estado CREATED, aguardando o arquivo:
2.2 — Solicitar a presigned URL
Com o transactionId em mãos, você pede o destino de upload, informando os metadados do arquivo:
2.3 — Enviar os bytes e confirmar o upload
Agora você faz um PUT direto na uploadUrl, enviando o arquivo binário. Esta chamada vai para o storage, não para a API — e por isso não leva o header Authorization; a autorização já está embutida na própria URL assinada. Em seguida, a chamada de confirmação (com o uploadToken) avisa a API que o arquivo chegou: é nela que o servidor calcula o hash SHA-256 do documento e move a transação para DOCUMENT_UPLOADED.
Em Node.js, o fluxo completo fica assim:
document.content (base64) na própria chamada de criação da sessão ou do envelope, eliminando presign e confirmação. É o caminho mais comum para começar; migre para o presigned URL quando os arquivos crescerem. Há também o upload direto em base64 pós-criação, via POST /v1/transactions/{id}/document.
Passo 3: montar o fluxo — sessão única ou envelope multi-signatário
Com o documento no lugar, o envio ganha forma: quem assina, como se autentica, em que ordem e até quando. Para um único signatário, a própria sessão de assinatura já resolve tudo. Para múltiplos signatários, o recurso certo é o envelope: o documento sobe uma vez e cada signatário recebe a sua própria sessão.
3.1 — O perfil de autenticação de cada signatário
Cada signatário recebe um perfil de autenticação (campo policy.profile), que define o nível de garantia exigido: CLICK_ONLY (aceite por clique), CLICK_PLUS_OTP (clique + código por e-mail/SMS), BIOMETRIC e BIOMETRIC_PLUS_OTP (biometria facial, sem ou com OTP) e DIGITAL_CERTIFICATE (certificado ICP-Brasil). Internamente, cada perfil vira uma sequência fixa de etapas (CLICK_ACCEPT, OTP_CHALLENGE, BIOMETRIC_LIVENESS, BIOMETRIC_MATCH...) que você vê na resposta da transação.
DIGITAL_SIGN_A1 é um step.type (tipo de etapa que aparece na resposta), nunca um valor de profile. Enviar DIGITAL_SIGN_A1 como profile resulta em erro 400. Para exigir certificado ICP-Brasil, use o profile DIGITAL_CERTIFICATE — via API, a assinatura usa o certificado A1 do próprio titular; tokens A3 são atendidos pelo assinador desktop do SignDocs, fora do fluxo da API. Para combinar métodos, veja a autenticação multimétodo.
3.2 — Definir a ordem: sequencial ou paralela
O campo signingMode, definido na criação do envelope, controla a dinâmica entre os signatários:
PARALLEL: todos os signatários podem assinar a qualquer momento, em qualquer ordem. Ideal para concluir o documento o mais rápido possível.SEQUENTIAL: a API impõe a fila definida pelosignerIndexde cada sessão (um inteiro de 1 a N) — o signatário 2 só consegue concluir depois que o 1 termina. Use quando houver dependência hierárquica de assinaturas.
Para um aprofundamento em cenários com muitas partes, papéis e dependências, consulte o guia de ordem de assinatura com múltiplos signatários.
3.3 — Personalizar a aparência (opcional)
A criação aceita um objeto appearance com a identidade visual do envio — companyName, logoUrl, brandColor, entre outros — aplicado à página hospedada que o signatário vê. Como a personalização é por envio, a mesma conta atende marcas ou clientes finais diferentes, o que é a base dos cenários white-label.
3.4 — Expiração e lembretes
No envio você define a janela de expiração — até quando os links são válidos — via expiresInMinutes no envelope. A API não tem lembretes recorrentes automáticos: o ritmo de cobrança fica no seu controle, com o evento TRANSACTION.DEADLINE_APPROACHING avisando via webhook quando o prazo de um signatário aperta e POST /v1/signing-sessions/{sessionId}/resend-invite reenviando o convite por e-mail.
3.5 — O envelope completo, na prática
Note o header X-Idempotency-Key: reenviar a mesma requisição com o mesmo corpo (após um timeout de rede, por exemplo) devolve a resposta original em vez de criar um envelope duplicado — a chave vale por 24 horas, e reutilizá-la com um corpo diferente resulta em 409. Repare também que cada signatário pode ter um perfil de autenticação diferente: o diretor com certificado ICP-Brasil, a testemunha com OTP. No modo sequencial, o signatário 2 até abre o link, mas só consegue concluir depois que o 1 termina. O desenho completo dos dois modos está no guia de ordem de assinatura com múltiplos signatários.
Passo 4: disparar os convites (ou entregar o link você mesmo)
Quando o envelope tem um owner (remetente) definido, a plataforma envia o convite por e-mail automaticamente a cada signatário cujo e-mail seja diferente do e-mail do owner. Mas há cenários em que você prefere controlar a distribuição:
- Convite automático por e-mail: defina o
ownerdo envelope e informe o e-mail de cada signatário. Simples e sem código adicional. - Entrega por canal próprio: monte o link final combinando a
urlda sessão com oclientSecretcomo parâmetro?cs=e distribua por WhatsApp, app, portal ou e-mail transacional seu. - Assinatura embarcada: em fluxos com assinatura incorporada, abra o checkout em um pop-up dentro da sua interface com a biblioteca
@signdocs-brasil/js, sem depender do e-mail.
A partir do envio, sua aplicação deve reagir aos eventos do ciclo de vida em vez de ficar consultando o status em loop. Configure um receptor para acompanhar SIGNING_SESSION.COMPLETED, ENVELOPE.ALL_SIGNED, TRANSACTION.EXPIRED e afins — o mecanismo completo está no guia de webhooks e eventos da API.
Envelopes vs. Assinatura Expressa: qual usar para enviar?
O SignDocs expõe duas superfícies de envio. Escolher a certa economiza código e evita complexidade desnecessária.
Envelopes (multi-signatário)
É o caminho para fluxos completos: múltiplos signatários, ordem sequencial ou paralela, perfis de autenticação distintos por signatário, eventos de ciclo de vida e evidências formais. É o que usamos nos exemplos acima. Para o desenho de ponta a ponta, veja o fluxo transacional completo.
Assinatura Expressa (Signing Sessions)
Resolve o caso "um documento, um signatário" em uma única chamada a POST /v1/signing-sessions, devolvendo o link de checkout hospedado (e o clientSecret para fluxos embarcados via pop-up). Ideal para a menor fricção possível — pense em onboarding, termos de aceite ou um contrato pontual:
A resposta já entrega a url de assinatura e o clientSecret — o link final é url?cs=... —, sem o passo de montar um envelope.
| Critério | Envelopes | Assinatura Expressa |
|---|---|---|
| Caso de uso | Fluxos completos, multi-signatário, contratos formais | Um documento, um fluxo, máxima simplicidade |
| Chamadas para enviar | Criação do envelope (com o documento) + uma sessão por signatário | Uma chamada a /v1/signing-sessions |
| Ordem de assinatura | SEQUENTIAL ou PARALLEL, com signerIndex por sessão | Focada em um signatário por sessão |
| Entrega ao signatário | E-mail automático (via owner) ou URL própria | Checkout hospedado ou pop-up incorporado |
| Eventos / webhooks | Ciclo de vida completo do envelope | Eventos da sessão de assinatura |
| Quando escolher | Controle granular e várias partes | Menor fricção e integração rápida |
Boas práticas e erros comuns ao enviar documentos
- Use X-Idempotency-Key na criação: reenviar o mesmo corpo devolve a resposta original em vez de duplicar o envio; a chave vale por 24 horas.
- Não envie base64 para arquivos grandes: o limite do inline é 10 MB, e o presigned URL evita o overhead de ~33% do base64.
- Não use
DIGITAL_SIGN_A1como profile: ele é umstep.type; para certificado ICP-Brasil useDIGITAL_CERTIFICATE. - Teste em homologação primeiro: use
api-hml.signdocs.com.br(atenção ao TTL de 7 dias das entidades) antes de ir para produção. - Registre seu webhook antes do primeiro envio: com o endpoint cadastrado desde o início, você não perde eventos do ciclo de vida.
- Valide o PDF antes do upload: arquivos protegidos por senha ou corrompidos são rejeitados na checagem de qualidade do upload — validar antes evita o vaivém.
- Trate a expiração da presigned URL: a URL vive 10 minutos; gere-a logo antes do PUT, não com horas de antecedência.
Cada documento enviado e concluído resulta em um arquivo assinado com validade jurídica respaldada pela MP 2.200-2/2001 (ICP-Brasil) e processamento em conformidade com a LGPD. O resultado pode ser verificado de forma independente no verificador público.
Perguntas Frequentes
Posso enviar o PDF em base64 dentro do JSON em vez de usar presigned URL?
Sim — e para a maioria das integrações é o caminho mais simples: o campo document.content da chamada de criação aceita o arquivo em base64, com limite de 10 MB. Acima disso, ou para evitar o overhead de ~33% do base64 em volume de produção, use o fluxo de presigned URL: crie a sessão sem o documento, solicite a URL assinada em POST /v1/transactions/{id}/document/presign, faça o PUT dos bytes direto no armazenamento de objetos e confirme em POST /v1/transactions/{id}/document/confirm — momento em que o servidor calcula o hash SHA-256 do arquivo.
Qual a diferença entre enviar por envelope e pela Assinatura Expressa?
O envelope é o caminho para fluxos com múltiplos signatários: você cria o envelope com o documento e o signingMode (SEQUENTIAL ou PARALLEL) e adiciona uma sessão por signatário via POST /v1/envelopes/{id}/sessions. A Assinatura Expressa, exposta em POST /v1/signing-sessions, resolve o caso de um documento e um signatário em uma única chamada, devolvendo a URL de assinatura hospedada e o clientSecret. Use envelopes quando houver várias partes e ordem de assinatura; use a Assinatura Expressa quando quiser a menor fricção possível para coletar uma assinatura.
Que formato de documento posso enviar para assinatura?
O PDF é o formato canônico para assinatura, pois recebe assinatura no padrão PAdES embutida no próprio arquivo, mantendo aparência e validade jurídica. Outros formatos — documentos Office (DOCX, XLSX, PPTX), OpenDocument, imagens (JPG, PNG, TIFF), TXT, CSV, XML, JSON e HTML — são aceitos e assinados via container CAdES no padrão PKCS#7/CMS, gerando um arquivo de assinatura separado do original. Na prática, recomenda-se converter para PDF antes do envio sempre que o objetivo for um documento assinado autocontido e fácil de verificar publicamente.
Como defino se os signatários assinam em sequência ou em paralelo?
A ordem é controlada pelo signingMode do envelope, definido na criação. No modo PARALLEL, todos os signatários podem assinar a qualquer momento, em qualquer ordem. No modo SEQUENTIAL, a fila é definida pelo signerIndex de cada sessão — um inteiro de 1 a N — e o signatário 2 só consegue concluir depois que o 1 termina. Escolha sequencial quando houver dependência hierárquica de assinaturas e paralelo quando quiser concluir o documento o mais rápido possível.
O que acontece se um documento não for assinado dentro do prazo de expiração?
Ao atingir a expiração, os links de assinatura pendentes deixam de ser válidos e sua aplicação é notificada via webhook pelos eventos TRANSACTION.EXPIRED, SIGNING_SESSION.EXPIRED e, em envelopes, ENVELOPE.EXPIRED — permitindo criar um novo envio ou disparar um fluxo de reengajamento. Antes disso, o evento TRANSACTION.DEADLINE_APPROACHING avisa quando o prazo de um signatário está apertando, e POST /v1/signing-sessions/{sessionId}/resend-invite reenvia o convite por e-mail. A janela de expiração é definida no envio (expiresInMinutes, no caso dos envelopes).
Posso personalizar a aparência da página de assinatura no envio?
Sim. A criação da sessão ou do envelope aceita um objeto appearance com a identidade visual do envio — nome da empresa, logotipo e cores (companyName, logoUrl, brandColor, entre outros) — aplicado à página hospedada que o signatário vê. Como a personalização é por envio, a mesma conta atende marcas ou clientes finais diferentes, o que é útil em cenários white-label. Já o posicionamento do carimbo visual dentro do PDF não é configurável por coordenadas: a plataforma aplica a assinatura digital ao documento e registra os dados do signatário na trilha de evidências.
Como envio o convite ao signatário: a API manda o e-mail ou eu entrego o link?
Os dois modelos são suportados. Se o envio tiver um owner (remetente) definido, a plataforma envia o convite por e-mail automaticamente a cada signatário cujo e-mail seja diferente do e-mail do owner. Se preferir distribuir por canal próprio (WhatsApp, portal, e-mail transacional seu), monte o link final combinando a url da sessão com o clientSecret como parâmetro ?cs= e entregue como quiser. Em integrações embarcadas, é comum abrir o checkout em um pop-up na sua interface com a biblioteca @signdocs-brasil/js, sem depender do e-mail.
Envie seu primeiro documento para assinatura via API hoje
Upload por presigned URL, envelopes para fluxos multi-signatário e Assinatura Expressa em uma chamada — com SDKs oficiais e suporte em pt-BR. Tudo com validade jurídica ICP-Brasil, conformidade LGPD e sandbox gratuito para desenvolver.
Fale com o time comercial Conheça a plataforma grátis