フォーム ID

仕組み

送信データが通過するすべてのチェックを順番に、それぞれが返しうる応答とあわせて説明します。

/f/<formId> への送信は、すべて同じパイプラインを通ります。コストの低いチェックから先に実行するので、大量送信や存在しないフォームへの送信にはほとんどコストがかかりません。最初に失敗したチェックが応答を決めます。

送信データが通過するチェック(順番どおり)

ボディを読む前

  1. 1大量送信ガードIP ごとに 1 分あたり 600 件、全フォーム合計429 rate_limited
  2. 2フォームの検索存在しない、削除済み、無効なフォーム404 not_found
  3. 3フォームのレート制限フォームのプリセット。訪問者ごととフォームごと429 rate_limited
  4. 4一時停止ダッシュボードでフォームが一時停止されている403 form_paused

送信を読み取る

  1. 5解析urlencoded、multipart、JSON、UTF-8、サイズ上限400、413、415、422
  2. 6API キーAuthorization ヘッダーが送られた場合のみ403 forbidden
  3. 7許可ドメインOrigin または Referer をフォームのドメインと照合スパム、または 403
  4. 8人間確認確認がオンの場合の Turnstile トークン403、または確認ページ

判定する

  1. 9バリデーション公開済みのフィールドがあれば、それと照合422 validation_failed
  2. 10スコアハニーポット、時間、リンク、キーワード、重複5 以上でスパム
  3. 11冪等性同じキーなら最初の応答を再送再送、409、422
  4. 12月間の使用量ワークスペースの上限を大きく超えている429 quota_exceeded

保存

送信データを保存

コードには 201、ブラウザーには 303

  • Webhook署名付き、約 3 日間リトライ
  • 通知メールフォームの受信者へ
  • ダッシュボードと APIすぐにリアルタイムで反映

スパムも保存され、成功と同じ応答を返しますが、何も送信されません。

各ステージの役割

何よりも先にレート制限

レート制限はボディを読む前に実行されます。大量送信ガード(IP ごとに 1 分あたり 600 件)はフォームの検索よりも前に動くので、大量送信がデータベースに届くことはありません。フォーム独自のルールは検索の直後に実行されます。拒否されたリクエストは許容量を消費しません。正確な数値はレート制限にあります。

解析

ボディは urlencoded、multipart、JSON として解析されます。テキストは UTF-8 としてデコードされ、NFC に正規化され、CRLF は LF に変換され、制御文字は削除されます。_ で始まる名前は _redirect や _subject などの予約済みの指示で、回答として保存されることはありません。HTML フォームを参照してください。

送信元の判定

Authorization: Bearer ヘッダーは任意です。submissions:write スコープを持つシークレットキー(ik_sk_)は、許可ドメインのチェックと Ikiform の人間確認をスキップします。公開可能キー(ik_pub_)は、キーに登録されたドメインからのみ使えます。キーがない場合は、Origin で送信を判定します。

スパム

スパムがエラーになることはありません。スパムモードで許可ドメインのポリシーに違反した送信や、スコアが 5 以上の送信は、ステータス spam で保存され、本物の送信と同じ成功の応答を返すので、ボットは何も学べません。スパムは Webhook もメールも送らず、使用量にもカウントされません。スパム対策を参照してください。

保存と配信

送信データ、その Webhook の配信、通知メールは 1 回のデータベースバッチで書き込まれ、キューに渡されます。Webhook の配信やメールが応答を遅くすることはなく、配信なしで送信データだけが保存されることもありません。

JSON かリダイレクトか

同じエンドポイントが、ブラウザーにはページで、コードには JSON で応答します。Ikiform はリクエストごとに判断します:

Ikiform が JSON の応答とリダイレクトのどちらを返すかの判定(上から順に確認)
  1. 1Accept に application/json が含まれるJSON
  2. 2ボディが JSONJSON
  3. 3Sec-Fetch-Mode: navigateリダイレクトまたはページ
  4. 4それ以外の Sec-Fetch-Mode(cors など)JSON
  5. 5Sec-Fetch-Mode がなく、Accept に text/html が含まれるリダイレクトまたはページ
  6. 6それ以外すべて(curl など)JSON

最初に一致したルールが適用されます。

JSON モードでは、成功すると 201 { "ok": true, "id": "sub_..." } を返します。ページモードでは成功すると 303 リダイレクトになり、エラー時はフィールドの問題をラベルごとに一覧にした、ホストされたエラーページを表示します。

送信データの保存後

内容タイミング詳細
Webhook数秒後。約 3 日間リトライWebhook
通知メール数秒後(フォームで通知がオンの場合)フォームごとに 1 時間あたり 50 通まで(作成から 7 日未満のワークスペースは 10 通)。それを超えると 1 時間ごとのダイジェスト 1 通
ダッシュボードすぐに、リアルタイムでスパムはスパムフィルターの下に表示
REST APIすぐにREST API
パスワード、カード番号、シードフレーズのようなフィールド名を含む送信データがあるフォームにはフラグが付き、通知メールは確認のため保留されます。フォームバックエンドで認証情報を集めないでください。

ID

ID形式メモ
フォームfrm_xxxxxxxxxxxxxxxxfrm_ に続くランダムな 16 文字。公開情報で、フォームの action の URL に含まれます。
送信データsub_01k7v2c9t3e8m5q4x6z0a1b2c3sub_ に続く 26 文字で、時刻順に並びます。
Webhook の配信dlv_...webhook-id として送られ、リトライしても変わりません。
リクエストreq_...すべてのレスポンスに X-Request-Id ヘッダーが付きます。サポートに問い合わせるときに伝えてください。
{ "ok": true, "id": "sub_01k7v2c9t3e8m5q4x6z0a1b2c3" }