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.
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_LOWse resolve orientando o usuário,BIOMETRIC_MATCH_FAILEDnã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:
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:
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