Pular para o conteúdo

Envelopes e destinatários

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

Campo Tipo Notas
template tpl_… Obrigatório
version número ou "latest" Predefinição latest; resolvida e fixada na criação. Tem de estar publicada
variables objeto Validado com base no JSON Schema da versão
recipients array Um por função (role, name, email; opcionalmente externalUserId, verification, fields para pré-preencher por id de campo e order para alterar a ordem de assinatura)
subject, message string Utilizados nos e-mails de assinatura e mostrados na página de assinatura
delivery email · embedded · none Predefinição email
expiresAt RFC 3339 Tem de estar no futuro; o envelope expira nesse momento e as ligações de assinatura e de observador deixam de funcionar
cc array Destinatários CC adicionais (name, email) para além das funções CC do modelo; até 50
viewers array Pessoas que acompanham o envelope sem assinar (name, email, notifyOnSignature opcional); limitado por envelope consoante o plano
viewerDocumentAccess booleano Permite que os observadores abram o documento na sua página de estado. Predefinição false (só o estado); 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 O seu próprio id, até 200 caracteres
dedupeOn "external_id" Devolve o envelope existente com este externalId em vez de criar outro
metadata objeto de strings Até 500 caracteres por valor; devolvido no envelope e nos webhooks

Cada destinatário precisa de uma função da versão; cada função que não seja CC precisa de exatamente um destinatário. Os erros são comunicados 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á utilizou os envelopes incluídos; 403 plan-upgrade-required quando os observadores excedem o limite do plano ou quando viewerDocumentAccess não está incluído no plano (Planos e limites). As simulações também verificam os limites do plano.

Todos os campos acrescentados depois da primeira versão são opcionais: um pedido sem eles comporta-se exatamente como antes.

O modelo define quem assina e por que ordem. Para um envelope concreto, pode alterar 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 é o passo em que o destinatário assina; os destinatários com o mesmo número assinam em simultâneo. Sem este campo, aplica-se o order da função no modelo. As ordens são números inteiros positivos; as funções CC não podem ser ordenadas; cada função continua a precisar do seu destinatário (para que os campos do modelo mantenham o respetivo signatário); pelo menos um destinatário tem de assinar. O evento envelope.created regista routingOverridden: true.
  • CC: os destinatários CC adicionais recebem o e-mail com o documento concluído e nunca assinam. Aparecem em recipients com kind: "cc" e a função _cc.
  • Lembretes: quem tem a vez recebe um lembrete a cada intervalHours (predefinição: o REMINDER_INTERVAL_HOURS da implementação, 72), no máximo três vezes; enabled: false não envia nenhum. Os lembretes aplicam-se à entrega email.
  • A autenticação do signatário é definida por destinatário: verification substitui o método da função. none (apenas a ligação de assinatura única, a predefinição para funções que não definem um método) e email_otp (a ligação mais um código enviado por e-mail) estão disponíveis atualmente; passkey e id_check são rejeitados por ainda não estarem disponíveis. Consulte verificação do signatário.
  • Idioma: locale num destinatário, CC ou observador (ou no envelope, para todos os que não têm o seu) define o idioma da respetiva página de assinatura e dos e-mails, um dos 50 idiomas de assinatura. Sem este campo, a página de assinatura segue o navegador e os e-mails são enviados em inglês.

O ecrã de envio do painel oferece as mesmas opções: antecipar ou adiar passos, assinalar Assinar em simultâneo, adicionar CC e observadores, escolher a autenticação (Só ligação por e-mail ou Ligação por e-mail + código) e o idioma de cada signatário e definir uma data de expiração e um calendário de lembretes.

  • email: cada destinatário recebe por e-mail uma ligação para a página de assinatura alojada quando chega a sua vez. Os destinatários que ainda não assinaram recebem um lembrete de poucos em poucos dias (até três), e todos recebem um e-mail quando o envelope é concluído.
  • embedded: nenhum e-mail para os signatários. Crie uma sessão de assinatura quando o signatário estiver no seu produto. Os observadores continuam a receber por e-mail a ligação de estado.
  • none: nenhum e-mail (incluindo para os observadores); utilize-o quando é o próprio a entregar as ligações (sessões alojadas).

POST /v1/envelopes/{id}/recipients/{recipient}/resend envia por e-mail uma ligação nova a um destinatário que tem a 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 curso: os destinatários estão a assinar pela ordem de encaminhamento
completed Todos os destinatários terminaram. A selagem começa
declined Um destinatário recusou; o envelope termina
voided Anulou-o ({ "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, a ser selado), sealed ou failed. A selagem nunca bloqueia a conclusão: o envelope é concluído primeiro e selado logo a seguir.

{
"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 sua vez), sent, viewed, completed ou declined, e o kind é o da função: signer, approver, form_filler ou cc. O encaminhamento segue o order (o da função ou a substituição no envio): todos os destinatários da ordem mais baixa por concluir atuam em paralelo, e o grupo seguinte começa quando terminam. Os destinatários CC nunca bloqueiam o encaminhamento.

Um observador acompanha um envelope sem assinar: um gestor, um assistente jurídico, o gestor de conta do lado do cliente. Os observadores não são destinatários. Não têm função nem vez, nunca bloqueiam nem concluem nada e nunca aparecem na lista de signatários do certificado.

  • Quando o envelope é enviado (ou quando os adiciona mais tarde com POST /v1/envelopes/{id}/viewers), cada observador recebe um e-mail com a sua marca e uma ligação para uma página de estado só de leitura: o título do envelope, o remetente e cada passo com os nomes, as funções, o estado e as horas dos respetivos destinatários, atualizada em tempo real à medida que as pessoas assinam. Os endereços de e-mail dos destinatários não são mostrados.
  • Os observadores recebem novo e-mail quando o envelope é concluído, recusado ou anulado e, se notifyOnSignature for true (desativado por predefinição), após cada assinatura.
  • O documento só aparece na página quando define viewerDocumentAccess: true (a partir do plano Team): o original enquanto está em curso e o PDF selado depois de selado. Caso contrário, os observadores só veem o estado.
  • DELETE /v1/envelopes/{id}/viewers/{viewer} revoga um observador: todas as ligações que lhe foram enviadas deixam de funcionar de imediato.
  • As ligações são URL de capacidade pessoais. Só é guardado um SHA-256 de cada token de ligação. Uma ligação funciona até o envelope expirar (no máximo 90 dias), durante 30 dias depois de o envelope terminar e nunca depois de o observador ser revogado.
  • A adição, a abertura (primeira visualização da página e do documento) e a revogação ficam registadas no registo de auditoria como viewer.added, viewer.viewed, viewer.document_viewed e viewer.revoked e, por conseguinte, no certificado.

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

{
"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); os destinatários CC não contam. Os observadores revogados libertam o seu lugar.

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

version Ficheiro
original (predefinição) O documento gerado tal como foi enviado para assinatura
sealed O PDF final: valores aplanados, certificado de conclusão anexado, carimbo temporal de documento. Após envelope.sealed
certificate Apenas o certificado de conclusão

O documentHash do envelope é o SHA-256 do original e o sealedDocumentHash o do ficheiro selado; são estes os valores que a verificação procura.

Cada ação é um evento numa cadeia de hashes por envelope: hash = SHA-256(prevHash ‖ canonical JSON of the event), sendo o primeiro prevHash composto por 64 zeros. GET /v1/envelopes/{id}/events devolve 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, o registo contém 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 sua página).

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

GET /v1/envelopes filtra por status, seal, template e q (texto livre sobre os nomes e e-mails dos destinatários, o externalId e o id do envelope). Como todas as listas, tem paginação por cursor:

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

Volte a passar o nextCursor como cursor; limit vai de 1 a 100 (predefinição 20).