--- title: 不正対策 — 広告不正 --- # 広告不正 これは **シナリオガイド** です。コア連携は変わりません——[Web SDK](../web-sdk) を読み込み、 [判定](../verdict-reference) を読み、[Data API](../data-api) からデータを取得する、という それらのページに記載のとおりです。本ページでは、広告不正シナリオだけが必要とする わずかな固有要素を補足します。 広告不正対策は、ボットと無効トラフィックを有料投放から締め出し、広告主と広告プラットフォームが 本物のクリックとインプレッションに対してのみ——虚偽のボリュームではなく——支払うようにします。 他のユースケースと異なる点は、**訪問者を第三者が届ける** ことであり、双方が独立した クリック単位の人間 / ボット結論で合意する必要があることです。 ## 源流でのリアルタイム遮断 Fraud Prevention はエントリーポイントで inline に動作し、判定をリアルタイムで返します——事後レポートではありません。訪問者が着地するページを所有する者は、その判定に基づいて即座に対処できます: - **広告主** はランディングページで SDK を実行します:無効トラフィックは到達した瞬間に検出され——オプションで Challenge を提示——ファネルに入る前、レポートを歪める前に止められます。 - **トラフィックプラットフォーム** は自前の pre-lander またはリダイレクトページで SDK を実行します:クリックは転送される *前* に検証されるため、ボットは入口で止められ、配信トラフィックになることはありません。 唯一の前提は、SDK を実行できるページがあることです:判定にはブラウザ信号が必要なため、純粋なサーバーサイドの 302 にはそれを収集する場所がありません——軽量な中間ページを 1 枚追加すれば、同じリアルタイム遮断が適用されます。 署名済み click token と Data API はその上に乗り、両サイドの突き合わせを行います。リアルタイムの inline 遮断が主要なメカニズムであり、事後の API スクラビングは中間ページがないトラフィック向けのフォールバックです。 ## 2 つの役割 - **広告主(Advertiser)** — 訪問者が到達するランディングページを所有します。そのページ上で Web SDK を実行して到達する各アクセスの判定を取得し、Data API から判定を取得して、 自分が課金された分を突き合わせます。 - **サービス提供者(Provider、トラフィック / 広告ソース)** — クリックを配信します。 **自分が送ったものの品質を証明する** 必要があるため、クリックごとにクリックトークンを発行し、 後で自分の配信レポートを独立した判定と突き合わせます。 双方は自分のアプリケーション認証情報で [Data API](../data-api) に認証し、同じクリック単位の 判定を読み取ります。これにより、互いの生ログを信頼せずとも突き合わせができます。 ## エンドツーエンドのフロー 下のシーケンスは、1 つのクリックが provider の配信から、訪問者と広告主のランディングページを 経て、**両アカウントが後にそれぞれ自分の側から読み取る** 単一の判定に至るまでを示します。 ```mermaid sequenceDiagram autonumber participant P as 提供者(Provider / アカウント B) participant V as 訪問者(Visitor) participant A as 広告主ランディングページ + SDK participant F as 不正対策バックエンド(Fraud Prevention API) P->>P: 自分の bot_kid + secret で click_token に署名(pkid を含む) P->>V: token を配信リンクに付与 ?_ctk=click_token V->>A: クリック → 広告主ランディングページに着地(URL に _ctk を保持) A->>A: SDK が URL から _ctk を読み取る A->>F: 暗号化 POST /bot/verify
(app_key = 広告主、click_token = provider が署名) F->>F: app_key → advertiser_app_id,
pkid を検証 → provider_app_id, 判定を出す,
両端の app_id を 1 行に書き込む F-->>A: verdict → onVerdict A->>A: verdict.action に従って処理(記録 / ブロック / チャレンジ) Note over P,F: 突き合わせ(クロスアカウント) A->>F: 広告主が自分の App-Key で GET /v1/bot F-->>A: 同じ行を読む(advertiser_app_id で一致) P->>F: 提供者が自分の App-Key で GET /v1/bot F-->>P: 同じ行を読む(provider_app_id で一致) ``` 決定的な性質はこうです。**両方の app_id が同じ行に存在します。** 広告主は `advertiser_app_id` で一致させてそれを読み、provider は `provider_app_id` で一致させてそれを読みます——2 つの 異なるアカウントが、それぞれ自分の App-Key で問い合わせ、それぞれ同じ独立した判定に着地します。 どちらの側も、あるクリックで何が起きたかについて合意するために、相手の生ログを露出させたり 信頼したりする必要はありません。 ## クリックトークン **クリックトークン(click token)** は、provider が配信したクリックを、そのアクセスが最終的に 受け取る判定と結びつけます。これは双方が精算の拠り所とするクリック単位の識別子です。 不正対策の他のユースケースはクリックトークンを必要としません——それらはトークンなしで 判定を突き合わせます。 フロー: 1. **発行** — provider は、訪問者を広告主のランディングページへルーティングする際に、 署名済みのクリックトークン(クリックごとに 1 つ)を取得します。 2. **遷移先 URL に付与する** — 発行されたトークンを、ランディング URL にクエリパラメータとして 付与します。 ``` https://advertiser.example/lp?click_token=ct_xxxxxxxx ``` 3. **ページで読み取る** — [Web SDK](../web-sdk) が URL からトークンを自動的に読み取ります。 別のパラメータ名を使う場合は `tokenParam` を設定します。 ```js BotSignal.init({ appKey: 'YOUR_APP_KEY', tokenParam: 'click_token' }); ``` 4. **突き合わせる** — 後で Data API 経由でそのクリックを照会し、provider の配信レポートに 結合します。 ::: info トークンはあなたに発行される時点で既に署名済みです——あなたは **それをランディング URL まで そのまま運ぶ** だけでよいのです。あなたの側で署名や計算を行うものは何もありません。 ::: ### `tokenParam` オプション このシナリオでは、Web SDK に追加のオプションが 1 つ加わります。 | オプション | 型 | デフォルト | 説明 | | --- | --- | --- | --- | | `tokenParam` | string | 自動検出 | provider のクリックトークンを運ぶ URL クエリパラメータの名前(例:`click_token`)。SDK がそれをページ URL から読み取り、判定をそのクリックに結びつけます。クリックトークンを使わない場合は未設定のままにします。 | ## 突き合わせと精算 アクセスがクリックトークンを運ぶようになると、双方は同じ独立した判定で精算します。 - **単一クリックの判定を取得する** — 例えば 1 つのクリックを争う、または確認する場合: ```bash GET /v1/bot/verdict?click_token=ct_xxx X-App-Key: YOUR_APP_KEY X-App-Secret: YOUR_APP_SECRET ``` - **クリック単位の行をエクスポートする** — 時間範囲を取得し、各行の `click_token` を あなた自身のクリックログに結合します: ```bash GET /v1/bot/export?from=2026-06-01&to=2026-06-30&format=csv X-App-Key: YOUR_APP_KEY X-App-Secret: YOUR_APP_SECRET ``` 各行は、そのアクセスの `click_token`(存在する場合)、タイムスタンプ、判定フィールド (`is_bot`、`score`、`level`、`action`)を含みます。 広告主はフラグ付き/ボットのクリックを支払い対象から除外し、provider は同じ結論に対して 自分の配信レポートを突き合わせます。双方が読むのは **同じ独立した判定** なので、精算は どちらの側の生ログにも依存しません。 ## セキュリティモデル `cid` とクリックトークンは URL に乗って運ばれるため、認証情報ではなく識別子として扱ってください: - **判定の読み取りには App-Key + App-Secret が必要です。** Data API はすべての呼び出しをあなたの app secret で認証し(定数時間で比較)、あなたのアプリが advertiser または provider である行だけを返します。`cid` だけでは何も取得できません——URL からそれをコピーした第三者は secret を持たず、その行の当事者でもありません。 - **provider は署名で束縛されます。** クリックトークンは provider の secret で HMAC 署名され、provider の `pkid` を含みます。偽造はできず、同一の `cid` は一度しか主張できません(リプレイ保護)。 - **任意で advertiser も束縛できます。** 対象 advertiser の `app_key` を `aud` としてトークンに署名します。すると検証はページの app_key が `aud` と一致することを要求するため、advertiser A 向けに発行されたトークンは advertiser B の判定に帰属させられません。`aud` を省けば、どの advertiser ページもそのトークンを受け入れられます。 正味の効果:ある `cid` の判定は、それに束縛された 2 つのアプリ——SDK を実行したページの advertiser と、トークンを提示した provider——だけが読め、それぞれが自分の App-Secret で認証します。 ## 次のステップ - [Web SDK](../web-sdk) — ランディングページで判定を収集する - [Verdict リファレンス](../verdict-reference) — すべてのフィールドと、その対処方法 - [Data API](../data-api) — サーバーサイドで判定を取得・突き合わせる