FormRead Web API 統合開発者ガイド

Oscar Munoz Oscar Munoz · · 読了時間 5 分

FormRead API の仕組み

FormRead API は2つの部分に分かれています:フォーム管理用の REST API(作成、更新、削除、データ保存)、およびフォーム編集やスキャン文書の読み取り用の埋め込み可能な iframe です。API 単独ではフォームの処理や読み取りは行わず、読み取りは完全に iframe を通じて処理されます。

  • REST API(このページ): フォームのメタデータの作成、更新、削除、取得に使用します。API はフォームデータを保存し、iframe の埋め込みに必要なトークンを返します。
  • Iframe(埋め込みビューアー): フォームテンプレートの編集、スキャン文書のアップロード、結果の抽出(OMR、OCR、BCR)に使用します。すべてのフォーム読み取りとデータ抽出は iframe 内で行われます。

サーバー間処理をお探しですか?

ビジュアルインターフェースが不要で、画像を送信して結果をJSONで受け取りたいだけなら、サーバーサイド処理APIをご確認ください。

一般的な統合ワークフロー

  1. ダッシュボードから生成された Bearer トークンで認証します。
  2. POST /api/forms エンドポイントを使用してフォームを作成し、iframe_token を取得します。
  3. iframe_token を使用して iframe をページに埋め込み、ユーザーがフォームを編集してドキュメントをスキャンできるようにします。
  4. iframe イベント(editForm、getResults、rowResult)をリッスンしてフォームデータと抽出結果を受信し、それらをシステムに保存します。

認証

エンタープライズ用途では、Bearer認証トークンを生成してAPIを使用できます。

FormRead ダッシュボードにログインし、APIトークンオプションにアクセスします:

API Tokensオプションが強調表示されたFormReadダッシュボードメニュー

サードパーティサービスがあなたの代わりに当社のアプリケーションで認証できるように、APIトークンを作成します:

権限チェックボックス付きの新しいFormRead APIトークンの作成

生成されたトークンを安全な場所にコピーしてください(一度しか表示されません):

生成されたFormRead API Bearerトークンは一度だけ表示されます - コピーして安全に保管してください

新規フォーム作成

POST /api/forms

ヘッダー

名前 値
Authorization Bearer YOUR_API_TOKEN
Accept application/json

リクエスト

curl --location --request POST 'https://formread.org/api/forms' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --form 'form_name="new form"' \
  --form 'custom_css="{ingest custom css to edit FormRead View}"'

回答

{
  "id": 8,
  "form_name": "new form",
  "iframe_token": "6ifvCyEcjB3D5SGqtFmJ5eg0sPYNQfLoWCEgv7bb",
  "created_at": "2022-02-28T21:22:55.000000Z",
  "updated_at": "2022-02-28T21:22:55.000000Z"
}

変数 custom_css により、CSSルールを取り込んでFormReadの外観を編集し、カスタムテキストを追加できます。例:

#app-title::after{
  content: 'Your Tittle';
  color: white;
}
#app-subtitle::after{
  content: 'Your Custom sub-tittle Your Custom sub-tittle Your Custom sub-tittle';
  color: white;
}
#upload-from-cam{
  display: none;
}
#upload-from-system{
  background: lightblue;
}
#upload-from-csv{
  display: none;
}
#app > div.bg-gray-50.h-screen.overflow-auto > div > div{
  background-color: black;
}

IDでフォームを取得

GET /api/forms/{form_id}

リクエスト

curl --location --request GET 'https://formread.org/api/forms/8' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN'

回答

{
  "id": 8,
  "form_name": "adsf",
  "iframe_token": "po75a0pqut4fa16XWgdEP2qRDwnhgfiqP3H0Dij6",
  "created_at": "2022-02-28T21:22:55.000000Z",
  "updated_at": "2022-03-01T01:40:19.000000Z"
}

フォームを編集

フォームが作成されるかGETされた後、レスポンスで提供されるiframe_tokenを使用してIframeに表示できます(このトークンは変動するため、iframeを表示する前に必ずフォームをGETしてください)

以下の例のように、iframeのイベントをリッスンするスクリプトも作成してください:

<!DOCTYPE html>
<html style="height: 100%">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body style="height: 100%">

<iframe src="https://formread.org/{lang}/api/forms/{form_id}/edit/{iframe_token}/{read_only}"
        style="height: 100%; width: 100%"></iframe>

<script>
    window.addEventListener('message', function (e) {
        // if (e.origin !== 'https://formread.org') return;

        console.log(e.data.method)

        if (e.data.method === "editForm") {
            let formData = e.data.formData // data used to saved your form
            let schema = JSON.parse(e.data.schema)
            console.log(schema)
            console.log(formData)
        }
        if (e.data.method === "getResults") {
            let results = JSON.parse(e.data.results)
            console.log(results)
        }
        if (e.data.method === "rowResult") {
            let rowResult = JSON.parse(e.data.rowResult)
            console.log(rowResult)
        }
    });
</script>
</body>
</html>

iframeのURLパラメータ

パラメーター 説明
lang アプリのコマンドを希望の言語で表示するには、lang 変数を設定します。現在、英語 (en)、フランス語 (fr)、スペイン語 (es)、ブラジルポルトガル語 (pt)、ヒンディー語 (hi) をサポートしています。
read_only 変数 read_only は、フォームの編集を無効にする場合は 1、編集を許可する場合は 0 に設定できます。

iframeのイベント

ユーザーが保存ボタンをクリックすると、<code class="language-plaintext">editForm</code>メソッドがトリガーされ、そこで2つの変数にアクセスできます:

  • formData変数には、フォームに加えられた変更を保存するために更新を使用して送信できるエンコードされたフォーム属性が含まれます:
  • schema変数により、これまでに作成されたフィールドを確認できます:
    {
      "file_name": {
        "type": "text"
      },
      "BCR-0": {
        "type": "text"
      },
      "OCR-1": {
        "type": "text"
      },
      "OMR-2-0": {
        "type": "select",
        "options": ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
        "questionIndex": "0"
      },
      "OMR-2-1": {
        "type": "select",
        "options": ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
        "questionIndex": "1"
      },
      "OMR-2-2": {
        "type": "select",
        "options": ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
        "questionIndex": "2"
      }
    }

    schema変数は、必須エリアフィールドの作成が必要な場合にユーザーにアラートを表示するためのものです:

ユーザーが結果のダウンロードをクリックすると、getResultsメソッドがトリガーされ、そこで結果データをJSON形式で取得できるため、システムに保存できます。

また、ページが処理されるたびにトリガーされるrowResultメソッドを使用して、行ごとの結果を取得できます。

フォームを更新

PUT /api/forms/{form_id}

リクエスト

curl --location --request POST 'https://formread.org/api/forms/8?_method=PUT' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --form 'form_data="eyJ2dWV4X3N0YXRlIjp7ImZvcm1OYW1lIjoiYWRzZiIsImZvcm1zIjp7f
                     Swic2VsZWN0ZWRGb3JtSWQiOiIiLCJmb3JtUmVhZEFyZWFzIjp7IkJDUi
                     0wIjp7ImNvbHVtblBvc2l0aW9uIjoxLCJ3aWR0aCI6MC4xMTQ5NTA0NTM
                     0MDUzNTE2NCwiaGVpZ2h0IjowL...' \
  --form 'custom_css="{ingest custom css to edit FormRead View}"'

回答

{
  "id": 8,
  "form_name": "adsf",
  "iframe_token": "po75a0pqut4fa16XWgdEP2qRDwnhgfiqP3H0Dij6",
  "created_at": "2022-02-28T21:22:55.000000Z",
  "updated_at": "2022-03-01T02:30:14.000000Z"
}

フォームを削除

DELETE /api/forms/{form_id}

リクエスト

curl --location --request DELETE 'https://formread.org/api/forms/8' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN'

回答

1

完全な例: 採点ワークフローの埋め込み

以下は、教師がフォームをデザインし、試験をスキャンし、採点結果をあなたのバックエンドにプッシュする方法を示すエンドツーエンドの例です。すべてFormRead iframeを埋め込んだ単一のページから行えます。

シナリオ

教師があなたのアプリを開き、「Math 101 - Midterm」の解答用紙をデザインし、印刷し、記入済みの試験をスキャンし、「結果をダウンロード」をクリックします。あなたのページはiframeのイベントをリッスンし、レイアウトを保存し、採点された回答をあなたの採点システムにポストします。

ステップ1 - サーバーからフォームを作成する

バックエンドで、教師用のフォームを作成します。idとiframe_tokenが返されます。これらを次のステップでiframeのURLに渡します。

# From YOUR backend (never from the browser)
curl --location --request POST 'https://formread.org/api/forms' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --form 'form_name="Math 101 - Midterm"'
{
  "id": 42,
  "form_name": "Math 101 - Midterm",
  "iframe_token": "6ifvCyEcjB3D5SGqtFmJ5eg0sPYNQfLoWCEgv7bb",
  "created_at": "2026-04-20T10:00:00.000000Z",
  "updated_at": "2026-04-20T10:00:00.000000Z"
}

idとiframe_tokenを、あなた自身のデータベースの教師レコードに関連付けて保存します。これらを使用して、ステップ2で編集可能なiframeをレンダリングします。

ステップ2 - 編集可能モードでiframeを開く

あなたのバックエンドは、read_only=0を指定したFormRead iframeを含むページをレンダリングします。これにより、教師はシート上にOMRバブル、OCR領域、バーコードを描画できます。iframe内で「保存」をクリックすると、editFormイベントが発生し、ブラウザは生のformDataをあなたのバックエンドに転送します。ブラウザが直接FormReadを呼び出すことはありません。

<!-- /design-form page rendered by YOUR backend.
     read_only = 0 → editable mode -->
<iframe id="formread-frame"
        src="https://formread.org/en/api/forms/42/edit/6ifvCyEcjB3D5SGqtFmJ5eg0sPYNQfLoWCEgv7bb/0"
        style="width:100%; height:100vh; border:0"></iframe>

<script>
    // The browser ONLY talks to your own backend. Never to FormRead.
    const FORM_ID = 42;

    window.addEventListener('message', async function (e) {
        if (e.origin !== 'https://formread.org') return;

        // Teacher clicked "Save" inside the iframe
        if (e.data.method === 'editForm') {
            await fetch(`/api/forms/${FORM_ID}/layout`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ form_data: e.data.formData })
            });
        }
    });
</script>

ステップ3 - バックエンドからレイアウトを永続化する

あなたのバックエンドはformData文字列を受け取り、あなたのBearerトークン(これはサーバーから決して離れません)を使用して、PUTでFormReadに転送します。これによりフォーム設定が永続的に保存され、後で同じフォームを試験のスキャンに再利用できます。

# Inside your backend handler for POST /api/forms/42/layout
# $formData is the raw string your browser posted.
curl --location --request POST 'https://formread.org/api/forms/42?_method=PUT' \
  --header 'Authorization: Bearer YOUR_API_TOKEN' \
  --form "form_data=${formData}"
{
  "id": 42,
  "form_name": "Math 101 - Midterm",
  "iframe_token": "po75a0pqut4fa16XWgdEP2qRDwnhgfiqP3H0Dij6",
  "created_at": "2026-04-20T10:00:00.000000Z",
  "updated_at": "2026-04-20T10:15:42.000000Z"
}

iframe_tokenはローテーションします

フォームの更新ごとに新しいiframe_tokenが返されます。iframeをレンダリングする直前に、常にバックエンドから最新のものを取得してください。ハードコードしたり長期にキャッシュしたりしないでください。

ステップ4 - 現在のiframe_tokenを取得する

後で、教師が試験をスキャンする準備ができたら、バックエンドはIDでフォームを読み取り、最新のiframe_tokenを取得します。

# From YOUR backend, right before rendering the scan page
curl --location --request GET 'https://formread.org/api/forms/42' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_TOKEN'
{
  "id": 42,
  "form_name": "Math 101 - Midterm",
  "iframe_token": "po75a0pqut4fa16XWgdEP2qRDwnhgfiqP3H0Dij6",
  "created_at": "2026-04-20T10:00:00.000000Z",
  "updated_at": "2026-04-20T10:15:42.000000Z"
}

ステップ5 - 読み取り専用モードでiframeを再度開き、スキャンする

iframeを再度レンダリングします。今回はURLの末尾にread_only=1を付けます。教師はレイアウトを編集できなくなり、スキャンのアップロードのみ可能です。ブラウザはrowResult(シートごとの進捗)とgetResults(最終ダウンロード)をあなたのバックエンドに転送します。

<!-- /scan-exams page. Note read_only = 1 at the end of the URL. -->
<iframe id="formread-frame"
        src="https://formread.org/en/api/forms/42/edit/po75a0pqut4fa16XWgdEP2qRDwnhgfiqP3H0Dij6/1"
        style="width:100%; height:100vh; border:0"></iframe>

<script>
    const FORM_ID = 42;

    window.addEventListener('message', async function (e) {
        if (e.origin !== 'https://formread.org') return;

        // Live progress while each sheet is processed
        if (e.data.method === 'rowResult') {
            const row = JSON.parse(e.data.rowResult);
            console.log('Processed', row.file_name);
        }

        // Teacher clicked "Download results"
        if (e.data.method === 'getResults') {
            const results = JSON.parse(e.data.results);

            await fetch('/api/grades/bulk', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ form_id: FORM_ID, results })
            });
        }
    });
</script>

ステップ6 - バックエンドで結果を処理する

getResultsイベントは、処理された試験ごとに1つのエントリを持つ配列を配信します。キーはパターン{AreaType}-{AreaIndex}[-{QuestionIndex}]に従います。以下は、ブラウザがあなたの/api/grades/bulkエンドポイントにポストするものの例です。

[
  {
    "file_name": "student_001.jpg",
    "BCR-0": "20260420-001",
    "OCR-1": "Alice Johnson",
    "OMR-2-0": "3",
    "OMR-2-1": "7",
    "OMR-2-2": "9"
  },
  {
    "file_name": "student_002.jpg",
    "BCR-0": "20260420-002",
    "OCR-1": "Ben Carter",
    "OMR-2-0": "3",
    "OMR-2-1": "6",
    "OMR-2-2": "9"
  }
]

トークンはサーバー上に保持する

Bearer トークンをブラウザ向けのコードで公開しないでください。FormRead API へのすべての作成/更新/読み取り呼び出しは、独自のバックエンドを経由します。ブラウザが目にするのは、単一のフォームにスコープされた iframe_token だけです。

よくある質問

FormRead Iframe Integration API とは何ですか?

REST API と埋め込み可能な iframe を組み合わせたものです。バックエンドは REST エンドポイントを通じてフォームを管理し、iframe は Web アプリ内にレンダリングされるため、ユーザーはインターフェースを離れることなくフォームの設計、スキャンのアップロード、結果の確認ができます。

iframe_token は期限切れになったり、変更されたりしますか?

iframe_token は、フォームが更新されるたびに再生成されます。iframe をレンダリングする直前に、バックエンドから FormRead REST API (GET /api/forms/{id}) で常に最新の値を取得してください。長期間キャッシュしないでください。

read_only=0 と read_only=1 の違いは何ですか?

read_only=0 は iframe を編集可能モードで開き、ユーザーがフォームを設計できるようにします(OMR バブル、OCR、バーコード領域の配置)。read_only=1 はスキャンモードのみで開き、ユーザーは記入済みのシートをアップロードして結果をダウンロードできますが、レイアウトを変更することはできません。

API トークンをブラウザに保存できますか?

いいえ。Bearer トークンはサーバー上に保持する必要があります。FormRead REST API へのすべての作成、更新、読み取り呼び出しは、独自のバックエンドを介してプロキシする必要があります。ブラウザに必要なのは、単一のフォームにスコープされた iframe_token だけです。

スキャン結果をどのように受け取りますか?

iframe は window.postMessage を介してメッセージを送信します。method="getResults" をリッスンして、スキャンされた全結果の配列(スキャンされたシートごとに 1 エントリ)を受け取り、method="rowResult" をリッスンして、スキャン中のシートごとの進行状況を表示します。

Postman コレクションリンク

Postmanコレクションを開く

手作業での採点をやめましょう。

今すぐFormReadを活用しましょう:フォームを作成し、最初のシートをスキャンすれば、数分で構造化された結果が得られます。

今すぐ開始 — クレジットカード不要