Node.jsチュートリアル

Node.jsでPDFをMarkdown(マークダウン)に変換

3回の呼び出しで完了します。ジョブを作成し、readyまで状態を確認して、きれいなMarkdownをダウンロードします。下の例はグローバルfetchを備えたNode 18以降だけで動き、依存関係もGPUも不要です。

要点

作成、状態確認、ダウンロード

PDF→Markdown APIは小さなジョブAPIです。APIキーを付けて、URLまたはアップロードファイルのPDFをPOST/api/v2/jobsへ送り、job_idを受け取ります。/api/v2/jobs/{job_id}readyになるまで確認し、/api/v2/jobs/{job_id}/downloadからMarkdownをダウンロードします。OCR、表、数式はサーバー側で処理されるため、Nodeアプリへの追加インストールは不要です。

手順

完全な実行例

convert.mjsとして保存し、node convert.mjsを実行します。APIキーとPDFのURLを置き換えてください。

// 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");

Idempotency-Keyにより、作成処理を安全に再試行できます。同じキーを2回送ると、重複した変換ではなく同じジョブが返ります。

ステップ別

各API呼び出しの役割

1

ジョブを作成

BearerトークンのAPIキーと{ "url": "..." }のJSON本文を付けて、POST /api/v2/jobsを送ります。ローカルファイルはfileフィールドを含むmultipart/form-dataで送信します。レスポンスからjob_idを取得できます。

2

完了まで状態を確認

GET /api/v2/jobs/{job_id}queuedprocessingreadyerrorのいずれかをstatusで返します。完了するまで数秒おきに確認します。

3

Markdownをダウンロード

GET /api/v2/jobs/{job_id}/downloadはMarkdownテキストを返します。.mdファイルへ保存し、LLMへ渡すか、RAGパイプラインへ格納できます。

知っておきたい点

エラー、再試行、大きなファイル

失敗を処理

error_codeは機械判読できます(例: processing_timeoutconversion_failed)。error_messageは安全にログへ記録できます。
readyジョブのtruncated: trueは、非常に長い文書が処理時間の上限に達した部分結果を示します。
Idempotency-Keyを使うと、ジョブを重複させずに作成処理を安全に再試行できます。

規模を拡大

多数のPDFを変換するには、ファイルごとに同じ3回の呼び出しを小さな並列数で実行します。またはポーリングをWebhookへ切り替え、各ジョブが完了した時点で通知を受け取ります。TypeScriptでも契約は同じで、jobレスポンスへ型を付けるだけです。

Pythonやシェルを使う場合は、PythonチュートリアルcURLの手順をご覧ください。

エージェントやパイプラインを構築するには

同じ変換はホスト型MCPエンドポイントでも利用でき、AIエージェントから設定なしでPDFを変換できます。APIの全リファレンスとOpenAPI仕様は開発者向けハブにあります。

よくある質問

よくある質問

Node.jsでPDFを変換するにはAPIキーが必要ですか?

REST APIではAPIキーをBearerトークンとして渡す必要があります。ブラウザまたはWebアプリではキーなしで匿名変換もできます。APIキーはプログラムや自動処理で使います。

必要なNode.jsのバージョンは?

グローバルfetchを備えたNode 18以降が必要です。この例には追加の依存関係がありません。古いバージョンではfetchのpolyfillまたはHTTPリクエストライブラリを導入してください。

URLではなくローカルPDFを変換するには?

JSON本文のurlではなく、FormDataBlobを使い、PDFをfileフィールドに設定したmultipart/form-dataのPOSTを/api/v2/jobsへ送ります。その後の状態確認とダウンロードは同じです。

エラーとタイムアウトの処理方法は?

statuserrorなら、error_code(例: processing_timeoutconversion_failed)とerror_messageを確認します。長い文書はreadyでもtruncatedがtrueになる場合があり、処理時間の上限に達した部分結果を意味します。

ポーリングの代わりにWebhookを使えますか?

はい。最初はポーリングが簡単ですが、APIはWebhookにも対応しています。ジョブが完了すると通知されるため、状態確認を繰り返す必要がありません。設定方法は開発者向けハブをご覧ください。