O que monitorar numa integração de assinatura (antes que o cliente avise)

Integrações de assinatura falham de um jeito peculiar: quase nunca com um estrondo. O sistema continua respondendo, os painéis continuam verdes, e o que quebrou aparece dias depois pela boca de um cliente — "mandei o contrato semana passada e ninguém recebeu". Isso acontece porque os modos de falha mais comuns aqui não são erros de servidor: são cotas que acabaram, eventos que ninguém consumiu e verificações de identidade reprovadas que voltam com status 200. Este guia lista os sinais que a API já emite para serem observados, quais valem alarme e quais valem apenas um painel.

O ponto de partida: monitorar taxa de erro HTTP não é suficiente numa integração de assinatura, porque as falhas que mais importam não são erros HTTP. Uma verificação de identidade reprovada, uma cota se esgotando e um webhook não consumido produzem, os três, respostas 200.

A falha que não aparece no painel

Comece pela mais importante, porque ela inverte o instinto de quem instrumenta APIs.

POST /v1/transactions/{id}/steps/{stepId}/complete // 200 OK — e a identidade foi REPROVADA { "status": "STARTED", "attempts": 2, "errorCode": "BIOMETRIC_MATCH_FAILED", "errorDetail": "Não foi possível confirmar seu rosto. Tente novamente.", "retryable": true }

O 200 está correto: a requisição foi recebida, processada e respondida. O que falhou foi a verificação dentro dela — e são coisas diferentes, que a API separa de propósito.

A consequência para monitoramento é direta: se o seu painel conta 2xx como sucesso, ele conta reprovações de identidade como assinaturas bem-sucedidas. Uma mudança de limiar, uma base de fotos de referência ruim ou um provedor degradado passariam despercebidos por semanas.

O que instrumentar:

  • Contagem por errorCode. Cada código é um modo de falha distinto e pede conduta distinta — DOCUMENT_QUALITY_LOW se resolve orientando o usuário, BIOMETRIC_MATCH_FAILED não.
  • Taxa de retryable: false. É o momento em que o signatário esgotou as tentativas e ficou sem saída. Deveria ser raro; se não for, algo está mal calibrado.
  • Distribuição de attempts. Se a maioria conclui na segunda ou terceira tentativa, a experiência está ruim antes de a métrica de conclusão acusar.

Cabeçalhos: o que vem de graça em toda resposta

Cabeçalho Para quê Ação
RateLimit-Limit Teto de requisições na janela Painel
RateLimit-Remaining Quanto resta na janela Alarme ao cair abaixo de uma margem
RateLimit-Reset Quando a janela reinicia Usar no backoff
Retry-After (no 429) Segundos a esperar Obedecer, em vez de inventar o intervalo
API-Version Versão que respondeu Registrar em log

Dois comentários. RateLimit-Remaining é o sinal antecipado: alarmar quando ele fica baixo avisa antes do primeiro 429, e um alarme que dispara depois do 429 chega junto com o incidente, não antes.

Registrar API-Version parece inútil até o dia em que salva a investigação. Quando alguém pergunta "isso mudou de comportamento?", ter a versão em cada linha de log transforma uma discussão em uma consulta.

Cota: o aviso que chega antes da recusa

Quotas se esgotam em silêncio até não se esgotarem mais — e aí a recusa acontece diante do cliente final. Existe um aviso antes disso:

{ "eventType": "QUOTA.WARNING", "tenantId": "...", "timestamp": "2026-09-05T11:02:44Z", "data": { /* método, limite, consumo */ } }

Este evento é disparado ao cruzar o percentual de alerta configurado para a conta. Trate-o como alarme, não como log. Ele é literalmente o último aviso antes de as chamadas começarem a ser recusadas, e as cotas são por método — clique, OTP, biometria, checagem governamental — então é possível esgotar uma e ter as outras sobrando.

Vale medir também a razão entre documentos enviados e cota consumida. Se ela subir sem explicação, normalmente há repetição escondida: tentativas de verificação que se acumulam, ou um processo reenviando o que já foi enviado.

Saúde: distinguir "eles" de "nós"

A primeira pergunta de todo incidente é sempre a mesma, e há um jeito de respondê-la sem autenticação:

GET https://api.signdocs.com.br/health // 200 → componentes internos operacionais // 503 → algum componente indisponível GET https://api.signdocs.com.br/health/history // métricas históricas de disponibilidade e incidentes

Vale uma sondagem periódica de baixa frequência, e vale principalmente consultar isso automaticamente quando a sua taxa de erro sobe. Um alerta que já chega dizendo "a API respondeu 503 no health" economiza o primeiro quarto de hora de toda investigação.

Cuidado com o excesso: sondar a saúde a cada segundo consome o seu próprio limite de requisições sem melhorar a detecção.

Webhooks: o assinante que parou de escutar

Webhooks introduzem um modo de falha que não aparece em lugar nenhum: o seu endpoint parou de processar e a API continua entregando normalmente. Do lado dela, tudo certo; do seu, contratos assinados que ninguém registrou.

O mínimo a assinar:

Evento Por quê
TRANSACTION.COMPLETED Desfecho positivo
ENVELOPE.ALL_SIGNED Desfecho de envelope — não confunda com o anterior
TRANSACTION.FAILED · TRANSACTION.EXPIRED Desfechos negativos, que costumam ficar sem tratamento
TRANSACTION.DEADLINE_APPROACHING Gancho para lembrar o signatário antes de o prazo acabar
QUOTA.WARNING Como acima
ENROLLMENT.EXPIRING · ENROLLMENT.EXPIRED Só se usar biometria — cadastro vencendo

E do seu lado, três medidas: a idade do último evento recebido (silêncio prolongado é suspeito num fluxo que costuma ter tráfego), a taxa de erro do seu próprio manipulador, e uma reconciliação periódica — listar transações concluídas na API e comparar com o que o seu banco registrou. A reconciliação é o que pega o buraco que o monitoramento de webhook, por definição, não pega. O desenho de fila e reprocessamento está em webhooks em fila.

A métrica que vale mais que todas

Se for para instrumentar uma coisa só, que seja esta: taxa de conclusão por janela de tempo — de cada 100 documentos enviados, quantos foram assinados em 24 h, em 72 h, dentro do prazo configurado.

Ela é a única métrica que capta, de uma vez, uma lista de problemas que não produzem erro algum na sua aplicação:

  • e-mail de convite indo para spam;
  • prazo configurado curto demais para o seu público;
  • verificação exigente demais para a base de referência que você tem;
  • página de assinatura com problema em algum navegador;
  • link chegando por um canal que o destinatário não lê.

Nenhum desses gera exceção, 4xx ou 5xx. Todos derrubam a taxa de conclusão. Segmente por perfil de verificação e por canal de entrega: é a segmentação que aponta a causa.

Um conjunto inicial de alarmes

Alarme Sugestão de gatilho
Cota em nível de aviso Qualquer QUOTA.WARNING
Requisições recusadas por limite Qualquer 429 sustentado
Reprovação de identidade acima do normal Taxa de errorCode acima da linha de base
Signatários sem saída retryable: false acima do esperado
Silêncio de webhook Nenhum evento por um período incomum para o seu volume
Divergência de reconciliação Concluídas na API sem registro no seu banco
Queda de conclusão Taxa abaixo da linha de base do período
API indisponível /health em 503

Note o que ficou de fora. Expiração de token não é alarme — o token dura 900 segundos e renová-lo é rotina; um pico de 401 após ociosidade aponta para um token guardado além da validade, que é defeito de implementação. E sessão expirada não é incidente: gente deixa de assinar, e isso é um dado de negócio, não uma falha técnica.

Para os códigos e o formato dos erros, veja códigos de erro e tratamento de falhas; para limites e backoff, rate limits, paginação e idempotência; e para os prazos que definem o que é "dentro da janela", todos os prazos da API.

Perguntas Frequentes

Qual é a falha mais fácil de não perceber?

Uma verificação de identidade reprovada. A requisição volta 200, com a sessão ainda ativa e o motivo em errorCode — porque a requisição de fato foi processada; o que falhou foi a verificação dentro dela. Uma integração que só observa o status HTTP conta essa reprovação como sucesso e nunca a vê num painel.

Que cabeçalhos a API devolve para monitoramento?

RateLimit-Limit, RateLimit-Remaining e RateLimit-Reset nas respostas, e Retry-After quando devolve 429. Há também API-Version em toda resposta — registrá-lo é o que permite correlacionar uma mudança de comportamento com uma mudança de versão, em vez de investigar às cegas.

Como fico sabendo que a cota está acabando?

Pelo evento QUOTA.WARNING, emitido ao cruzar o percentual de alerta configurado para a conta. Ele é o único aviso antes da recusa e merece tratamento de alarme, não de log: quando as chamadas passam a ser recusadas por cota, o problema já chegou ao cliente final.

A API tem verificação de saúde pública?

Sim, e sem autenticação: GET /health devolve 200 quando todos os componentes internos estão operacionais e 503 quando algum não está. Há também GET /health/history com métricas históricas de disponibilidade. Servem para distinguir "a API está fora" de "a minha integração quebrou" — a primeira pergunta de todo incidente.

Quais eventos de webhook devo assinar no mínimo?

Os de desfecho — TRANSACTION.COMPLETED, TRANSACTION.FAILED, TRANSACTION.EXPIRED, ENVELOPE.ALL_SIGNED — mais TRANSACTION.DEADLINE_APPROACHING, que avisa antes de o prazo acabar e permite lembrar o signatário, e QUOTA.WARNING. Se usar biometria, acrescente ENROLLMENT.EXPIRING e ENROLLMENT.EXPIRED.

Qual métrica de negócio revela problema mais cedo?

A taxa de conclusão por janela de tempo. Documentos enviados que não foram assinados dentro do prazo esperado é o indicador que capta, de uma vez, e-mail que não chega, link que expira cedo demais, verificação exigente demais e página que não carrega — nenhum dos quais gera erro na sua aplicação.

Preciso monitorar a expiração do token?

Não como alarme, mas trate-a corretamente: o token dura 900 segundos. Um pico de 401 logo após uma janela ociosa costuma indicar token guardado além da validade — é um defeito de implementação, não um incidente da API.

Instrumente antes de precisar

Cabeçalhos de limite em toda resposta, eventos de aviso de cota e verificação de saúde pública. Os sinais já existem — só precisam ser lidos. Teste a instrumentação no sandbox gratuito.

Criar credenciais de homologação Fale com o time comercial