開発者向け
Formalini API
ドキュメントと抽出されたフィールドの読み取り、自社システムからのドキュメント登録、値の修正、変更時の署名付き Webhook 受信を行えます。以下のすべてのサンプルコードは curl、JavaScript、Python、PHP、C# で記載されています。
ベース URL
すべてのエンドポイントはこのベース URL の下にあります。JSON の送受信に対応しています。
https://api.formalini.com/api/public/v1短縮アドレス api.formalini.com は現在利用可能です。上記に表示されているアドレスとなります。
認証
アプリ内の「連携」で API キーを作成し、各リクエストで Bearer トークンとして送信してください。キーは特定のワークスペースに紐づき、そのワークスペースのデータのみにアクセスできます。
documents.read— ドキュメントおよびフィールドの読み取りdocuments.write— ドキュメントの作成およびフィールドの修正workflows.run— オンデマンドでの Webhook へのイベント送信
各キーには1分あたりのリクエスト制限(デフォルト60件)が設定されています。レスポンスには X-RateLimit-Limit および X-RateLimit-Remaining が含まれ、上限を超えると Retry-After とともに 429 が返されます。
ドキュメント一覧の取得
GET /documents?limit=25&status=approved — documents.read
新しい順に取得されます。limit は 1〜100(デフォルト25)、status で queued、processing、review、approved、exported、failed ごとにフィルタリングできます。
curl -X GET "https://api.formalini.com/api/public/v1/documents?limit=25&status=approved" \
-H "Authorization: Bearer pf_live_your_key"{
"documents": [
{
"id": "b0f1c8d2-5a71-4c0e-9f2a-1d4b6e8c3a90",
"name": "Job sheet 4821.jpg",
"status": "approved",
"average_confidence": 0.94,
"source": "upload",
"created_at": "2026-09-11T09:12:04.000Z",
"fields": [
{ "name": "engineer", "value": "M. Byrne", "type": "text",
"confidence": 0.97, "page": 1, "valid": true }
]
}
]
}修正された値は元の読み取り結果を上書きするため、常に value に指定された値をご使用ください。
単一ドキュメントの取得
GET /documents/{id} — documents.read
ドキュメントを、そのカテゴリー、取引先、金額、日付、およびすべてのフィールドとともに返します。
curl -X GET "https://api.formalini.com/api/public/v1/documents/b0f1c8d2-5a71-4c0e-9f2a-1d4b6e8c3a90" \
-H "Authorization: Bearer pf_live_your_key"ファイルのアップロードとデータ取得
POST /documents/upload — documents.write
ページ画像を送信すると、同一レスポンス内で構造化データが返されます。ドキュメントは通常のスキャンと同様にワークベンチの受信トレイに表示され、1ページあたり1つの AI クレジットを消費し、完了時に Webhook を送信します。
file— ページ画像。複数ページのドキュメントの場合は、1ページにつき1回フィールドを繰り返します(最大25ページ)。name— ドキュメント名(任意)。省略した場合はファイル名が使用されます。template_id— テンプレート ID(任意)。指定すると、カスタム名が割り当てられたフィールドが返されます。async— true に設定すると即座に 202 が返され、GET /documents/{id} をポーリングして結果を取得できます
curl -X POST "https://api.formalini.com/api/public/v1/documents/upload" \
-H "Authorization: Bearer pf_live_your_key" \
-F "file=@invoice-page-1.jpg" \
-F "file=@invoice-page-2.jpg" \
-F "name=Invoice 2026-0041"{
"document": {
"id": "8c2a1f76-4d33-4a1e-8f10-72b9e5c4a118",
"name": "Invoice 2026-0041",
"status": "review",
"average_confidence": 0.93,
"vendor": "Northbridge Supplies",
"amount": 1249.5,
"currency": "EUR",
"document_date": "2026-09-14",
"pages": 2,
"credits_spent": 2,
"fields": [
{ "name": "invoice_number", "value": "2026-0041", "type": "string",
"confidence": 0.98, "page": 1, "valid": true }
]
}
}JPEG、PNG、WebP、HEIC に対応しており、1ページあたり最大 100 MB です。1ページの読み取りには数秒かかるため、タイムアウトを長めに設定するか async=true を使用してください。402 はワークスペースのクレジット、ストレージ、または1日の利用上限が不足していることを意味し、レスポンスにその詳細が記載されます。
現在ここでは PDF に対応していません。各ページを JPEG または PNG にレンダリングし、複数の file フィールドとして送信してください。アプリ内での PDF アップロードはブラウザ上でページがレンダリングされるため、引き続き利用可能です。
ドキュメントの作成
POST /documents — documents.write
すでにデータが存在するドキュメントを登録します。name は必須、fields は任意で最大400件まで指定可能です。fields があるドキュメントは「確認中」に、ないものは「キュー」に入ります。
curl -X POST "https://api.formalini.com/api/public/v1/documents" \
-H "Authorization: Bearer pf_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Invoice 2026-0041.pdf",
"category": "invoice",
"vendor": "Northbridge Supplies",
"amount": 1249.5,
"document_date": "2026-09-14",
"fields": [
{
"name": "invoice_number",
"value": "2026-0041",
"type": "text",
"confidence": 0.99,
"page": 1
},
{
"name": "total",
"value": "1249.50",
"type": "number",
"confidence": 0.96,
"page": 1
}
]
}'{
"document": {
"id": "8c2a…",
"name": "Invoice 2026-0041.pdf",
"status": "review",
"created_at": "2026-09-18T10:02:11.000Z",
"fields": 2
}
}ドキュメントの更新
PATCH /documents/{id} — documents.write
ステータスの変更や、フィールド名指定での値修正を行います。ステータスを approved、exported、または review に設定すると、対応する Webhook もトリガーされます。
curl -X PATCH "https://api.formalini.com/api/public/v1/documents/b0f1c8d2-5a71-4c0e-9f2a-1d4b6e8c3a90" \
-H "Authorization: Bearer pf_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"status": "approved",
"fields": [
{
"name": "total",
"value": "1249.50"
}
]
}'{ "ok": true, "updated_fields": 1 }Webhook のトリガー
POST /workflows/dispatch — workflows.run
購読しているすべてのアクティブな Webhook にイベントを送信し、オンデマンドで外部システムを起動できます。許可されているイベント:document.processed、document.needs_review、document.approved、document.exported。
curl -X POST "https://api.formalini.com/api/public/v1/workflows/dispatch" \
-H "Authorization: Bearer pf_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"event": "document.approved",
"document_id": "b0f1c8d2-5a71-4c0e-9f2a-1d4b6e8c3a90",
"payload": {
"target": "erp"
}
}'{ "ok": true, "event": "document.approved", "document_id": "b0f1…" }Webhook
アプリ内で Webhook URL を追加し、受信したいイベントを選択します。各配信は JSON 本文と署名ヘッダー(Webhook シークレットで署名)を含む POST リクエストです。
POST https://your-app.example.com/hooks/formalini
Content-Type: application/json
X-Paperflow-Signature: sha256=<hex hmac of the raw body>
{ "event": "document.processed", "document_id": "b0f1…", "payload": { … } }配信に失敗した場合は間隔を空けながら最大5回まで再試行され、アプリから手動で再送することも可能です。
配信を信頼する前に、未加工のリクエスト本文に対して署名を検証してください:
// Node.js
import crypto from "node:crypto";
function verify(rawBody, header, secret) {
const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const got = (header || "").replace(/^sha256=/, "");
return got.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected));
}
# Python
import hmac, hashlib
def verify(raw_body: bytes, header: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, (header or "").removeprefix("sha256="))
// PHP
$expected = hash_hmac('sha256', $rawBody, $secret);
$got = str_replace('sha256=', '', $_SERVER['HTTP_X_PAPERFLOW_SIGNATURE'] ?? '');
$ok = hash_equals($expected, $got);
// C#
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var expected = Convert.ToHexString(hmac.ComputeHash(rawBodyBytes)).ToLowerInvariant();
var ok = CryptographicOperations.FixedTimeEquals(
Encoding.UTF8.GetBytes(expected),
Encoding.UTF8.GetBytes(header.Replace("sha256=", "")));エラー
400— リクエスト本文が JSON ではないか、必須項目が不足しているか無効です401— キーが存在しないか、失効または期限切れです403— このエンドポイントに必要な権限がキーにありません404— このワークスペース内に指定された ID のドキュメントが見つかりません429— 1分あたりの上限に達しました。時間を置いてから再試行してください500— サーバー側でエラーが発生しました。詳細はレスポンスをご確認ください