---
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) — サーバーサイドで判定を取得・突き合わせる