Gere contratos de trabalho automaticamente a partir dos dados do colaborador — planilha, ATS ou ERP de folha — e colete as assinaturas da empresa e do colaborador em minutos, com validade jurídica fundada na MP 2.200-2/2001 (art. 10, §2º), tratamento de dados alinhado à LGPD e um pacote de evidências assinado com certificado ICP-Brasil ao final. O resultado de negócio: admissões, aditivos contratuais e acordos de home office deixam de esperar impressão, coleta presencial e digitalização — o Departamento Pessoal dispara o documento pelo sistema que já usa e arquiva o contrato assinado com trilha de auditoria completa.
Público-alvo: desenvolvedores e equipes de tecnologia que atendem RH/Departamento Pessoal — integrando ERP de folha, ATS ou até uma planilha — e fornecedores de software de gestão de pessoas que querem embutir assinatura eletrônica no próprio produto.
✅ Este guia ≠ onboarding de RH — o guia Onboarding de RH cobre a jornada de admissão completa (múltiplos documentos, etapas e áreas envolvidas). Este guia foca na automação do documento contrato em si: dados do colaborador → template → PDF → assinatura de duas partes → evidência arquivada. O mesmo fluxo serve para aditivos contratuais (reajuste, mudança de cargo) e acordos de home office / teletrabalho — só muda o template.
SIGNDOCS_CLIENT_ID / SIGNDOCS_CLIENT_SECRET.SEQUENTIAL com totalSigners: 2 via POST /v1/envelopes, enviando o PDF em base64.CLICK_PLUS_OTP e entregue os links de assinatura.ENVELOPE.ALL_SIGNED, baixe o PDF com carimbo combinado e o pacote de evidências — contrato assinado e arquivado.Na maioria das empresas, o contrato de trabalho ainda nasce de um copiar-e-colar: alguém do DP abre o último contrato no Word, troca nome, CPF, cargo e salário na mão, imprime duas vias e corre atrás das assinaturas. Cada admissão consome tempo de gente qualificada em trabalho mecânico, e cada campo digitado à mão é uma chance de erro — um salário trocado ou um CPF errado num contrato assinado é retrabalho jurídico, não só administrativo. Quando o colaborador é remoto, some-se o custo de motoboy, correio ou uma primeira semana de trabalho sem contrato formalizado.
O problema se multiplica fora da admissão. Um reajuste coletivo ou uma política nova de home office pode significar centenas de aditivos contratuais de uma vez — todos com a mesma estrutura, mudando apenas os dados de cada colaborador. Fazer isso à mão não escala; é exatamente o caso de gerar contrato de trabalho automaticamente a partir dos dados que já existem — e de formalizar cada aditivo contratual online, sem papel.
O fluxo deste guia automatiza as duas pontas: os dados que já existem na folha, no ATS ou numa planilha alimentam um template e viram PDF sem digitação; a API da SignDocs coleta as assinaturas da empresa e do colaborador em ordem — assinatura eletrônica CLT com verificação de identidade por e-mail (OTP); e ao final você recebe o PDF carimbado com todas as assinaturas mais um pacote de evidências verificável — hash SHA-256 do documento, trilha de auditoria e timestamp ISO do servidor, tudo assinado com certificado ICP-Brasil — pronto para arquivar no dossiê do colaborador.
Folha / ATS / Planilha
│ dados do colaborador (nome, CPF, cargo, salário...)
▼
Motor de template ──> contrato.pdf (base64)
│
▼
POST /v1/envelopes (SEQUENTIAL, totalSigners: 2)
│
├── POST /v1/envelopes/{id}/sessions signerIndex: 1 → empresa
└── POST /v1/envelopes/{id}/sessions signerIndex: 2 → colaborador
│
Empresa assina ──> Colaborador assina
│
Webhook ENVELOPE.ALL_SIGNED
│
├── POST /v1/envelopes/{id}/combined-stamp ──> PDF final
└── GET /v1/transactions/{txId}/evidence ──> pacote .p7m
│
▼
Arquivo no dossiê do colaborador (seu storage)
| Primitiva | Serve para este cenário? |
|---|---|
Envelope (POST /v1/envelopes) |
✅ Sim. Contrato de trabalho tem duas partes assinando o mesmo documento — exatamente o que o envelope modela. SEQUENTIAL garante que o colaborador assina a versão já firmada pela empresa. |
Sessão de assinatura (POST /v1/signing-sessions) |
Não — é para 1 signatário sobre 1 documento. Útil em declarações unilaterais do colaborador, não no contrato bilateral. |
Sessão de confiança (POST /v1/trust-sessions) |
Não — autentica uma ação sem documento (aprovação, consentimento, KYC). Não produz documento assinado. |
Por que SEQUENTIAL e não PARALLEL? Em contrato de trabalho a praxe é a empresa formalizar primeiro e o colaborador aderir ao texto já firmado. O modo sequencial impõe essa ordem: a sessão do colaborador (signerIndex: 2) só fica disponível depois que a da empresa (signerIndex: 1) concluir. Se a ordem não importa no seu processo, PARALLEL também funciona sem nenhuma outra mudança no código.
transactions:read transactions:write steps:write evidence:read webhooks:write.npm install @signdocs-brasil/api (TypeScript) ou pip install signdocs-brasil (Python). Para Go, Java, PHP e C#, veja o guia de autenticação dos SDKs e o guia de envelopes dos SDKs.Variáveis de ambiente usadas nos exemplos:
export SIGNDOCS_CLIENT_ID="your_client_id"
export SIGNDOCS_CLIENT_SECRET="your_client_secret"
export SIGNDOCS_BASE_URL="https://api-hml.signdocs.com.br" # HML
# export SIGNDOCS_BASE_URL="https://api.signdocs.com.br" # Produção
🟠 HML vs Produção — desenvolva sempre em HML (
api-hml.signdocs.com.br, com hífen). Credenciais HML não consomem cota do plano, os dados expiram em 7 dias e o código OTP vem no camposandbox.otpCodeda resposta — você testa o fluxo inteiro sem enviar e-mail a ninguém.
A etapa de geração é deliberadamente agnóstica: a API recebe um PDF pronto e não impõe como você o produz. Qualquer abordagem de template com placeholders funciona — Google Docs API (copiar um template e usar batchUpdate com replaceAllText, depois exportar como PDF), docx-templates ou docxtpl para preencher um .docx e converter, motores de template dedicados como Carbone, ou renderização de HTML para PDF com Puppeteer/Gotenberg. O que importa é o contrato de saída: um PDF de até 10 MB, com os dados do colaborador (nome, CPF, cargo, remuneração, jornada, data de admissão) já mesclados a partir da fonte que sua empresa usa — a mesma linha da planilha, o mesmo registro do ATS ou da folha que hoje alguém copia à mão. Se o processo é no-code, o template n8n da seção "Caminho sem código" já faz a mescla via Google Docs.
✅ Dica — inclua no rodapé do template um identificador seu (ex.: matrícula + versão do template). Ele reaparece no PDF assinado e facilita conciliar o documento com o registro na folha. Os mesmos dados vão também no
metadatado envelope (seção 6), que volta em todos os webhooks.
A API usa OAuth2 client_credentials: troque client_id + client_secret por um access_token em POST /oauth2/token.
ACCESS_TOKEN=$(curl -s -X POST "$SIGNDOCS_BASE_URL/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=$SIGNDOCS_CLIENT_ID&client_secret=$SIGNDOCS_CLIENT_SECRET" \
| jq -r '.access_token')
Com os SDKs, a autenticação (e a renovação do token) é automática — basta inicializar o cliente:
import { SignDocsBrasilClient } from '@signdocs-brasil/api';
const client = new SignDocsBrasilClient({
clientId: process.env.SIGNDOCS_CLIENT_ID!,
clientSecret: process.env.SIGNDOCS_CLIENT_SECRET!,
baseUrl: process.env.SIGNDOCS_BASE_URL,
});
import os
from signdocs_brasil import SignDocsBrasilClient, ClientConfig
client = SignDocsBrasilClient(ClientConfig(
client_id=os.environ['SIGNDOCS_CLIENT_ID'],
client_secret=os.environ['SIGNDOCS_CLIENT_SECRET'],
base_url=os.environ.get('SIGNDOCS_BASE_URL', 'https://api-hml.signdocs.com.br'),
))
O envelope carrega o documento (inline, em base64), o modo de assinatura e os metadados de negócio. Use metadata para amarrar o envelope ao registro do colaborador no seu sistema — esses pares chave-valor voltam nos webhooks e nas consultas. expiresInMinutes: 4320 dá 72 horas para as duas assinaturas.
PDF_BASE64=$(base64 -w0 contrato-trabalho.pdf)
curl -s -X POST "$SIGNDOCS_BASE_URL/v1/envelopes" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d @- <<EOF
{
"signingMode": "SEQUENTIAL",
"totalSigners": 2,
"document": { "content": "$PDF_BASE64", "filename": "contrato-trabalho-maria-souza.pdf" },
"metadata": {
"tipoDocumento": "contrato-trabalho",
"matricula": "4812",
"cargo": "Analista de Dados",
"origem": "folha-erp"
},
"locale": "pt-BR",
"expiresInMinutes": 4320,
"owner": { "email": "dp@suaempresa.com.br", "name": "Departamento Pessoal" }
}
EOF
A resposta traz envelopeId, o documentHash (SHA-256 do PDF enviado) e expiresAt. Guarde o envelopeId junto ao registro do colaborador.
Sobre o campo owner: quando informado, a SignDocs envia automaticamente o e-mail de convite a cada signatário cujo signer.email seja diferente de owner.email, e notifica o solicitante a cada assinatura concluída. Se você omitir owner, nenhum e-mail é enviado pela SignDocs — seu sistema entrega os links por conta própria (seção 7).
import { readFileSync } from 'fs';
const pdfBase64 = readFileSync('contrato-trabalho.pdf').toString('base64');
const envelope = await client.envelopes.create({
signingMode: 'SEQUENTIAL',
totalSigners: 2,
document: { content: pdfBase64, filename: 'contrato-trabalho-maria-souza.pdf' },
metadata: {
tipoDocumento: 'contrato-trabalho',
matricula: '4812',
cargo: 'Analista de Dados',
origem: 'folha-erp',
},
locale: 'pt-BR',
expiresInMinutes: 4320,
});
console.log('Envelope ID:', envelope.envelopeId);
import base64
from signdocs_brasil.models import CreateEnvelopeRequest
with open('contrato-trabalho.pdf', 'rb') as f:
pdf_base64 = base64.b64encode(f.read()).decode()
envelope = client.envelopes.create(CreateEnvelopeRequest(
signing_mode='SEQUENTIAL',
total_signers=2,
document_content=pdf_base64,
document_filename='contrato-trabalho-maria-souza.pdf',
metadata={
'tipoDocumento': 'contrato-trabalho',
'matricula': '4812',
'cargo': 'Analista de Dados',
'origem': 'folha-erp',
},
locale='pt-BR',
expires_in_minutes=4320,
))
print('Envelope ID:', envelope.envelope_id)
Duas sessões: signerIndex: 1 para o representante legal da empresa, signerIndex: 2 para o colaborador. Com o modo SEQUENTIAL, o link do colaborador só libera a assinatura depois que a empresa concluir. O perfil CLICK_PLUS_OTP exige signer.email (o código OTP é enviado por e-mail), e cada signatário precisa de cpf ou cnpj.
ENVELOPE_ID="env_01JXYZ..." # da resposta anterior
# Signatário 1 — representante da empresa
curl -s -X POST "$SIGNDOCS_BASE_URL/v1/envelopes/$ENVELOPE_ID/sessions" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"signer": { "name": "Carlos Pereira", "cpf": "11122233344", "email": "carlos.pereira@suaempresa.com.br", "userExternalId": "rep-legal-001" },
"policy": { "profile": "CLICK_PLUS_OTP" },
"purpose": "DOCUMENT_SIGNATURE",
"signerIndex": 1
}'
# Signatário 2 — colaborador
curl -s -X POST "$SIGNDOCS_BASE_URL/v1/envelopes/$ENVELOPE_ID/sessions" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"signer": { "name": "Maria Souza", "cpf": "98765432100", "email": "maria.souza@gmail.com", "userExternalId": "matricula-4812" },
"policy": { "profile": "CLICK_PLUS_OTP" },
"purpose": "DOCUMENT_SIGNATURE",
"signerIndex": 2
}'
Cada resposta traz url e clientSecret. O link entregue ao signatário é a combinação dos dois: url + ?cs= + clientSecret. O clientSecret é de uso único — guarde apenas até a entrega.
// Signatário 1 — representante da empresa (assina primeiro)
const empresa = await client.envelopes.addSession(envelope.envelopeId, {
signer: { name: 'Carlos Pereira', cpf: '11122233344', email: 'carlos.pereira@suaempresa.com.br', userExternalId: 'rep-legal-001' },
policy: { profile: 'CLICK_PLUS_OTP' },
purpose: 'DOCUMENT_SIGNATURE',
signerIndex: 1,
});
// Signatário 2 — colaborador (assina após a empresa)
const colaborador = await client.envelopes.addSession(envelope.envelopeId, {
signer: { name: 'Maria Souza', cpf: '98765432100', email: 'maria.souza@gmail.com', userExternalId: 'matricula-4812' },
policy: { profile: 'CLICK_PLUS_OTP' },
purpose: 'DOCUMENT_SIGNATURE',
signerIndex: 2,
});
console.log('Link empresa:', `${empresa.url}?cs=${empresa.clientSecret}`);
console.log('Link colaborador:', `${colaborador.url}?cs=${colaborador.clientSecret}`);
from signdocs_brasil.models import AddEnvelopeSessionRequest
# Signatário 1 — representante da empresa (assina primeiro)
empresa = client.envelopes.add_session(envelope.envelope_id, AddEnvelopeSessionRequest(
signer_name='Carlos Pereira',
signer_cpf='11122233344',
signer_email='carlos.pereira@suaempresa.com.br',
signer_user_external_id='rep-legal-001',
policy_profile='CLICK_PLUS_OTP',
purpose='DOCUMENT_SIGNATURE',
signer_index=1,
))
# Signatário 2 — colaborador (assina após a empresa)
colaborador = client.envelopes.add_session(envelope.envelope_id, AddEnvelopeSessionRequest(
signer_name='Maria Souza',
signer_cpf='98765432100',
signer_email='maria.souza@gmail.com',
signer_user_external_id='matricula-4812',
policy_profile='CLICK_PLUS_OTP',
purpose='DOCUMENT_SIGNATURE',
signer_index=2,
))
print('Link empresa:', f'{empresa.url}?cs={empresa.client_secret}')
print('Link colaborador:', f'{colaborador.url}?cs={colaborador.client_secret}')
Como entregar os links: se você criou o envelope com owner (como no cURL da seção 6), a SignDocs já enviou o convite por e-mail a cada signatário — a resposta indica isso no campo inviteSent. Sem owner, entregue você mesmo: e-mail transacional do seu sistema, portal do colaborador, ou mensagem por WhatsApp/Telegram enviada pela sua própria automação (o WhatsApp é canal de entrega do link — veja o guia n8n).
Consulte o envelope a qualquer momento (útil para exibir o progresso no seu painel de DP):
curl -s "$SIGNDOCS_BASE_URL/v1/envelopes/$ENVELOPE_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN"
A resposta lista as sessões com signerIndex, signerName e status, além de completedSessions/totalSigners. Quando todas concluírem (prefira o webhook ENVELOPE.ALL_SIGNED a polling — próxima seção), gere o carimbo combinado — o PDF final com as assinaturas das duas partes — e baixe o pacote de evidências de cada sessão:
# PDF final com todas as assinaturas
DOWNLOAD_URL=$(curl -s -X POST "$SIGNDOCS_BASE_URL/v1/envelopes/$ENVELOPE_ID/combined-stamp" \
-H "Authorization: Bearer $ACCESS_TOKEN" | jq -r '.downloadUrl')
curl -s -o contrato-assinado.pdf "$DOWNLOAD_URL"
# Pacote de evidências (.p7m) de uma sessão — use o transactionId da sessão
curl -s "$SIGNDOCS_BASE_URL/v1/transactions/$TRANSACTION_ID/evidence" \
-H "Authorization: Bearer $ACCESS_TOKEN"
import { writeFileSync } from 'fs';
// 1. Consultar o envelope
const detail = await client.envelopes.get(envelope.envelopeId);
console.log(`Progresso: ${detail.completedSessions}/${detail.totalSigners}`);
// 2. Após ENVELOPE.ALL_SIGNED: baixar o PDF com carimbo combinado
const stamp = await client.envelopes.combinedStamp(envelope.envelopeId);
const res = await fetch(stamp.downloadUrl);
writeFileSync('contrato-assinado.pdf', Buffer.from(await res.arrayBuffer()));
console.log('Assinaturas no carimbo:', stamp.signerCount);
from pathlib import Path
import httpx
# 1. Consultar o envelope
detail = client.envelopes.get(envelope.envelope_id)
print(f'Progresso: {detail.completed_sessions}/{detail.total_signers}')
# 2. Após ENVELOPE.ALL_SIGNED: baixar o PDF com carimbo combinado
stamp = client.envelopes.combined_stamp(envelope.envelope_id)
Path('contrato-assinado.pdf').write_bytes(httpx.get(stamp.download_url).content)
print('Assinaturas no carimbo:', stamp.signer_count)
O pacote de evidências é um JSON assinado em PKCS#7/CMS (.p7m) com certificado ICP-Brasil A1, contendo a trilha de auditoria, o hash SHA-256 do documento e os timestamps ISO do servidor. Qualquer pessoa (o colaborador, um auditor, a Justiça do Trabalho) pode verificar a evidência sem credenciais via GET /v1/verify/{evidenceId} — e GET /v1/verify/{evidenceId}/downloads fornece os artefatos (.p7m, PDF assinado, PDF com carimbo visual). Arquive contrato-assinado.pdf + o .p7m no dossiê do colaborador; o evidenceId de cada sessão chega no webhook e na consulta do envelope.
Em produção, não faça polling — registre um webhook e reaja ao evento:
curl -s -X POST "$SIGNDOCS_BASE_URL/v1/webhooks" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://seu-sistema.com.br/webhooks/signdocs",
"events": ["ENVELOPE.ALL_SIGNED", "SIGNING_SESSION.COMPLETED", "SIGNING_SESSION.EXPIRED"]
}'
| Evento | Quando usar neste cenário |
|---|---|
ENVELOPE.ALL_SIGNED |
O gatilho principal: as duas partes assinaram. Gere o carimbo combinado, baixe a evidência, marque a admissão/aditivo como formalizado na folha. |
SIGNING_SESSION.COMPLETED |
Cada assinatura individual — ex.: avisar o DP que a empresa assinou e o link do colaborador foi liberado. |
SIGNING_SESSION.EXPIRED |
O prazo de 72h venceu sem assinatura — dispare um reenvio (novo envelope) ou um follow-up humano. |
O registro retorna um secret; todo payload chega assinado com HMAC-SHA256 e você deve validar a assinatura antes de processar. Especificação completa, headers e código de validação no guia de webhooks.
| Perfil | Como o signatário prova identidade | Quando usar em contrato de trabalho |
|---|---|---|
CLICK_ONLY |
Visualiza e aceita com um clique | Comunicados internos; fraco para o contrato em si, pois não verifica posse do e-mail. |
CLICK_PLUS_OTP |
Aceite + código de uso único enviado ao e-mail | ✅ Recomendado. Verifica posse do e-mail informado na admissão, sem atrito de câmera — o colaborador assina do celular em 1 minuto. |
BIOMETRIC |
Verificação facial com prova de vida (exige signer.cpf) |
Populações com risco maior de repúdio ou admissão 100% remota sem contato prévio; adiciona atrito de câmera. |
DIGITAL_CERTIFICATE |
Assinatura com certificado digital ICP-Brasil do signatário | Quando a política interna exige ICP-Brasil das duas partes; raro em CLT, pois poucos colaboradores têm certificado. |
Default recomendado: CLICK_PLUS_OTP para os dois signatários — equilibra robustez probatória (posse do e-mail + trilha de auditoria + hash do documento) e taxa de conclusão. Você pode misturar perfis no mesmo envelope (ex.: DIGITAL_CERTIFICATE para a empresa e CLICK_PLUS_OTP para o colaborador). Comparativo completo dos níveis de robustez jurídica em Perfis de assinatura e níveis legais.
ENVELOPE.ALL_SIGNED — veja Integração Make.1. Signatário sem CPF/CNPJ
{ "type": "https://api.signdocs.com.br/errors/validation", "title": "Unprocessable Entity", "status": 422, "detail": "Missing required field: signer.cpf" }
Toda sessão de envelope exige signer.cpf (11 dígitos, sem pontuação) ou signer.cnpj (14 dígitos). Puxe o CPF da mesma fonte de dados que alimenta o template — nunca digite.
2. Perfil OTP sem e-mail
{ "type": "https://api.signdocs.com.br/errors/validation", "title": "Unprocessable Entity", "status": 422, "detail": "Missing required field: signer.email" }
CLICK_PLUS_OTP envia o código por e-mail: inclua signer.email, ou use otpChannel: "sms" com signer.phone em formato E.164 (+5511988887777).
3. PDF grande demais
{ "type": "https://api.signdocs.com.br/errors/bad-request", "title": "Bad Request", "status": 400, "detail": "Document exceeds maximum size of 10 MB" }
Contratos gerados de template raramente passam de 1 MB — se passou, o motor de template está embutindo imagens sem compressão. Comprima o PDF antes do base64.
4. Carimbo combinado antes da hora
{ "type": "https://api.signdocs.com.br/errors/conflict", "title": "Conflict", "status": 409, "detail": "Envelope is not completed" }
POST /v1/envelopes/{id}/combined-stamp só funciona após todas as sessões concluírem. Chame-o do handler do webhook ENVELOPE.ALL_SIGNED, não logo após criar as sessões.
5. 401 ao criar o envelope
{ "type": "https://api.signdocs.com.br/errors/unauthorized", "title": "Unauthorized", "status": 401, "detail": "Invalid or expired access token" }
O token expira — trate 401 renovando via POST /oauth2/token e repetindo a chamada (os SDKs fazem isso sozinhos). Confira também se não está usando credenciais HML contra a URL de produção.
Referência completa na documentação da API.
Sim. A assinatura eletrônica tem validade fundada na MP 2.200-2/2001, art. 10, §2º — as partes admitem como válido o meio de comprovação acordado. O pacote de evidências da SignDocs (trilha de auditoria, hash SHA-256, timestamps do servidor, tudo assinado com certificado ICP-Brasil) documenta quem assinou, o quê e quando. Os níveis de robustez de cada perfil estão em Perfis de assinatura e níveis legais.
Não como regra geral — perfis eletrônicos como CLICK_PLUS_OTP atendem o contrato de trabalho típico, e exigir certificado do colaborador inviabilizaria a maioria das admissões. Se a sua política interna ou o seu jurídico exigirem ICP-Brasil, use o perfil DIGITAL_CERTIFICATE (ao menos para o representante da empresa). Detalhes em Perfis de assinatura e níveis legais.
O eSocial recebe os eventos de admissão prestados pelo empregador; o contrato assinado não é transmitido por ele — permanece como documento comprobatório que o empregador deve guardar. Arquive o PDF com carimbo combinado e o pacote de evidências (.p7m) no dossiê do colaborador, prontos para fiscalização ou reclamatória. Para prazos de guarda e enquadramentos específicos, consulte seu jurídico ou contabilidade.
Sim — é o mesmo envelope de duas partes; só muda o template que gera o PDF. Use metadata.tipoDocumento (contrato-trabalho, aditivo-salarial, acordo-home-office) para distinguir os documentos nos webhooks e no seu arquivo. Para reajustes coletivos, itere sobre a lista de colaboradores criando um envelope por aditivo.
Neste guia, a empresa (signerIndex: 1) assina primeiro e o colaborador (signerIndex: 2) adere ao texto já firmado — o modo SEQUENTIAL impõe essa ordem automaticamente. Se a ordem for indiferente no seu processo, troque para signingMode: "PARALLEL" e os dois links ficam ativos ao mesmo tempo.
O envelope expira conforme expiresInMinutes (72h nos exemplos) e você recebe o webhook SIGNING_SESSION.EXPIRED. Links expirados não podem ser reativados: gere um novo envelope com o mesmo PDF e reenvie — como a geração é automática, o reenvio é uma chamada de função, não retrabalho manual.