Erro 401: "Embed token has been consumed" e os outros cinco

Um 401 na API de assinatura raramente significa o que parece. Antes de desconfiar da credencial, vale ler a mensagem: existem seis mensagens distintas ligadas ao token de embed — o token do signatário, diferente do token da sua aplicação — e cada uma tem uma causa e uma correção próprias. A mais comum de todas nem é um token com problema: é uma rota que só aceita o token do signatário, chamada com o Bearer do integrador. Este guia traz as seis, o que fazer em cada caso, e como reemitir um link de assinatura sem recriar nada nem gastar cota.

Resposta rápida: se a mensagem fala em embed token, o problema é o token do signatário, não a sua credencial. E se a credencial está certa e a mensagem não menciona embed token, provavelmente você chamou com Bearer uma rota que só aceita o token do signatário.

As seis mensagens

Mensagem Causa Correção
Embed token has been consumed O link já foi usado — ele é de uso único Emitir um link novo para a mesma sessão
Embed token has expired O prazo da sessão acabou Criar uma sessão nova — reemitir não estende
Embed token load limit exceeded O link foi carregado vezes demais Emitir um link novo
Embed token not found O token não existe Conferir se a URL chegou inteira
Invalid embed token O token não é válido Idem — link truncado é a causa usual
Embed token missing required claims O token está malformado Não montar a URL à mão; usar a que a API devolve

O caso mais comum: consumed

O link de assinatura vale uma vez. Depois que a pessoa conclui — ou que o token embutido é consumido de outra forma — reabrir a mesma URL devolve:

HTTP/1.1 401 Embed token has been consumed

Isso soa como defeito e é o comportamento correto. Um link reutilizável seria uma credencial permanente circulando por e-mail, capaz de reabrir a sessão de assinatura de outra pessoa. O uso único é o que impede isso.

O efeito colateral é real, porém, e não é culpa de ninguém: a pessoa fecha a aba sem querer, o e-mail é encaminhado e alguém abre antes, o aplicativo de mensagens pré-carrega o endereço para gerar a pré-visualização. Nenhuma dessas situações deveria custar uma transação nova — e não custa:

POST /v1/signing-sessions/{sessionId}/link Authorization: Bearer <access_token> // 200 — URL nova, sem recriar nada { "sessionId": "ss_01J...", "url": "https://sign.signdocs.com.br/s/ss_01J...?cs=...", "expiresAt": "2026-09-12T10:14:02Z" }

Três propriedades que respondem às dúvidas previsíveis: não consome cota (reemitir não é enviar de novo), não estende o prazo (o expiresAt é o da sessão original), e só funciona em sessão ativa — uma concluída ou cancelada devolve 409, o que faz sentido, já que um link para uma sessão encerrada não autenticaria nada.

O 401 que não é sobre token: rota errada

Este é o caso que mais consome tempo, porque a mensagem não menciona embed token e a credencial está perfeita.

A API tem duas credenciais com públicos diferentes: o Bearer representa a sua aplicação; o token de embed representa a pessoa que assina. Seis rotas aceitam apenas o segundo — todas elas usadas pela página de assinatura:

GET /v1/signing-sessions/{id} // carregar a sessão POST /v1/signing-sessions/{id}/advance // avançar etapa POST /v1/signing-sessions/{id}/resend-otp GET /v1/trust-sessions/{id} POST /v1/trust-sessions/{id}/advance POST /v1/trust-sessions/{id}/resend-otp

A confusão mora aqui: GET /v1/signing-sessions/{id} parece a rota óbvia para consultar uma sessão — é o padrão REST que todo mundo espera. Mas ela é a que a página de assinatura usa, e por isso só aceita token de embed. A rota do integrador é GET /v1/signing-sessions/{id}/status, que usa Bearer normalmente e pede o escopo de leitura.

A separação existe por um motivo substantivo: se o token da aplicação pudesse avançar etapas, quem enviou o documento poderia concluir a assinatura em nome de quem deveria assinar — e a evidência registraria, com todos os carimbos em ordem, um ato que a pessoa nunca praticou. O detalhamento está em os dois tokens da API.

Expired é diferente de consumed

Vale distinguir, porque a correção é oposta:

consumed expired
O que acabou O uso do link O prazo da sessão
Reemitir resolve? Sim Não — o link novo herda o prazo vencido
Consome cota? Não Sim, porque exige sessão nova

Se expired aparece com frequência, o problema não é de código: é o prazo escolhido. A janela padrão é de 72 horas e pode ir de 5 minutos a 7 dias, definida por sessão — os detalhes estão em todos os prazos da API. Vale também tratar o evento de prazo se aproximando, que permite lembrar o signatário antes de o link morrer.

Not found e invalid: quase sempre link truncado

Antes de investigar qualquer outra hipótese, confira se a URL chegou inteira. O segredo do signatário viaja como parâmetro na URL, e ele é longo — o suficiente para que:

  • clientes de e-mail quebrem a linha no meio e o link vire dois pedaços;
  • uma cópia manual pegue só até o primeiro espaço;
  • um encurtador remova o que vem depois do ?.

A prevenção é entregar o link como link, e não como texto a ser copiado — e nunca montá-lo à mão a partir de pedaços. Use a URL que a API devolve, inteira. Montar manualmente é também a origem típica de missing required claims.

Quando o 401 é da sua credencial mesmo

Aí a mensagem é outra, e não fala em embed token. Duas causas dominam:

  • Token de acesso vencido. Ele dura 900 segundos. Um pico de 401 logo depois de uma janela ociosa indica um token guardado além da validade — defeito de implementação, não incidente. Renove pelo expires_in devolvido, não por agenda fixa.
  • Credencial pausada ou revogada. Chamadas com uma credencial pausada passam a falhar; a mudança leva até 60 segundos para valer em toda a frota. Confira o status no painel — ver rotação de credenciais.

Roteiro de diagnóstico

  1. A mensagem fala em embed token? Se sim, é o token do signatário — use a tabela do topo.
  2. Se não: a rota está na lista das seis? Então ela nunca vai aceitar o seu Bearer. Para consultar, troque pela rota de status.
  3. Nem uma coisa nem outra? Verifique a validade do token e o status da credencial no painel.
  4. É 403, e não 401? Então a credencial foi aceita e falta permissão — o problema é escopo, tratado em por que o seu token falha.

Para o catálogo completo dos códigos de erro, veja códigos de erro e tratamento de falhas. O painel também traz, ao lado de cada requisição que falhou, uma explicação em português e uma linha de como corrigir — descrito em o painel de API. E a visão geral da API de assinatura digital descreve os recursos citados aqui.

Perguntas Frequentes

O que significa "Embed token has been consumed"?

Que o link de assinatura já foi usado. O link é de uso único por desenho — depois que o signatário conclui, ou que o token embutido é consumido de outra forma, reabrir a mesma URL devolve esse 401. A correção não é recriar a transação: existe um endpoint que emite um link novo para a mesma sessão, sem consumir cota.

E "Embed token has expired"?

O prazo da sessão acabou. Diferente do anterior, aqui não há link a reemitir: reemitir devolve o mesmo prazo original, que já passou. Uma sessão vencida exige criar outra — e aí sim há consumo de cota.

Recebi 401 numa rota e a credencial está correta. Por quê?

Provavelmente você chamou, com o Bearer da aplicação, uma das rotas que só aceitam o token de embed. São seis, todas usadas pela página de assinatura: carregar a sessão, avançar etapa e reenviar código, nas sessões de assinatura e nas de confiança. Para consultar o andamento, a rota do integrador é a de status, não a de leitura da sessão.

O que é "Embed token load limit exceeded"?

O token foi carregado mais vezes do que o permitido. Costuma indicar recarregamento repetido da página de assinatura, ou um cliente de e-mail que pré-carrega o link várias vezes. A saída é a mesma do token consumido: emitir um link novo.

E "Embed token not found" ou "Invalid embed token"?

O token não existe ou não é válido. Na prática, quase sempre é um link truncado — o parâmetro que carrega o segredo foi cortado ao copiar, ou o e-mail quebrou a URL em duas linhas. Confira se a URL chegou inteira antes de investigar qualquer outra coisa.

Como emito um link novo?

Pelo endpoint de link da sessão, que gera outra URL para a sessão existente sem recriar a transação e sem consumir cota. Duas condições: a sessão precisa estar ativa, e o prazo original não é estendido — o link novo herda o vencimento do antigo.

O 401 pode ser da minha credencial mesmo?

Pode, e aí a mensagem é outra: erro de credencial ou token de acesso vencido. O token da aplicação dura 900 segundos, então um pico de 401 depois de um período ocioso costuma ser um token guardado além da validade — defeito de implementação, não incidente da API.

Resolva o 401 sem recriar a transação

Link consumido tem conserto: existe um endpoint que emite outro para a mesma sessão, sem consumir cota. Teste o comportamento no ambiente de homologação, que é gratuito.

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