抽出の実行
概要
抽出エンドポイントは、ドキュメント(base64エンコード済み)を受け取り、定義したテンプレートを通して処理し、テンプレートの変数に一致する構造化データを返します。1回のAPIコールでパイプライン全体(アップロード、AI処理、構造化出力)を処理します。
すべての抽出リクエストは POST /v1/extractions/run を経由します。
ドキュメントの準備
ドキュメントをAPIに送信する前に、ファイルの内容をbase64エンコードする必要があります。
制約:
- リクエストボディの最大サイズ: 15 MB
- サポートされるMIMEタイプ:
application/pdf(PDF)application/vnd.openxmlformats-officedocument.wordprocessingml.document(DOCX)
# PDFファイルをBase64エンコード
base64 -i invoice.pdf -o invoice_b64.txt
# またはインライン(macOS / Linux)
PDF_BASE64=$(base64 -w 0 invoice.pdf)import { readFileSync } from "fs";
const pdfBuffer = readFileSync("invoice.pdf");
const pdfBase64 = pdfBuffer.toString("base64");import base64
with open("invoice.pdf", "rb") as f:
pdf_base64 = base64.b64encode(f.read()).decode("utf-8")WARNING
Base64エンコードにより、ファイルサイズは約33%増加します。10 MBのPDFはエンコード後に約13.3 MBになるため、15 MBのリクエスト制限内に収まるよう、元ファイルは約11 MB以下にしてください。
リクエストの送信
以下のJSONボディで POST リクエストを /v1/extractions/run に送信します:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
templateId | string | はい | 抽出に使用するテンプレートのID |
fileName | string | はい | 元のファイル名(例:"invoice.pdf") |
pdfBase64 | string | はい | Base64エンコードされたファイルの内容 |
mimeType | string | はい | ファイルのMIMEタイプ |
runId | string | いいえ | 複数の抽出をバッチにグループ化するためのオプションの識別子 |
curl -X POST https://api.docmap.io/v1/extractions/run \
-H "Authorization: Bearer dm_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"templateId": "tmpl_abc123",
"fileName": "invoice.pdf",
"pdfBase64": "JVBERi0xLjQKJeLj...",
"mimeType": "application/pdf"
}'const response = await fetch("https://api.docmap.io/v1/extractions/run", {
method: "POST",
headers: {
Authorization: "Bearer dm_live_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
templateId: "tmpl_abc123",
fileName: "invoice.pdf",
pdfBase64: pdfBase64,
mimeType: "application/pdf",
}),
});
const { data } = await response.json();
console.log(data.extractedData);import requests
response = requests.post(
"https://api.docmap.io/v1/extractions/run",
headers={
"Authorization": "Bearer dm_live_your_api_key",
"Content-Type": "application/json",
},
json={
"templateId": "tmpl_abc123",
"fileName": "invoice.pdf",
"pdfBase64": pdf_base64,
"mimeType": "application/pdf",
},
)
data = response.json()["data"]
print(data["extractedData"])レスポンスの理解
抽出が成功すると、data オブジェクトでラップされたレスポンスが返されます:
{
"data": {
"id": "ext_abc123def456",
"userId": "user_789",
"templateId": "tmpl_abc123",
"templateName": "Invoice Parser",
"fileName": "invoice.pdf",
"status": "completed",
"extractedData": {
"vendor_name": "Acme Corp",
"invoice_number": "INV-2024-001",
"total_amount": 1250.00,
"line_items": [
{ "description": "Widget A", "quantity": 10, "unit_price": 125.00 }
]
},
"error": null,
"variables": [
{ "name": "vendor_name", "type": "string", "description": "Company name of the vendor" },
{ "name": "invoice_number", "type": "string", "description": "Invoice reference number" },
{ "name": "total_amount", "type": "number", "description": "Total invoice amount" },
{ "name": "line_items", "type": "array", "description": "List of line items" }
],
"source": "api",
"runId": null,
"processingTimeMs": 3420,
"createdAt": "2025-07-15T10:30:00.000Z"
}
}| フィールド | 説明 |
|---|---|
id | 一意の抽出ID(ext_ プレフィックス付き) |
status | 実行中(非同期モード)は "processing"、データが正常に抽出された場合は "completed"、処理中にエラーが発生した場合は "failed" |
extractedData | テンプレートの変数名に一致するキーを持つオブジェクト。抽出が失敗した場合は null |
error | 抽出が失敗した場合のエラーメッセージ文字列。成功時は null |
processingTimeMs | AIがドキュメントを処理するのにかかった時間(ミリ秒) |
source | APIキー経由でトリガーされた場合は "api"、Web UIからトリガーされた場合は "dashboard" |
variables | この抽出に使用されたテンプレート変数定義 |
runId | 指定したバッチ識別子、または指定なしの場合は null |
templateName | 使用されたテンプレートの人間が読める名前 |
createdAt | 抽出が作成されたISO 8601タイムスタンプ |
TIP
extractedData にアクセスする前に、必ず status フィールドを確認してください。status が "failed" の場合、error フィールドに何が問題だったかの説明が含まれています。
バッチ抽出
複数のファイルを論理的なバッチとして処理するには、各抽出リクエストに同じ runId を渡します。これはドキュメントの処理方法を変えるものではありません -- 各ファイルは個別に抽出されます -- ただし、バッチからのすべての結果をまとめてクエリできるようになります。
const runId = "batch-invoices-2025-07";
const files = ["invoice-001.pdf", "invoice-002.pdf", "invoice-003.pdf"];
// 同じrunIdで各ファイルを処理
const results = await Promise.all(
files.map(async (fileName) => {
const pdfBase64 = readFileSync(fileName).toString("base64");
const response = await fetch("https://api.docmap.io/v1/extractions/run", {
method: "POST",
headers: {
Authorization: "Bearer dm_live_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
templateId: "tmpl_abc123",
fileName,
pdfBase64,
mimeType: "application/pdf",
runId,
}),
});
return response.json();
})
);次に、バッチからすべての抽出を取得します:
curl "https://api.docmap.io/v1/extractions?runId=batch-invoices-2025-07" \
-H "Authorization: Bearer dm_live_your_api_key"const response = await fetch(
"https://api.docmap.io/v1/extractions?runId=batch-invoices-2025-07",
{
headers: { Authorization: "Bearer dm_live_your_api_key" },
}
);
const { data } = await response.json();
console.log(`Batch contains ${data.length} extractions`);response = requests.get(
"https://api.docmap.io/v1/extractions",
params={"runId": "batch-invoices-2025-07"},
headers={"Authorization": "Bearer dm_live_your_api_key"},
)
data = response.json()["data"]
print(f"Batch contains {len(data)} extractions")TIP
一覧エンドポイントは templateId によるフィルタリングと limit パラメータ(1〜100、デフォルト50)もサポートしています。フィルタを組み合わせることができます: ?runId=batch-001&templateId=tmpl_abc123&limit=100。
非同期ワークフロー
デフォルトでは、抽出リクエストは同期的です -- APIは処理が完了するまでブロックします。長時間実行される抽出の場合やHTTPタイムアウトを回避したい場合は、URLに ?async=true を追加して非同期モードを使用します。APIは即座に "processing" ステータスで応答し、結果の準備ができるまで別のエンドポイントをポーリングします。
送信 + ポーリングパターン
import { readFileSync } from "fs";
const API_BASE = "https://api.docmap.io";
const API_KEY = process.env.DOCMAP_API_KEY!;
// 1. 非同期で抽出を送信
const submitResponse = await fetch(`${API_BASE}/v1/extractions/run?async=true`, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
templateId: "tmpl_abc123",
fileName: "invoice.pdf",
pdfBase64: readFileSync("invoice.pdf").toString("base64"),
mimeType: "application/pdf",
}),
});
const { data: submitted } = await submitResponse.json();
console.log(`Extraction ${submitted.id} submitted, status: ${submitted.status}`);
// 2. 完了までポーリング
async function poll(extractionId: string): Promise<any> {
for (let i = 0; i < 30; i++) {
const res = await fetch(`${API_BASE}/v1/extractions/${extractionId}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
const { data } = await res.json();
if (data.status !== "processing") return data;
await new Promise((r) => setTimeout(r, 2000));
}
throw new Error("Extraction timed out");
}
const result = await poll(submitted.id);
console.log(`Final status: ${result.status}`);
console.log("Extracted data:", result.extractedData);import base64
import time
import requests
API_BASE = "https://api.docmap.io"
API_KEY = "dm_live_your_api_key"
headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
# 1. 非同期で抽出を送信
with open("invoice.pdf", "rb") as f:
pdf_base64 = base64.b64encode(f.read()).decode("utf-8")
submit_response = requests.post(
f"{API_BASE}/v1/extractions/run?async=true",
headers=headers,
json={
"templateId": "tmpl_abc123",
"fileName": "invoice.pdf",
"pdfBase64": pdf_base64,
"mimeType": "application/pdf",
},
)
submitted = submit_response.json()["data"]
print(f"Extraction {submitted['id']} submitted, status: {submitted['status']}")
# 2. 完了までポーリング
def poll(extraction_id: str):
for _ in range(30):
res = requests.get(
f"{API_BASE}/v1/extractions/{extraction_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
)
data = res.json()["data"]
if data["status"] != "processing":
return data
time.sleep(2)
raise TimeoutError("Extraction timed out")
result = poll(submitted["id"])
print(f"Final status: {result['status']}")
print("Extracted data:", result["extractedData"])非同期モードを使用するタイミング
大きなドキュメントを処理する場合、HTTPクライアントのタイムアウトが短い場合、または複数の抽出を送信して後で結果を収集したい場合に非同期モードを使用してください。ほとんどの単一ドキュメントの抽出には、同期モードの方がシンプルです。
完全なワークフロー例
以下は、ディスクからPDFを読み込み、抽出を実行し、成功と失敗の両方を処理するTypeScriptによるエンドツーエンドの完全な例です:
import { readFileSync } from "fs";
const API_BASE = "https://api.docmap.io";
const API_KEY = process.env.DOCMAP_API_KEY!;
async function extractInvoice(filePath: string) {
// 1. PDFを読み込みエンコード
const pdfBuffer = readFileSync(filePath);
const pdfBase64 = pdfBuffer.toString("base64");
const fileName = filePath.split("/").pop()!;
console.log(`Processing ${fileName} (${(pdfBuffer.length / 1024).toFixed(0)} KB)...`);
// 2. 抽出を実行
const response = await fetch(`${API_BASE}/v1/extractions/run`, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
templateId: "tmpl_invoice_parser",
fileName,
pdfBase64,
mimeType: "application/pdf",
}),
});
if (!response.ok) {
const error = await response.json();
throw new Error(`API error ${response.status}: ${error.error.message}`);
}
const { data } = await response.json();
// 3. 抽出結果を確認
if (data.status === "failed") {
console.error(`Extraction failed: ${data.error}`);
return null;
}
console.log(`Extraction completed in ${data.processingTimeMs}ms`);
console.log("Extracted data:", JSON.stringify(data.extractedData, null, 2));
return data.extractedData;
}
// 実行
extractInvoice("./invoices/invoice-001.pdf")
.then((result) => {
if (result) {
console.log(`Vendor: ${result.vendor_name}`);
console.log(`Total: $${result.total_amount}`);
}
})
.catch(console.error);