Pular para o conteúdo
AdigitalMAX AdigitalMAX API v1
Operar

Limites e consumo

Uma integração que respeita os limites é mais rápida do que uma que os ignora, porque não passa metade do tempo tratando 429. Esta página tem os números, o que cada contador de consumo mede e as práticas que separam uma integração que roda por anos de uma que precisa de babá.

Todos os limites em uma tabela

Se você só tem um minuto, leia esta tabela e vá embora.
LimiteValorAo estourar
Requisições por minuto60 por chave429 com Retry-After
Tamanho do arquivo20 MB por PDF, apenas application/pdf413
Páginas por documento300422
Signatários por documento50422
Campos por documento500422
Itens por página de listagem1 a 100, padrão 25o valor é limitado a 100, sem erro
Validade do cursor24 horas422, refaça a listagem
Validade da URL de download15 minutos, uso único404, peça outra
Reenvio de convite3 por signatário por hora429
Validação pública30 por minuto por IP, rajada de 10429
Autenticação do painel10 por minuto por IP429
Chaves de idempotêncialembradas por 24 horasdepois disso a chave é tratada como nova
Resposta do seu webhook10 segundosconta como falha e entra em retentativa

>>> PENDENTE DE BACKEND <<<

Os valores de 60 requisições por minuto e 20 MB por arquivo vêm da configuração real da plataforma. Os demais números desta tabela são o desenho do contrato e ainda não foram exercidos contra o servidor. Trate-os como ordem de grandeza confiável, não como garantia contratual, até a publicação da API.

Limite de requisição

São 60 requisições por minuto, contadas por chave de API, em janela deslizante. Cada resposta traz o estado do seu orçamento, e o cliente que lê esses cabeçalhos nunca precisa descobrir o limite por tentativa e erro:

Cabeçalhos de toda resposta
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 1786031111

Quando você estoura, a resposta é 429 e vem com o tempo exato de espera:

429 Too Many Requests
HTTP/1.1 429 Too Many Requests
Retry-After: 23
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1786031111
X-Request-Id: req_01J9M4X7QK2ZB8N3P6R0T5V2WY

Retry-After é em segundos e é exato, não estimativa. Respeitá-lo é mais rápido do que tentar de novo antes: cada tentativa antecipada volta a estourar o limite e ainda conta.

// Um regulador de vazao simples: em vez de bater no limite e tratar
// 429, mantenha-se abaixo dele. Sai mais barato e o log fica limpo.

class Regulador {
  /** @param {number} porMinuto deixe folga: 50 de 60 e um bom alvo. */
  constructor(porMinuto = 50) {
    this.intervaloMs = 60000 / porMinuto;
    this.proximo = 0;
  }

  async esperarVez() {
    const agora = Date.now();
    const alvo = Math.max(agora, this.proximo);
    this.proximo = alvo + this.intervaloMs;
    if (alvo > agora) {
      await new Promise((r) => setTimeout(r, alvo - agora));
    }
  }

  /** Freia de verdade quando o servidor mandar frear. */
  ajustarPor(resposta) {
    const restante = Number(resposta.headers.get("X-RateLimit-Remaining"));
    const reset = Number(resposta.headers.get("X-RateLimit-Reset"));

    // Menos de 10% de folga: pare ate a janela virar.
    if (Number.isFinite(restante) && restante < 6 && Number.isFinite(reset)) {
      this.proximo = Math.max(this.proximo, reset * 1000);
    }
  }
}

const regulador = new Regulador(50);

export async function chamarRegulado(url, opcoes) {
  await regulador.esperarVez();
  const resposta = await fetch(url, opcoes);
  regulador.ajustarPor(resposta);

  if (resposta.status === 429) {
    const espera = Number(resposta.headers.get("Retry-After") || 5);
    await new Promise((r) => setTimeout(r, espera * 1000));
    return chamarRegulado(url, opcoes);
  }
  return resposta;
}

Precisa de mais que 60 por minuto? Antes de pedir aumento, confira se a causa não é sondagem: quem consulta o estado de cada documento aberto a cada minuto gasta a cota inteira sem produzir nada. Trocar sondagem por webhook costuma reduzir o volume em uma ordem de grandeza. Se depois disso o limite continuar apertado, fale conosco com o número de documentos por dia e o padrão de uso.

Paginação por cursor

Toda listagem usa cursor, e não número de página. Os parâmetros são limite, de 1 a 100, e cursor, que vem da página anterior.

A razão de não haver ?pagina=3 é que o acervo muda enquanto você o percorre. Com página numerada, um documento criado entre a leitura da página 1 e a da página 2 empurra tudo para baixo, e um item da página 1 reaparece na 2 enquanto outro nunca é lido. Em uma lista de vinte contratos isso é um incômodo; em uma conciliação noturna de dez mil, é um contrato que o seu sistema nunca viu. O cursor aponta para uma posição estável no conjunto, e a inserção concorrente não desloca nada.

O laço correto
# 1. Primeira pagina: so limite.
GET /v1/documentos?limite=100

# 2. Resposta:
#    { "itens": [...], "total": 412, "proximoCursor": "Y3Vyc29y..." }

# 3. Proxima pagina: repita os MESMOS filtros e acrescente o cursor.
GET /v1/documentos?limite=100&cursor=Y3Vyc29y...

# 4. Pare quando proximoCursor vier nulo ou ausente. NUNCA pare
#    com menos itens que o limite: sao coisas diferentes.

Três regras que evitam os erros mais comuns:

Um exemplo completo de percurso paginado, com tratamento de 429, está em Guias.

Tamanho e formato de arquivo

O que aceitamos, e o que recusamos antes de processar.
RegraValor
Tamanho máximo20 MB por arquivo
FormatoPDF apenas. Não convertemos DOCX, XLSX nem imagem.
Páginasaté 300
Versão do PDF1.4 a 2.0
Protegido por senharecusado com 422
Já assinado digitalmenterecusado com 422: assinar por cima invalidaria a assinatura anterior
Com formulário AcroForm preenchidorecusado com 422: os campos entrariam em conflito com os nossos
Varredura antivírustodo upload é varrido antes de ficar disponível

O limite de 20 MB é imposto na borda, pelo servidor web, antes de a aplicação ver a requisição. Isso significa que um arquivo de 30 MB pode receber a recusa antes de o upload terminar, e o sintoma no seu lado pode ser uma conexão encerrada em vez de um 413 limpo. Confira o tamanho antes de enviar.

Conferir e reduzir antes de enviar
#!/usr/bin/env bash
# Confere o tamanho e, se passar do limite, reduz sem perder legibilidade.

set -euo pipefail

PDF="${1:?informe o PDF}"
LIMITE=$((25 * 1024 * 1024))

TAMANHO=$(stat -c%s "$PDF" 2>/dev/null || stat -f%z "$PDF")
echo "tamanho: $((TAMANHO / 1024 / 1024)) MB"

if [ "$TAMANHO" -le "$LIMITE" ]; then
  echo "OK, cabe."
  exit 0
fi

# Quase sempre o excesso vem de pagina digitalizada em 600 dpi.
# /ebook mantem 150 dpi, que e legivel e imprime bem.
gs -sDEVICE=pdfwrite \
   -dCompatibilityLevel=1.7 \
   -dPDFSETTINGS=/ebook \
   -dNOPAUSE -dQUIET -dBATCH \
   -sOutputFile="${PDF%.pdf}-reduzido.pdf" \
   "$PDF"

echo "gerado: ${PDF%.pdf}-reduzido.pdf"
echo "CONFIRA O RESULTADO antes de enviar: reducao agressiva pode"
echo "tornar ilegivel um documento que sera prova em juizo."

Medição de consumo

Você precisa saber o que custa antes de a fatura chegar. São nove contadores; cinco importam para praticamente toda integração e estão marcados abaixo. Todos são consultáveis a qualquer momento por GET /v1/consumo.

O que dispara cada contador, e o que não dispara.
Contador Conta quando Não conta quando
ENVELOPE_ENVIADO Um documento sai do rascunho, por POST /v1/documentos/{documentoId}/enviar ou por POST /v1/envelopes/{envelopeId}/enviar. É a unidade da franquia do plano, e um envelope conta um tenha ele um documento ou seis. Criar rascunho, reenviar convite, lembrete automático, cancelar, mover.
DOCUMENTO_ENVIADO Um PDF é recebido, varrido, rasterizado e preparado. Um por arquivo enviado. Instanciar modelo já processado. Por isso modelo sai mais barato em volume.
ASSINATURA_COLETADA Um signatário conclui a assinatura. Um documento com três signatários conta três. Recusa, expiração, visualização sem assinar.
REQUISICAO_API Toda requisição autenticada que devolve 2xx, 4xx de negócio ou 404. 429, 5xx, /healthz, /readyz e as rotas públicas de validação.
SMS_ENVIADO Um SMS sai: convite por metodoEntrega: "SMS", código do fator SMS_OTP, ou lembrete por SMS. Cada reenvio de código conta de novo. SMS recusado pela operadora antes do envio.
WHATSAPP_ENVIADO Uma mensagem de WhatsApp é entregue. Falha de entrega por número inválido.
VERIFICACAO_BIOMETRICA Uma prova de vida é processada, aprovada ou não. >>> PENDENTE DE BACKEND <<< O signatário desistir antes de enviar a selfie.
CARIMBO_TEMPO Um carimbo do tempo é solicitado à autoridade, no nível ICP_BRASIL. >>> PENDENTE DE BACKEND <<< Níveis ELETRONICA, SEGURA e AVANCADA.
ARMAZENAMENTO_MB_DIA Soma diária dos megabytes guardados: original, assinado, PAdES e certificado. Arquivo já expurgado pela política de retenção.

O contador que surpreende é o de SMS. Um documento com três signatários exigindo SMS_OTP, em que dois pedem reenvio do código porque demoraram a abrir, custa cinco SMS, e não três. Se o volume for grande e o risco não exigir, TOTP entrega o mesmo segundo fator sem custo por uso; a contrapartida é que o signatário precisa cadastrar o aplicativo autenticador na primeira vez.

Prever o custo de um envio

Vale calcular antes, e a conta é direta. Um contrato de 12 páginas, dois signatários, os dois com fatoresExigidos: ["EMAIL", "SMS_OTP"], enviado a partir de modelo e acompanhado por webhook:

Um envio típico, contador por contador.
ContadorQuantidadeDe onde vem
ENVELOPE_ENVIADO1o disparo
DOCUMENTO_ENVIADO0o modelo já foi processado quando foi criado
ASSINATURA_COLETADA2uma por signatário que assinou
REQUISICAO_API3instanciar o modelo, ler o certificado, baixar o PDF
SMS_ENVIADO2 a 4um código por signatário, mais os reenvios que eles pedirem

Compare com o mesmo envio feito sem modelo e com sondagem de dois em dois minutos por dois dias: DOCUMENTO_ENVIADO sobe para 1 e REQUISICAO_API sobe de 3 para mais de mil. É esse contador que separa uma integração barata de uma cara, e ele depende inteiramente de decisões suas.

Retenção

>>> PENDENTE DE BACKEND <<<

A política de retenção ainda não está definida. O mecanismo de expurgo existe e está deliberadamente desligado até haver política escrita, aprovada e com restauração de backup testada. Enquanto isso, nada é apagado automaticamente. Não construa premissa de prazo em cima do que está escrito abaixo: isto é a forma que a política vai ter, não os números dela.

Quando a política entrar, ela terá esta forma, e alguns prazos já são certos porque não dependem de decisão comercial:

O que vive quanto tempo.
ItemPrazo
Documento concluído e certificadodefinido pela sua organização, com mínimo legal aplicável ao tipo de documento
Documento em rascunho, nunca enviado90 dias sem alteração
Documento cancelado ou expiradoprazo próprio, mais curto que o de concluído
Trilha de auditoriaacompanha o documento; nunca é apagada antes dele
Histórico de entregas de webhook30 dias
Log de chamadas à API90 dias
Chaves de idempotência24 horas
Cursores de paginação24 horas
URLs de download15 minutos, uso único

Guarde a sua própria cópia. Independentemente da política que vier, um contrato de doze anos precisa sobreviver ao fornecedor que o processou. Baixe o PDF assinado e o certificado quando o evento document.completed chegar, guarde no seu armazenamento, e guarde junto o código de validação do certificado: com ele, a autenticidade continua conferível pela validação pública. O código para fazer isso está em Guias.

Sete práticas para não ser barrado

  1. Troque sondagem por webhook

    É a decisão de maior impacto, e sozinha resolve a maioria dos casos de 429. Sondar não faz o signatário assinar mais rápido; só gasta a sua cota descobrindo que nada mudou.

  2. Regule a vazão em vez de tratar o erro

    Um regulador que segura em 50 por minuto nunca vê um 429. Tratar 429 depois de estourar já custou a requisição, e o log fica cheio de erro que não é erro. O código está acima.

  3. Use limite=100 em listagem

    Percorrer mil documentos com o padrão de 25 custa 40 requisições; com 100, custa 10. A resposta é maior, e isso quase nunca importa em rede de servidor.

  4. Mande Idempotency-Key em toda criação

    Com uma chave do seu domínio, retentativa depois de timeout não duplica documento e não consome envelope a mais. Sem ela, o mesmo timeout vira um contrato duplicado na caixa do cliente.

  5. Prefira modelo a upload repetido

    Instanciar modelo evita o contador DOCUMENTO_ENVIADO, dispensa subir o mesmo PDF de novo e reduz o tempo de resposta. Em volume, a diferença é grande.

  6. Distribua o disparo em lote

    Mil contratos disparados às 8h em ponto batem no limite. Espalhe pela hora, ou pelo dia: o signatário não percebe a diferença de dez minutos, e a sua integração termina sem um único 429.

  7. Registre o X-Request-Id sempre

    Em sucesso e em falha. É o que transforma um chamado de suporte de três dias em uma resposta na primeira mensagem. Veja Erros.