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ステップで準備
APIキーを取得
無料のGoogleアカウントでログインし、アカウント画面からAPIキーを作成します。表示は一度だけです。Authorization: Bearer p2m_your_keyとして送信してください。
ジョブを作成
PDFのURLまたはアップロードしたバイト列を/api/v2/jobsへPOSTします。ジョブIDとステータスが返ります。
完了まで状態を確認
statusがreadyまたはerrorになるまで、GET /api/v2/jobs/{id}を呼びます。
Markdownをダウンロード
GET /api/v2/jobs/{id}/downloadでMarkdownテキストを取得します。truncatedとpagesも確認してください。
完全な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_code(processing_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_code(processing_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と一括作成も利用できます。