convertajá

Guia 9 de 10

Idempotência, lista de tarefas e reenvios seguros

Rede cai, servidor do cliente reinicia, fila reprocessa. Com a Idempotency-Key, repetir um POST nunca cria outra tarefa nem cobra duas vezes; com GET /v1/jobs, você reencontra qualquer tarefa dos últimos 90 dias.

10 min · Intermediário · atualizado em 17/10/2026

O que você vai construir

Uma função que cria tarefas com novas tentativas seguras (mesma chave em todas), uma varredura paginada das tarefas do dia com o gasto de créditos e a limpeza dos arquivos sensíveis logo depois do download.

Antes de começar

Como a idempotência funciona

  • Vale para todo POST que cria algo ou cobra: /v1/tools/{id}, /v1/esign/envelopes, /v1/esign/envelopes/{id}/send, /v1/validate, /v1/boleto/parse, /v1/pix/brcode, /v1/qrcode e /v1/barcode.
  • Mesma chave + mesmo pedido (em até 24 h): a resposta original volta igual (mesmo status, mesmo id), com o cabeçalho Idempotent-Replayed: true. Nada é cobrado de novo.
  • Mesma chave + pedido diferente: 409 idempotency_key_reused. Comparamos caminho, campos, opções e o SHA-256 de cada arquivo (o separador do multipart pode mudar à vontade).
  • Ao mesmo tempo: se duas tentativas chegam juntas, só uma roda; a outra espera e recebe a mesma resposta (ou 409 idempotency_in_progress com Retry-After, se passar de ~60 s).
  • Erros não ficam guardados: depois de 402, 429 ou 400, corrija e repita com a mesma chave.
  • A chave vale por conta (produção e teste separadas), tem até 255 caracteres visíveis e expira em 24 horas.

Passo 1: Crie a tarefa com Idempotency-Key

Gere a chave antes da primeira tentativa e guarde junto do pedido no seu banco (ex.: pedido_123:comprimir ou um UUID). Todas as tentativas usam a mesma chave:

# Gere UMA chave por operação e repita o MESMO pedido com a MESMA chave se a conexão cair
CHAVE=$(uuidgen)   # ex.: 6f1c2b8e-3f0a-4c55-9d1e-2a7b9c0d4e11; guarde junto do pedido no seu banco

curl -X POST "https://convertaja.com.br/v1/tools/comprimir-pdf" \
  -H "Authorization: Bearer $CONVERTAJA_KEY" \
  -H "Idempotency-Key: $CHAVE" \
  -F "files=@contrato.pdf" \
  --retry 3 --retry-all-errors -i
# A repetição devolve a mesma tarefa (mesmo "id") com o cabeçalho Idempotent-Replayed: true, sem cobrar de novo
Segunda tentativa (repetição)
HTTP/1.1 202 Accepted
Idempotent-Replayed: true
Location: /v1/jobs/Fi_TgsjgpM19
X-Credits-Remaining: 29874

{ "id": "Fi_TgsjgpM19", "tool": "comprimir-pdf", "status": "running", "credits_charged": 1, … }
Mesma chave com outro arquivo
{
  "error": {
    "code": "idempotency_key_reused",
    "message": "Esta Idempotency-Key já foi usada nas últimas 24 horas em outro pedido (POST /v1/tools/comprimir-pdf com outro conteúdo). Use uma chave nova para cada operação diferente.",
    "request_id": "req_UkbrW3QRi59d"
  }
}

Dica A resposta repetida é a original (de quando a tarefa foi criada). Para a situação atual, consulte GET /v1/jobs/{id}.

Passo 2: Liste e filtre as tarefas

GET /v1/jobs devolve as tarefas da conta, da mais recente para a mais antiga, por 90 dias (os arquivos ficam 1 hora: files_available diz se ainda dá para baixar). Filtros:

ParâmetroValores
limit1 a 100 (padrão 20)
starting_aftero next_cursor da página anterior (id da última tarefa)
statusrunning, done, error (vários com vírgula: done,error)
toolid da ferramenta, ex.: comprimir-pdf
created_after, created_beforeISO 8601 (2026-10-17 = meia-noite de Brasília, ou 2026-10-17T13:00:00Z) ou Unix em segundos
# Tarefas concluídas de uma ferramenta, criadas a partir de 17/10/2026 (horário de Brasília), 50 por página
curl -G "https://convertaja.com.br/v1/jobs" \
  -H "Authorization: Bearer $CONVERTAJA_KEY" \
  --data-urlencode "status=done" \
  --data-urlencode "tool=comprimir-pdf" \
  --data-urlencode "created_after=2026-10-17" \
  --data-urlencode "limit=50"

# Próxima página: o next_cursor da resposta em starting_after
curl -G "https://convertaja.com.br/v1/jobs" -H "Authorization: Bearer $CONVERTAJA_KEY" \
  --data-urlencode "limit=50" --data-urlencode "starting_after=Fi_TgsjgpM19"
Resposta 200 (trecho)
{
  "object": "list",
  "count": 2,
  "has_more": true,
  "next_cursor": "lrzqWwqfYv4a",
  "data": [
    {
      "id": "Fi_TgsjgpM19",
      "tool": "comprimir-pdf",
      "operation": "pdf-compress",
      "status": "done",
      "progress": 100,
      "message": "Pronto!",
      "created_at": "2026-10-16T20:36:06.144Z",
      "finished_at": "2026-10-16T20:36:07.523Z",
      "expires_at": "2026-10-16T21:36:06.144Z",
      "credits_charged": 1,
      "credits_refunded": 0,
      "test": false,
      "outputs": [
        {
          "index": 0,
          "name": "contrato - comprimido.pdf",
          "size": 34031,
          "url": "https://convertaja.com.br/v1/jobs/Fi_TgsjgpM19/files/0"
        }
      ],
      "download_url": "https://convertaja.com.br/v1/jobs/Fi_TgsjgpM19/download",
      "info": "5.5 MB → 33 KB (99% menor)",
      "files_available": true,
      "files_deleted_at": null
    },
    {
      "id": "lrzqWwqfYv4a",
      "tool": "xml-nfe-para-pdf",
      "operation": "nfe-danfe",
      "status": "error",
      "progress": 0,
      "message": "Nenhuma NF-e encontrada. Envie os arquivos XML das notas (ou um ZIP com eles). (1 arquivo ignorado por não ser NF-e)",
      "created_at": "2026-10-16T20:24:25.824Z",
      "finished_at": "2026-10-16T20:24:25.998Z",
      "expires_at": "2026-10-16T21:24:25.824Z",
      "credits_charged": 1,
      "credits_refunded": 1,
      "test": false,
      "outputs": [],
      "error": {
        "code": "job_failed",
        "message": "Nenhuma NF-e encontrada. Envie os arquivos XML das notas (ou um ZIP com eles). (1 arquivo ignorado por não ser NF-e)"
      },
      "files_available": false,
      "files_deleted_at": null
    }
  ]
}

Passo 3: Apague os arquivos assim que baixar

Documentos sensíveis (contratos, notas, exames)? Não espere 1 hora: depois de baixar, apague. A tarefa continua na lista, com files_available: false e files_deleted_at. Tarefa ainda em andamento: 409 job_running (não há cancelamento no meio; apague quando terminar).

# Apaga os arquivos gerados antes de 1 hora (a tarefa continua na lista, com files_available: false)
curl -X DELETE "https://convertaja.com.br/v1/jobs/Fi_TgsjgpM19" \
  -H "Authorization: Bearer $CONVERTAJA_KEY"

# Mesmo efeito, para clientes que só fazem GET e POST
curl -X POST "https://convertaja.com.br/v1/jobs/Fi_TgsjgpM19/delete" \
  -H "Authorization: Bearer $CONVERTAJA_KEY"

Tarefas interrompidas

Se o servidor reiniciar no meio de uma tarefa, ela termina com status: "error" e error.code: "job_interrupted", e os créditos voltam automaticamente. Envie de novo com uma nova Idempotency-Key (a resposta guardada da chave antiga é a da tarefa interrompida).

Próximos passos

Todos os endpoints e opções: referência da API. Dúvidas? Fale com a gente e informe o X-Request-Id da chamada.