Pular para o conteúdo

Envelopes e destinatários

Um envelope é um contrato a caminho de ser assinado: uma versão de modelo renderizada com suas variáveis, os destinatários que atuam nele e as evidências de tudo o que acontece. Crie um com POST /v1/envelopes.

Campo Tipo Observações
template tpl_… Obrigatório
version número ou "latest" Padrão latest; resolvida e fixada na criação. Precisa estar publicada
variables objeto Validado contra o JSON Schema da versão
recipients array Um por papel (role, name, email; opcionais externalUserId, verification, fields para preencher previamente por id de campo e order para alterar a ordem de assinatura)
subject, message string Usados nos e-mails de assinatura e exibidos na página de assinatura
delivery email · embedded · none Padrão email
expiresAt RFC 3339 Precisa estar no futuro; o envelope expira nesse momento, e os links de assinatura e de observador deixam de funcionar
cc array Destinatários CC extras (name, email) além dos papéis CC do modelo; até 50
viewers array Pessoas que acompanham o envelope sem assinar (name, email, notifyOnSignature opcional); limitado por envelope conforme o plano
viewerDocumentAccess booleano Permite que os observadores abram o documento na página de status. Padrão false (só o status); a partir do plano Team
reminders objeto { "enabled": false } desativa os lembretes; { "enabled": true, "intervalHours": 24 } altera o intervalo (de 1 a 720)
externalId string Seu próprio id, com até 200 caracteres
dedupeOn "external_id" Retorna o envelope existente com esse externalId em vez de criar outro
metadata objeto de strings Até 500 caracteres por valor; retornado no envelope e nos webhooks

Todo destinatário precisa de um papel da versão; cada papel que não é CC precisa de exatamente um destinatário. Os erros são informados em conjunto, com ponteiros como /recipients/1/role ou /recipients/0/fields/start_date.

Respostas: 201 com o envelope e um cabeçalho Location; 200 com o envelope existente e x-deduplicated: true quando o dedupeOn encontrou correspondência; 200 com um resumo da simulação para ?dry_run=true; 402 quando um espaço de trabalho Free já usou os envelopes incluídos; 403 plan-upgrade-required quando os observadores excedem o limite do plano ou quando viewerDocumentAccess não faz parte do plano (Planos e limites). As simulações também verificam os limites do plano.

Todo campo adicionado depois da primeira versão é opcional: uma requisição sem eles se comporta exatamente como antes.

O modelo define quem assina e em que ordem. Para um envelope específico, você pode mudar isso sem mexer no modelo:

{
"template": "tpl_9fK2mQ7xLp",
"variables": { "client": { "name": "Jane Doe" } },
"recipients": [
{ "role": "client", "name": "Jane Doe", "email": "jane@acme.dev", "order": 2 },
{ "role": "company", "name": "Sam Lee", "email": "sam@bonafide.dev", "order": 1 },
{ "role": "witness", "name": "Kim Park", "email": "kim@acme.dev", "order": 1 }
],
"cc": [{ "name": "Legal", "email": "legal@acme.dev" }],
"viewers": [{ "name": "Alex Chen", "email": "alex@acme.dev", "notifyOnSignature": true }],
"reminders": { "enabled": true, "intervalHours": 48 },
"expiresAt": "2026-11-30T23:59:59Z"
}
  • Ordem: recipients[].order é a etapa em que o destinatário assina; destinatários com o mesmo número assinam ao mesmo tempo. Sem ele, vale o order do papel no modelo. As ordens são inteiros positivos; papéis CC não podem ser ordenados; todo papel continua precisando do seu destinatário (para que os campos do modelo mantenham o signatário); pelo menos um destinatário precisa assinar. O evento envelope.created registra routingOverridden: true.
  • CC: os destinatários CC extras recebem o e-mail do documento concluído e nunca assinam. Eles aparecem em recipients com kind: "cc" e o papel _cc.
  • Lembretes: quem está na vez recebe um lembrete a cada intervalHours (padrão: o REMINDER_INTERVAL_HOURS da implantação, 72), no máximo três vezes; enabled: false não envia nenhum. Os lembretes valem para a entrega email.
  • A autenticação do signatário é por destinatário: verification substitui o método do papel. none (só o link de assinatura exclusivo, o padrão para papéis que não definem um método) e email_otp (o link mais um código enviado por e-mail) estão disponíveis hoje; passkey e id_check são rejeitados por ainda não estarem disponíveis. Consulte verificação do signatário.
  • Idioma: locale em um destinatário, CC ou observador (ou no envelope, para todos que não têm o seu) define o idioma da página de assinatura e dos e-mails dessa pessoa, um dos 50 idiomas de assinatura. Sem ele, a página de assinatura segue o navegador e os e-mails ficam em inglês.

A tela de envio do painel oferece as mesmas opções: mover etapas para antes ou depois, marcar Assinar ao mesmo tempo, adicionar CCs e observadores, escolher a autenticação (Somente link por e-mail ou Link por e-mail + código) e o idioma de cada signatário e definir uma data de expiração e uma programação de lembretes.

  • email: cada destinatário recebe por e-mail um link para a página de assinatura hospedada quando chega a vez dele. Os destinatários que ainda não assinaram recebem um lembrete a cada poucos dias (até três), e todos recebem um e-mail quando o envelope é concluído.
  • embedded: nenhum e-mail para os signatários. Gere uma sessão de assinatura quando o signatário estiver no seu produto. Os observadores continuam recebendo o link de status por e-mail.
  • none: nenhum e-mail (nem para os observadores); use quando você mesmo entrega os links (sessões hospedadas).

POST /v1/envelopes/{id}/recipients/{recipient}/resend envia por e-mail um link novo a um destinatário que está na vez (no máximo uma vez por minuto).

┌──────────── declined (a signer declined)
│
sent ─────┼──────────── voided (POST /v1/envelopes/{id}/void)
│
├──────────── expired (expiresAt passed)
│
└──────────── completed ──► seal: pending ──► sealed
status Significado
rendering Em preparação
sent Em andamento: os destinatários estão assinando na ordem de roteamento
completed Todos os destinatários terminaram. A selagem começa
declined Um destinatário recusou; o envelope é encerrado
voided Você o anulou ({ "reason": "…" }); as sessões de assinatura abertas deixam de funcionar
expired O expiresAt passou antes da conclusão

seal acompanha o PDF selado: not_started, pending (concluído, em selagem), sealed ou failed. A selagem nunca bloqueia a conclusão: o envelope é concluído primeiro e selado logo em seguida.

{
"id": "rcp_5Jw0pLs9Xe",
"role": "client",
"name": "Jane Doe",
"email": "jane@acme.dev",
"order": 1,
"status": "viewed",
"verification": "email_otp",
"completedAt": null
}

O status do destinatário é pending (ainda não é a vez dele), sent, viewed, completed ou declined, e o kind é o do papel: signer, approver, form_filler ou cc. O roteamento segue o order (o do papel ou a substituição no envio): todos os destinatários da menor ordem não concluída atuam em paralelo, e o grupo seguinte começa quando eles terminam. Destinatários CC nunca bloqueiam o roteamento.

Um observador acompanha um envelope sem assinar: um gestor, um assistente jurídico, o responsável pela conta do lado do cliente. Observadores não são destinatários. Eles não têm papel nem vez, nunca bloqueiam nem concluem nada e nunca aparecem na lista de signatários do certificado.

  • Quando o envelope é enviado (ou quando você os adiciona depois com POST /v1/envelopes/{id}/viewers), cada observador recebe um e-mail com a sua marca e um link para uma página de status somente leitura: o título do envelope, o remetente e cada etapa com nomes, papéis, status e horários dos destinatários, atualizada em tempo real à medida que as pessoas assinam. Os endereços de e-mail dos destinatários não são exibidos.
  • Os observadores recebem um novo e-mail quando o envelope é concluído, recusado ou anulado e, se notifyOnSignature for true (desativado por padrão), depois de cada assinatura.
  • O documento só aparece na página quando você define viewerDocumentAccess: true (a partir do plano Team): o original enquanto está em andamento e o PDF selado depois da selagem. Caso contrário, os observadores veem apenas o status.
  • DELETE /v1/envelopes/{id}/viewers/{viewer} revoga um observador: todos os links enviados a ele deixam de funcionar na hora.
  • Os links são URLs de capacidade pessoais. Só um SHA-256 de cada token de link é armazenado. Um link funciona até o envelope expirar (no máximo 90 dias), por 30 dias depois que o envelope termina e nunca depois que o observador é revogado.
  • Adição, abertura (primeira visualização da página e do documento) e revogação ficam registradas na trilha de auditoria como viewer.added, viewer.viewed, viewer.document_viewed e viewer.revoked e, portanto, também no certificado.

As respostas de envelope individual (criar, obter, anular) os listam:

{
"viewers": [
{
"id": "vwr_2Hc8sQ1nVt",
"name": "Alex Chen",
"email": "alex@acme.dev",
"notifyOnSignature": true,
"status": "active",
"invitedAt": "2026-10-13T13:58:04.512Z",
"firstViewedAt": "2026-10-13T14:05:41.090Z",
"lastViewedAt": "2026-10-13T15:12:09.337Z",
"revokedAt": null,
"createdAt": "2026-10-13T13:58:04.512Z"
}
],
"viewerDocumentAccess": false
}

O número de observadores por envelope depende do plano (Free 1, Pay-as-you-go 2, Team 5, Business 20, Platform ilimitado); destinatários CC não contam. Observadores revogados liberam a vaga.

GET /v1/envelopes/{id}/document?version=… baixa um PDF, com o SHA-256 dele em x-document-sha256:

version Arquivo
original (padrão) O documento renderizado tal como foi enviado para assinatura
sealed O PDF final: valores achatados, certificado de conclusão anexado, carimbo de tempo de documento. Depois de envelope.sealed
certificate Apenas o certificado de conclusão

O documentHash do envelope é o SHA-256 do original, e o sealedDocumentHash, o do arquivo selado; são esses os valores que a verificação consulta.

Cada ação é um evento em uma cadeia de hashes por envelope: hash = SHA-256(prevHash ‖ canonical JSON of the event), sendo o primeiro prevHash composto de 64 zeros. GET /v1/envelopes/{id}/events retorna os eventos e verifica a cadeia:

{
"data": [
{
"id": "evt_…",
"envelope": "env_8Gm2kQ4rT1",
"seq": 1,
"type": "envelope.created",
"createdAt": "2026-10-13T13:58:04.512Z",
"recipient": null,
"actor": { "kind": "api_key", "id": "…", "name": null, "email": null },
"ip": "203.0.113.7",
"userAgent": null,
"data": { "template": "tpl_…", "templateVersion": 3, "documentHash": "9f2c…" },
"hash": "4b1d…",
"prevHash": "0000000000000000000000000000000000000000000000000000000000000000"
}
],
"chain": { "valid": true, "brokenAt": null }
}

Além dos tipos de evento de webhook, a trilha tem entradas exclusivas de auditoria, como session.created, recipient.verified, recipient.reminded e os eventos de observador (tipo de ator viewer quando um observador abre a página dele).

Para status em tempo real em uma interface, GET /v1/envelopes/{id}/events/stream é um fluxo de server-sent events: o nome do evento de cada frame é o type do evento, e o id, o seq; reconecte com Last-Event-ID para retomar.

GET /v1/envelopes filtra por status, seal, template e q (texto livre sobre nomes e e-mails dos destinatários, externalId e o id do envelope). Como toda listagem, é paginada por cursor:

{ "data": [ … ], "hasMore": true, "nextCursor": "…" }

Passe o nextCursor de volta como cursor; limit vai de 1 a 100 (padrão 20).