Pythonチュートリアル

PythonでPDFをMarkdown(マークダウン)に変換

REST APIを使う手順を段階的に解説します。APIキーを取得し、ジョブを作成して状態を確認し、きれいなMarkdownをダウンロードします。コピーできる完全な例と適切なエラー処理も含みます。

要点

1つのキー、3回の呼び出し

PythonからPDFをMarkdownへ変換するには、Bearerキー付きで小さなREST APIを呼びます。POST /api/v2/jobsでジョブを作成し、GET /api/v2/jobs/{id}readyまで確認してから、GET /api/v2/jobs/{id}/downloadでMarkdownを取得します。ホスティングや重いライブラリは不要で、必要なのはrequestsだけです。同じ処理はエージェント向けのホスト型MCPでも利用でき、拡張機能やWebアプリと同じMarkdownが返ります。ブラウザで試してから安心して自動化できます。

手順

4ステップで準備

1

APIキーを取得

無料のGoogleアカウントでログインし、アカウント画面からAPIキーを作成します。表示は一度だけです。Authorization: Bearer p2m_your_keyとして送信してください。

2

ジョブを作成

PDFのURLまたはアップロードしたバイト列を/api/v2/jobsへPOSTします。ジョブIDとステータスが返ります。

3

完了まで状態を確認

statusreadyまたはerrorになるまで、GET /api/v2/jobs/{id}を呼びます。

4

Markdownをダウンロード

GET /api/v2/jobs/{id}/downloadでMarkdownテキストを取得します。truncatedpagesも確認してください。

完全な例

完全なPythonスクリプト

標準ライブラリとrequestsを使います。PDFのURLからジョブを作成し、状態を確認してMarkdownを保存します。

# pip install requests
import requests, time

API = "https://pdf2md.dev/api/v2"
H = {"Authorization": "Bearer p2m_your_key"}

# 1) create a job from a PDF URL
r = requests.post(f"{API}/jobs", headers={**H, "Idempotency-Key": "report-2026-01"},
                  json={"url": "https://example.com/report.pdf"})
r.raise_for_status()
jid = r.json()["job_id"]

# 2) poll until ready or error
while True:
    job = requests.get(f"{API}/jobs/{jid}", headers=H).json()
    if job["status"] in ("ready", "error"):
        break
    time.sleep(3)

if job["status"] == "error":
    raise SystemExit(f"conversion failed: {job.get('error_code')} {job.get('error_message')}")

# 3) download the Markdown
md = requests.get(f"{API}/jobs/{jid}/download", headers=H).text
if job.get("truncated"):
    print("note: partial result (hit the time budget)")
open("report.md", "w").write(md)

URLではなくローカルファイルを送る場合は、同じエンドポイントへfileフィールドを含むmultipart/form-dataとしてバイト列をPOSTします。リクエストとレスポンスの全形式はOpenAPI仕様にあります。

多数のPDFを変換する場合は、ファイルごとに1つのジョブを作成し、スロット上限まで並列に状態を確認します。無料プランは3スロットで、有料プランでは増加します。再試行で処理が重複しないよう、ファイルごとに異なるIdempotency-Keyを使い、429ではRetry-Afterヘッダーに従って待機してください。

堅牢にする

エラー、再試行、Webhook

エラーコードを確認

失敗したジョブはstatus: errorと、機械判読できるerror_codeprocessing_timeoutまたはconversion_failed)、安全なerror_messageを返します。メッセージの文面ではなくコードで分岐してください。

truncatedを処理

長い文書はreadyでもtruncated=trueになる場合があります。フラグを確認し、ファイルを分割するか、より長い有料プランの処理時間を利用してください。

Idempotency-Key

Idempotency-Keyヘッダーを送ると、作成処理を再試行してもジョブが重複しません。

ポーリングよりWebhook

有料プランではWebhookを登録するかcallback_urlを渡すと、ポーリングせずにreadyまたはerror時のPOST通知を受け取れます。

429を尊重

429では再試行前にRetry-Afterで指定された秒数を待ち、キューへ連続リクエストを送らないでください。

キーはサーバー側で管理

APIキーは秘密情報です。サーバー側に保存し、TLSで送信し、必要に応じていつでもローテーションまたは失効させてください。

ほかの言語

Python以外でも同じ3回

単純なHTTPS APIなので、どの言語からでも利用できます。Nodeでも作成、状態確認、ダウンロードの流れは同じです。

// Node 18+ (global fetch)
const API = "https://pdf2md.dev/api/v2";
const H = { Authorization: "Bearer p2m_your_key" };

let r = await fetch(`${API}/jobs`, { method: "POST",
  headers: { ...H, "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://example.com/report.pdf" }) });
let { job_id } = await r.json();

let job;
do { await new Promise(s => setTimeout(s, 3000));
     job = await (await fetch(`${API}/jobs/${job_id}`, { headers: H })).json();
} while (!["ready", "error"].includes(job.status));

const md = await (await fetch(`${API}/jobs/${job_id}/download`, { headers: H })).text();

エージェントやRAGで使うには

同じ処理はChatGPT、Claude、エージェントフレームワーク向けのホスト型MCPでも利用できます。取り込みとチャンク分割についてはRAGガイドをご覧ください。

よくある質問

よくある質問

PythonでPDFをMarkdownに変換するには?

BearerキーでREST APIを呼びます。PDFを/api/v2/jobsへPOSTし、GET /api/v2/jobs/{id}をreadyまで確認してから、/downloadをGETしてMarkdownを取得します。完全なrequestsの例は上にあります。

APIキーは必要ですか?

APIを使う場合は必要です。無料のGoogleアカウントでキーを作成し、ホスト型MCPも利用できます。ブラウザ拡張機能とWebアプリは匿名で利用でき、キーは不要です。

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

失敗したジョブはstatus: errorと、機械判読できるerror_codeprocessing_timeoutまたはconversion_failed)、安全なerror_messageを返します。長い文書はreadyでもtruncated=trueになる場合があるため、このフラグを確認してください。

ポーリングを省けますか?

有料プランでは、ジョブ作成時にWebhookを登録するかcallback_urlを渡せます。readyまたはerrorになるとサービスからPOSTされるため、ポーリングは不要です。

Nodeやほかの言語でも使えますか?

はい。単純なHTTPS APIなので、どの言語からでも利用できます。上に短いNodeの例があり、完全な契約はOpenAPI仕様で確認できます。

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

JSON本文のurlではなく、fileフィールドを含むmultipart/form-dataとしてファイルのバイト列を/api/v2/jobsへPOSTします。状態確認とダウンロードは同じです。

複数のPDFを同時に変換できますか?

ファイルごとにジョブを作成し、スロット上限まで並列に状態を確認します。無料プランは3スロットで、有料プランでは増加します。有料プランには一括作成エンドポイントとWebhookもあり、ポーリングを省けます。

拡張機能やWebアプリと同じ出力ですか?

はい。すべての画面で同じ変換エンジンを使うため、APIはブラウザと同じMarkdownを返します。

無料で使えますか?

無料プランは3スロット、10 MB、処理時間15分、保持時間1時間です。有料プランでは各上限が増え、Webhookと一括作成も利用できます。