Linha de comando

Converter PDF para Markdown com cURL

Sem linguagem de programação. Com curl e jq você converte um PDF para Markdown direto do terminal, de um Makefile, de um passo de CI ou de um cron. Copie a receita abaixo, defina sua chave e rode.

Resposta curta

Três curls e um loop de consulta

curl -X POST do PDF para /api/v2/jobs com sua chave, extraia o job_id com jq, faça um loop em /api/v2/jobs/{job_id} até o status ser ready, e então faça curl em /api/v2/jobs/{job_id}/download com -o para salvar o Markdown. É HTTP puro, então roda onde quer que uma shell rode, sem SDK e sem nada para compilar.

Como fazer

A receita de shell completa

Salve como convert.sh, chmod +x, e rode. Troque pela sua chave e pelo seu PDF.

#!/usr/bin/env bash
set -euo pipefail
API="https://pdf2md.dev/api/v2"
AUTH="Authorization: Bearer p2m_your_key"

# 1) criar um job a partir de uma URL de PDF
#    (para enviar um arquivo local, use: -F [email protected] )
JID=$(curl -fsS -X POST "$API/jobs" -H "$AUTH" \
  -H "Content-Type: application/json" -H "Idempotency-Key: report-2026-01" \
  -d '{"url":"https://example.com/report.pdf"}' | jq -r .job_id)

# 2) consultar até ready ou error
while :; do
  JOB=$(curl -fsS "$API/jobs/$JID" -H "$AUTH")
  STATUS=$(echo "$JOB" | jq -r .status)
  [ "$STATUS" = "ready" ] && break
  if [ "$STATUS" = "error" ]; then
    echo "failed: $(echo "$JOB" | jq -r .error_code)" >&2
    exit 1
  fi
  sleep 3
done

# 3) baixar o Markdown
curl -fsS "$API/jobs/$JID/download" -H "$AUTH" -o report.md
echo "salvo report.md"

A opção -f faz o curl falhar diante de erros HTTP, e set -euo pipefail interrompe o script no primeiro problema, então uma execução quebrada nunca grava um arquivo vazio em silêncio.

Onde encaixa

Feito para automação

Como é um único script autocontido com um código de saída real, a receita se encaixa onde um programa completo seria exagero.

Pipelines de CI

Adicione como passo de build para converter PDFs de documentação em Markdown a cada commit. Uma conversão falha faz o passo falhar.

Jobs de cron

Agende para baixar e converter um relatório noturno, gravando o Markdown onde seu site de documentação ou seu pipeline espera.

Segredos, não literais

Mantenha a chave de API em um segredo de CI ou uma variável de ambiente e referencie-a no cabeçalho Authorization, nunca embutida no código.

Quer isso dentro de um app? Veja os tutoriais de Python, Node.js e Go.

Toda a API em uma página

Cada endpoint, campo e código de erro está no hub para desenvolvedores, com a especificação OpenAPI que você pode importar no Postman ou usar para gerar um cliente.

Além do bash

Outras shells e webhooks

A receita é bash, mas as três chamadas são só HTTP, então elas se portam para qualquer lugar onde o curl rode.

Windows e PowerShell

O curl vem com o Windows moderno, então as mesmas chamadas funcionam no PowerShell ou em um arquivo .cmd; você só ajusta o uso de aspas (o PowerShell prefere aspas simples em volta do JSON, ou use Invoke-RestMethod com um corpo de hashtable). Em um Makefile, em um passo de build de Dockerfile ou em um bloco run: do GitHub Actions, o script não muda.

Pule o loop de consulta

A consulta é a abordagem mais simples e serve para um arquivo ou alguns poucos. Para muitos arquivos, ou para evitar a espera por completo, registre um webhook e a API chama você de volta quando um job fica pronto, assim um script pode disparar conversões e processar resultados à medida que chegam em vez de ficar em um loop.

Seja qual for a shell, mantenha a chave fora do corpo do script: leia-a de uma variável de ambiente ou de um segredo de CI. E se você precisar inspecionar um resultado antes de salvar, canalize o download para um visualizador (curl ... | less) em vez de -o, já que o endpoint retorna texto Markdown puro.

Perguntas frequentes

Perguntas comuns

O que eu preciso para rodar a receita de cURL?

curl e jq. O curl faz as chamadas HTTP e o jq lê job_id e status das respostas JSON. Ambos estão disponíveis na maioria dos sistemas ou a uma instalação de pacote de distância.

Como converto um arquivo local com curl?

Use um envio multipart: curl -X POST /api/v2/jobs -F [email protected] com o cabeçalho Authorization, em vez do corpo JSON -d que carrega uma url.

Como uso isso em CI ou em um cron?

O script sai com código diferente de zero quando um job falha, então ele se encaixa em um passo de CI ou em um cron agendado. Guarde a chave de API como um segredo de CI ou uma variável de ambiente e passe-a no cabeçalho Authorization.

Dá para fazer sem jq?

O jq é a forma mais limpa de ler job_id e status, mas você também pode fazer o parsing do JSON com grep e sed se o jq não estiver disponível. O jq é recomendado pela confiabilidade.

O que o cabeçalho Idempotency-Key faz?

Enviar a mesma Idempotency-Key em um create repetido retorna o mesmo job em vez de iniciar uma conversão duplicada, o que é útil quando um passo de CI instável roda de novo.