Documentação Guias Webhooks

Webhooks

In English. Register one or more URLs per account and receive a JSON POST for 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 the event you know and discard the rest with a 2xx. There is no signature header and no delivery id: validate the origin with accountId (and a secret in your URL) and treat repeats by the content of entity. 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:// ou https://, 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 responder 200 ou 202 em até 20 segundos; o resultado fica em available. A URL é gravada mesmo quando o teste falha, e o Test nã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_list e remova com partners_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; 200 ou 202 sã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 + signedAt identificam 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

  1. Responda rápido. Grave o payload numa fila e responda 202; processe depois. Assim você fica longe dos 20 segundos mesmo em picos.
  2. Seja idempotente. Guarde uma chave derivada do conteúdo e ignore o que já processou.
  3. Valide a origem. Rejeite (4xx) payloads cujo accountId não seja seu ou cujo segredo na URL não bata.
  4. Reconcilie. Como não há ordem garantida, ao receber DocumentSignatureMember confirme o estado com partners_v1_document_signatures_status antes de decisões irreversíveis.
  5. Registre. Guarde o payload bruto e o instante de recebimento; sem identificador de entrega, é o seu registro que permite investigar.
  6. Monitore available. Se o teste do cadastro falhou, corrija a URL e cadastre de novo (remova a anterior primeiro).
  7. Descarte o que você não trata. Eventos novos podem ser criados. Faça o roteamento pelo event que você conhece, responda 2xx para os demais e descarte-os: um 4xx/5xx num 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"
          }
        ]
      }
    ]
  }
}

Este guia também existe em Markdown, e o conjunto completo da documentação em llms.txt.