Converter PDF em Markdown no Node.js
Três chamadas e pronto: crie um trabalho, consulte até ele estar pronto e baixe Markdown limpo. O exemplo abaixo é Node 18+ com o fetch global, sem dependências, sem GPU, apenas a API REST.
Criar, consultar, baixar
A API de PDF para Markdown é uma pequena API de trabalhos. Você faz POST de um PDF (uma URL ou um arquivo enviado) para /api/v2/jobs com sua chave de API, recebe um job_id, consulta /api/v2/jobs/{job_id} até o status ser ready, e então baixa o Markdown de /api/v2/jobs/{job_id}/download. O OCR, as tabelas e as fórmulas são tratados no servidor, então não há nada para instalar no seu app Node.
O exemplo completo
Salve como convert.mjs e execute node convert.mjs. Troque a chave e a URL do PDF.
// Node 18+ has a global fetch, so no dependencies are needed.
const API = "https://pdf2md.dev/api/v2";
const H = { Authorization: "Bearer p2m_your_key" };
// 1) create a job from a PDF URL
const created = await fetch(`${API}/jobs`, {
method: "POST",
headers: { ...H, "Content-Type": "application/json", "Idempotency-Key": "report-2026-01" },
body: JSON.stringify({ url: "https://example.com/report.pdf" }),
});
if (!created.ok) throw new Error(`create failed: ${created.status}`);
const { job_id } = await created.json();
// 2) poll until ready or error
let job;
do {
await new Promise((r) => setTimeout(r, 3000));
job = await (await fetch(`${API}/jobs/${job_id}`, { headers: H })).json();
} while (!["ready", "error"].includes(job.status));
if (job.status === "error") {
throw new Error(`conversion failed: ${job.error_code} ${job.error_message}`);
}
// 3) download the Markdown
const md = await (await fetch(`${API}/jobs/${job_id}/download`, { headers: H })).text();
if (job.truncated) console.warn("note: partial result (hit the time budget)");
const fs = await import("node:fs/promises");
await fs.writeFile("report.md", md);
console.log("saved report.md");
O Idempotency-Key torna seguro um create repetido: se a mesma chave for enviada duas vezes, você recebe o mesmo trabalho em vez de uma conversão duplicada.
O que cada chamada faz
Crie um trabalho
POST /api/v2/jobs com a chave de API como token bearer e um corpo JSON de { "url": "..." }. Para converter um arquivo local, envie multipart/form-data com um campo file. A resposta dá um job_id.
Consulte até ready
GET /api/v2/jobs/{job_id} retorna um status de queued, processing, ready ou error. Consulte a cada poucos segundos até ele se estabilizar.
Baixe o Markdown
GET /api/v2/jobs/{job_id}/download retorna o texto Markdown. Grave-o em um arquivo .md, entregue-o a um LLM, ou guarde-o para um pipeline RAG.
Erros, novas tentativas e arquivos grandes
Trate as falhas
processing_timeout, conversion_failed); error_message é seguro de registrar.ready significa um resultado parcial que atingiu o orçamento de tempo em um documento muito longo.Escale
Para converter muitos PDF, execute as mesmas três chamadas por arquivo com um pequeno limite de concorrência, ou troque a consulta por webhooks para que você seja avisado quando cada trabalho estiver pronto. O contrato é idêntico em TypeScript; tipe a resposta job e pronto.
Prefere Python ou a shell? Consulte o tutorial de Python e a receita de cURL.
Construindo um agente ou pipeline?
A mesma conversão está disponível como um endpoint MCP hospedado, então um agente de IA pode converter PDF sem configuração. Consulte o hub para desenvolvedores para a referência completa da API e a especificação OpenAPI.
Perguntas comuns
Preciso de uma chave de API para converter PDF no Node.js?
Sim, para a API REST você passa uma chave de API como token bearer. Você também pode converter de forma anônima no navegador ou no app web sem chave; a chave de API é para o uso programático e automatizado.
De qual versão do Node.js eu preciso?
Node 18 ou superior, que inclui um fetch global, assim o exemplo não precisa de dependências extras. Em versões anteriores, instale um polyfill de fetch ou use uma biblioteca de requisições.
Como converto um arquivo PDF local em vez de uma URL?
Envie um POST multipart/form-data para /api/v2/jobs com o campo file apontando para o PDF, usando FormData e um Blob, em vez de um corpo JSON com url. O restante do fluxo (consultar, baixar) é igual.
Como trato erros e tempos limite?
Quando o status é error, leia error_code (por exemplo processing_timeout ou conversion_failed) e error_message. Um documento longo pode terminar ready com truncated em true, o que significa um resultado parcial que atingiu o orçamento de tempo.
Posso usar webhooks em vez de consulta?
Sim. A consulta é o mais simples para começar, mas a API também aceita webhooks para que você seja avisado quando um trabalho estiver pronto em vez de consultar. Consulte o hub para desenvolvedores para a configuração do webhook.