Tutorial de Node.js

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.

Resposta breve

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.

Como fazer

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.

Passo a passo

O que cada chamada faz

1

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.

2

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.

3

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.

Bom saber

Erros, novas tentativas e arquivos grandes

Trate as falhas

error_code é legível por máquina (por exemplo processing_timeout, conversion_failed); error_message é seguro de registrar.
truncated: true em um trabalho ready significa um resultado parcial que atingiu o orçamento de tempo em um documento muito longo.
Idempotency-Key permite que você repita um create com segurança sem um trabalho duplicado.

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 frequentes

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.