Webhooks
In English. Register one or more URLs per account and receive a JSON
POSTfor each event: document sent for signature, signer added, signer signed, all signatures finished, document status changed, document removed, form filled, signatures expired, signatures canceled. Any 2xx within 20 seconds confirms delivery; failures are retried up to 5 times. New events may be added, so route by theeventyou know and discard the rest with a 2xx. There is no signature header and no delivery id: validate the origin withaccountId(and a secret in your URL) and treat repeats by the content ofentity. Text in Brazilian Portuguese.
Webhooks são a forma recomendada de acompanhar documentos: em vez de consultar a situação
repetidamente, sua URL recebe um POST a cada evento da conta.
Cadastro
Cadastre a URL com partners_v1_webhooks_create (exige a feature integrations):
curl -X POST -H "Authorization: SUA_CHAVE" -H "Content-Type: application/json" \
https://api.letssign.com.br/partners/v1/accounts/0199143a-7c2e-7b1a-9f2d-3c4b5a6d7e8f/webhooks \
-d '{ "uri": "https://integracao.exemplo.com.br/letssign/webhook" }'
{
"id": "0199143e-4a5b-7c6d-9e7f-8a9b0c1d2e3f",
"accountId": "0199143a-7c2e-7b1a-9f2d-3c4b5a6d7e8f",
"uri": "https://integracao.exemplo.com.br/letssign/webhook",
"available": true,
"createdAt": "2026-08-20T14:05:00Z"
}
- A URL precisa começar com
http://ouhttps://, ter o host em minúsculas e um TLD de 2 a 5 letras. A mesma URL não pode ser cadastrada duas vezes na conta (400). - No cadastro, um evento
Testé enviado de imediato. Sua URL deve responder200ou202em até 20 segundos; o resultado fica emavailable. A URL é gravada mesmo quando o teste falha, e oTestnão é reenviado depois. - Cada URL cadastrada recebe todos os eventos da conta; não há filtro por evento. Para receber em mais de um sistema, cadastre mais de uma URL.
- Liste com
partners_v1_webhooks_liste remova compartners_v1_webhooks_delete. Depois da remoção, eventos novos deixam de ser enviados àquela URL.
O envelope
Cada entrega é um POST com Content-Type: application/json; charset=utf-8 e este corpo:
| Campo | Tipo | O que traz |
|---|---|---|
event |
string | Nome do evento, que define o formato de entity. |
accountId |
UUID | Conta à qual o evento pertence. Use para validar a origem e rotear. |
occurredAt |
data e hora (UTC) | Instante desta tentativa de envio, não do evento. Muda a cada retentativa. |
entity |
objeto | Os dados do evento. O schema de cada um está no objeto webhooks do documento OpenAPI e na seção de payloads abaixo. |
{
"occurredAt": "2026-08-21T10:12:45Z",
"accountId": "0199143a-7c2e-7b1a-9f2d-3c4b5a6d7e8f",
"event": "DocumentSignatureFinished",
"entity": { "...": "depende do evento" }
}
Os eventos
| Evento | Quando | O que fazer |
|---|---|---|
Test |
Uma vez, no cadastro da URL. entity.test é sempre true. |
Responder 2xx. |
DocumentSentToSignature |
Um documento foi enviado para assinatura: na criação por partners_v1_document_signatures_create_from_file, em partners_v1_documents_request_signatures ou pelo aplicativo. Com envio agendado, sai no momento da criação. |
Guardar entity.signers[].id: é o signatureId para editar, remover e reenviar. |
SignerAddedToDocument |
Um signatário foi adicionado a um documento já em assinatura. | Guardar entity.signer.id. |
DocumentSignatureMember |
Um signatário assinou. Chega uma vez por signatário, com papel, e-mail, nome informado e signedAt. |
Atualizar o andamento. Quando é o último, também chega DocumentSignatureFinished. |
DocumentSignatureFinished |
O último signatário assinou: entity.signatureStatus é Signed. |
Baixar o PDF assinado (partners_v1_documents_download_signed) ou, com certificado digital, partners_v1_documents_download_digital_certificate. |
DocumentStatusChanged |
O status do documento mudou: Finished (conteúdo pronto, em documentos gerados no editor ou por formulário) ou NewVersionBase (o documento virou base de uma nova versão, em entity.newVersionId). |
Acompanhar a nova versão, se houver. |
DocumentRemoved |
O documento foi excluído, pela API ou pelo aplicativo. Ao excluir um envelope, sai uma vez, com o id do envelope. | Encerrar o acompanhamento; operações sobre o documento passam a responder 400. |
FormFilled |
Um formulário criado por partners_v1_forms_create foi preenchido por completo e o documento foi gerado. |
Solicitar as assinaturas com partners_v1_documents_request_signatures. |
DocumentSignaturesExpired |
O prazo de assinatura venceu e as assinaturas foram canceladas pelo processo automático diário. entity.deadlineForSignature é o prazo que venceu. Sai uma vez por envelope, e entity.documents traz só os documentos atingidos. |
Guardar documents[].pendingSigners: quem não assinou deixa de existir depois do cancelamento. Reenviar com partners_v1_documents_request_signatures e um prazo novo, se for o caso. |
DocumentSignaturesCanceled |
As assinaturas foram canceladas a pedido, pela API ou pelo aplicativo. Numa exclusão só chega se o documento estava aguardando assinaturas, e parte das exclusões feitas no aplicativo não o envia. Mesmo formato do evento acima, sem o prazo. | Encerrar o acompanhamento, ou reabrir com partners_v1_documents_request_signatures. |
Contrato de entrega
- Confirmação. Qualquer status 2xx confirma a entrega;
200ou202são os recomendados. O corpo da sua resposta é ignorado. - Tempo limite. 20 segundos. Outro status, tempo esgotado ou erro de rede contam como falha.
- Retentativas. A entrega é repetida em seguida, até 5 tentativas, sem espera progressiva. Depois disso o evento não é reenviado.
- Sem assinatura. Não há cabeçalho de autenticação nem assinatura HMAC no payload. Valide a
origem pelo
accountId(ele precisa ser uma conta sua) e, se quiser uma camada a mais, inclua um segredo na própria URL cadastrada (https://.../webhook?token=...) e confira-o a cada entrega. - Sem identificador de entrega. Trate repetições pelo conteúdo de
entity: por exemplo,event+entity.documentId+entity.signer.id+signedAtidentificam uma assinatura. - Sem garantia de ordem, mesmo entre eventos do mesmo documento. Para saber o estado atual,
consulte
partners_v1_document_signatures_status.
Como tratar no seu lado
- Responda rápido. Grave o payload numa fila e responda
202; processe depois. Assim você fica longe dos 20 segundos mesmo em picos. - Seja idempotente. Guarde uma chave derivada do conteúdo e ignore o que já processou.
- Valide a origem. Rejeite (
4xx) payloads cujoaccountIdnão seja seu ou cujo segredo na URL não bata. - Reconcilie. Como não há ordem garantida, ao receber
DocumentSignatureMemberconfirme o estado compartners_v1_document_signatures_statusantes de decisões irreversíveis. - Registre. Guarde o payload bruto e o instante de recebimento; sem identificador de entrega, é o seu registro que permite investigar.
- Monitore
available. Se o teste do cadastro falhou, corrija a URL e cadastre de novo (remova a anterior primeiro). - Descarte o que você não trata. Eventos novos podem ser criados. Faça o roteamento pelo
eventque você conhece, responda 2xx para os demais e descarte-os: um4xx/5xxnum evento que você não trata só gera retentativa e ruído no seu registro.
Payloads de exemplo
Os exemplos abaixo são os mesmos do objeto webhooks do documento OpenAPI, com o envelope
completo.
Test
Enviado no cadastro de uma URL de webhook, para verificar a disponibilidade.
{
"occurredAt": "2026-08-21T10:12:45Z",
"accountId": "0199143a-7c2e-7b1a-9f2d-3c4b5a6d7e8f",
"event": "Test",
"entity": {
"test": true
}
}
DocumentSentToSignature
Documento enviado para assinatura.
{
"occurredAt": "2026-08-21T10:12:45Z",
"accountId": "0199143a-7c2e-7b1a-9f2d-3c4b5a6d7e8f",
"event": "DocumentSentToSignature",
"entity": {
"documentId": "01991440-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
"sentAt": "2026-08-20T14:05:00Z",
"signers": [
{
"id": "01991441-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"role": "Parte",
"authenticationMethod": "Email",
"email": "maria.silva@exemplo.com.br",
"name": "Maria da Silva"
},
{
"id": "01991441-9f8e-7d6c-8b5a-4c3d2e1f0a9b",
"role": "Testemunha",
"authenticationMethod": "Email",
"email": "joao.souza@exemplo.com.br",
"name": "João de Souza"
}
]
}
}
SignerAddedToDocument
Novo signatário adicionado ao documento.
{
"occurredAt": "2026-08-21T10:12:45Z",
"accountId": "0199143a-7c2e-7b1a-9f2d-3c4b5a6d7e8f",
"event": "SignerAddedToDocument",
"entity": {
"documentId": "01991440-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
"signer": {
"id": "01991441-9f8e-7d6c-8b5a-4c3d2e1f0a9b",
"role": "Testemunha",
"authenticationMethod": "Email",
"email": "joao.souza@exemplo.com.br",
"name": "João de Souza"
}
}
}
DocumentSignatureMember
Signatário assinou o documento.
{
"occurredAt": "2026-08-21T10:12:45Z",
"accountId": "0199143a-7c2e-7b1a-9f2d-3c4b5a6d7e8f",
"event": "DocumentSignatureMember",
"entity": {
"documentId": "01991440-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
"role": "Parte",
"email": "maria.silva@exemplo.com.br",
"name": "Maria da Silva",
"signedAt": "2026-08-21T10:12:45Z"
}
}
DocumentSignatureFinished
Todos signatários assinaram o documento.
{
"occurredAt": "2026-08-21T10:12:45Z",
"accountId": "0199143a-7c2e-7b1a-9f2d-3c4b5a6d7e8f",
"event": "DocumentSignatureFinished",
"entity": {
"id": "01991440-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
"status": "Finished",
"signatureStatus": "Signed"
}
}
DocumentStatusChanged
Documento teve status alterado.
{
"occurredAt": "2026-08-21T10:12:45Z",
"accountId": "0199143a-7c2e-7b1a-9f2d-3c4b5a6d7e8f",
"event": "DocumentStatusChanged",
"entity": {
"status": "NewVersionBase",
"newVersionId": "0199144e-b8c9-7d0e-8f1a-2b3c4d5e6f7a",
"id": "01991440-5a6b-7c8d-9e0f-1a2b3c4d5e6f"
}
}
DocumentRemoved
Documento foi removido.
{
"occurredAt": "2026-08-21T10:12:45Z",
"accountId": "0199143a-7c2e-7b1a-9f2d-3c4b5a6d7e8f",
"event": "DocumentRemoved",
"entity": {
"id": "01991440-5a6b-7c8d-9e0f-1a2b3c4d5e6f"
}
}
FormFilled
Formulário foi preenchido.
{
"occurredAt": "2026-08-21T10:12:45Z",
"accountId": "0199143a-7c2e-7b1a-9f2d-3c4b5a6d7e8f",
"event": "FormFilled",
"entity": {
"formId": "01991443-7d8e-7f9a-8b1c-2d3e4f5a6b7c",
"documentId": "01991440-5a6b-7c8d-9e0f-1a2b3c4d5e6f"
}
}
DocumentSignaturesExpired
Prazo de assinatura do documento venceu.
{
"occurredAt": "2026-08-21T10:12:45Z",
"accountId": "0199143a-7c2e-7b1a-9f2d-3c4b5a6d7e8f",
"event": "DocumentSignaturesExpired",
"entity": {
"deadlineForSignature": "2026-09-08T00:00:00Z",
"id": "01991447-3c4d-7e5f-8a6b-7c8d9e0f1a2b",
"documents": [
{
"id": "01991440-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
"pendingSigners": [
{
"id": "01991441-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"role": "Parte",
"authenticationMethod": "Email",
"email": "maria.silva@exemplo.com.br",
"name": "Maria da Silva"
},
{
"id": "01991441-9f8e-7d6c-8b5a-4c3d2e1f0a9b",
"role": "Testemunha",
"authenticationMethod": "Email",
"email": "joao.souza@exemplo.com.br",
"name": "João de Souza"
}
]
}
]
}
}
DocumentSignaturesCanceled
Assinaturas do documento foram canceladas.
{
"occurredAt": "2026-08-21T10:12:45Z",
"accountId": "0199143a-7c2e-7b1a-9f2d-3c4b5a6d7e8f",
"event": "DocumentSignaturesCanceled",
"entity": {
"id": "01991447-3c4d-7e5f-8a6b-7c8d9e0f1a2b",
"documents": [
{
"id": "01991440-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
"pendingSigners": [
{
"id": "01991441-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"role": "Parte",
"authenticationMethod": "Email",
"email": "maria.silva@exemplo.com.br",
"name": "Maria da Silva"
},
{
"id": "01991441-9f8e-7d6c-8b5a-4c3d2e1f0a9b",
"role": "Testemunha",
"authenticationMethod": "Email",
"email": "joao.souza@exemplo.com.br",
"name": "João de Souza"
}
]
}
]
}
}