EchoScan API・導入ガイド

EchoScan は、登録、ログイン、注文、決済、出金、クーポン取得、投票、フォーム送信、パスワードリセットなど、リスク判断が必要なアクセスや業務アクションでブラウザ環境の偽装、自動化アクセス、ネットワーク ID の異常を評価します。

基本フローはシンプルです。ブラウザで実行されるコードが imprint を生成し、保護対象のリクエストと一緒にサーバーへ送ります。サーバー側コードは EchoScan secret key で report を照会し、最終的なリスク判断を行います。

推奨フロー

  1. 保護したいアクセスまたは業務アクションを選びます。
  2. ブラウザで実行されるコードで Browser Verifier を呼び出し、imprint を生成します。
  3. imprint を現在の業務リクエストと一緒にサーバーへ送ります。body、リクエストヘッダー、または自分で実装する独立したリスク判定エンドポイントを利用できます。
  4. サーバーで実行されるコードだけが EchoScan secret key を読み取り、Lite または Pro report を照会します。
  5. サーバーは allowchallengereviewdeny などの最小限の判断結果を返します。

Next.js、Nuxt、Remix、SvelteKit、Laravel、Rails、Django、Vercel Functions、Cloudflare Workers などでは、ブラウザコードとサーバー route が同じリポジトリにある場合があります。重要なのはディレクトリ構成ではなく実行場所です。secret key はサーバー実行環境だけに置いてください。

ブラウザで imprint を生成

Browser Verifier はブラウザ環境のシグナルを収集し、imprint を返します。最終 report は返さず、EchoScan secret key も保持しません。

インストール
npm install @echoscan/browser-verifier
JavaScript
import { createEchoScan } from '@echoscan/browser-verifier'

const { imprint } = await createEchoScan().run()

CDN 方式はビルドなしのページや短いデモに適しています。本番アプリでは、通常はパッケージマネージャーとビルドフローで導入してください。

HTML
<script type="module">
  import { createEchoScan } from 'https://cdn.echoscan.org/v1/echoscan.esm.js'

  const { imprint } = await createEchoScan().run()
</script>

<script src="https://cdn.echoscan.org/v1/echoscan.umd.js"></script>
<script>
  window.EchoScan.createEchoScan().run().then(({ imprint }) => {
    console.log(imprint)
  })
</script>

サーバーへ送信

imprint は、保護対象のアクションと一緒にサーバー側コードへ届けば十分です。既存 API に合う形を選んでください。

body 方式は、業務リクエストが JSON の場合に自然です。

リクエスト例
await fetch('/api/your-action', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    ...yourActionPayload,
    echoscanImprint: imprint
  })
})

リクエストヘッダー方式は、業務 body を変えたくない場合に使えます。

リクエスト例
await fetch('/api/your-action', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-EchoScan-Imprint': imprint
  },
  body: JSON.stringify(yourActionPayload)
})

リスク判定フローを業務 API と分けたい場合は、自分のサーバー側エンドポイントを作ることもできます。

リクエスト例
await fetch('/api/echoscan/report', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ imprint })
})

/api/echoscan/report はサンプルのパスであり、あなたのサーバーで実装する必要があります。EchoScan の公式エンドポイントではありません。

Lite 導入

Lite は公開用途や軽量なリスク判断を最短で動かすためのプランです。Lite key も secret key なので、サーバー環境変数、secret manager、または同等のサーバー側シークレットストアに保存してください。

Node.js

インストール
npm install @echoscan/echoscan
リクエスト例
import { createLiteClient } from '@echoscan/echoscan'

const echoscan = createLiteClient({
  apiKey: process.env.ECHOSCAN_LITE_KEY
})

export async function getEchoScanReport(imprint) {
  return echoscan.getReport(imprint)
}

Go

インストール
go get github.com/echoscan/echoscan-go@latest
リクエスト例
package main

import (
	"context"
	"log"
	"os"

	echoscan "github.com/echoscan/echoscan-go"
)

func main() {
	imprint := "fp_session_xxx"

	echoscanClient, err := echoscan.NewLiteClient(os.Getenv("ECHOSCAN_LITE_KEY"))
	if err != nil {
		log.Fatal(err)
	}

	report, err := echoscanClient.GetReport(context.Background(), imprint)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("lyingCount=%v", report["lyingCount"])
}

Python

インストール
pip install echoscan
リクエスト例
import os
from echoscan import EchoScanLiteClient

imprint = "fp_session_xxx"
echoscan_client = EchoScanLiteClient(os.environ["ECHOSCAN_LITE_KEY"])
report = echoscan_client.get_report(imprint)

print(report.get("lyingCount"))

Rust

インストール
[dependencies]
echoscan = "0.2.1"
リクエスト例
use std::env;
use echoscan::LiteClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let imprint = "fp_session_xxx";
    let api_key = env::var("ECHOSCAN_LITE_KEY")?;
    let echoscan = LiteClient::new(&api_key)?;

    let report = echoscan.get_report(imprint).await?;
    println!("{}", report["lyingCount"]);

    Ok(())
}

Lite report

Lite report は、サーバーが imprint を照会したあとに返す最小限の公開結果です。リスク判断に必要な要約フィールドだけを残し、元の収集値、内部証拠、検出実装の詳細は隠します。

Lite report は「要約 + 明細」として読むのが自然です。lyingCount は強いリスクの要約、projection はモジュール単位の結果です。サーバーはこれらを使って allowchallengereviewdeny などの独自判断を返します。

通常アクセスの例:

戻り値例
{
  "analysis": {
    "browser": {
      "brand": "Google Chrome",
      "browser_version": "126.0.x",
      "rendering_engine": "Chromium",
      "browser_version_consistency_status": "PASS"
    },
    "os": {
      "os": "Windows",
      "version": "11",
      "os_consistency_status": "PASS"
    },
    "hash": {
      "accessCount": 1,
      "stableHash": "stb_8f4d2c1a",
      "uniqueHash": "unq_3a9b7e42"
    }
  },
  "lyingCount": 0,
  "projection": {
    "navigator": {
      "status": "PASS"
    },
    "screen": {
      "status": "PASS"
    },
    "webgl": {
      "status": "PASS"
    }
  }
}

疑わしいアクセスの例:

戻り値例
{
  "analysis": {
    "browser": {
      "brand": "Google Chrome",
      "browser_version": "126.0.x",
      "rendering_engine": "Chromium",
      "browser_version_consistency_status": "FAIL"
    },
    "os": {
      "os": "Windows",
      "version": "11",
      "os_consistency_status": "PASS"
    },
    "hash": {
      "accessCount": 1,
      "stableHash": "stb_8f4d2c1a",
      "uniqueHash": "unq_9c0f2d31"
    }
  },
  "lyingCount": 1,
  "projection": {
    "navigator": {
      "status": "DECEPTIVE"
    },
    "screen": {
      "status": "PASS"
    },
    "webgl": {
      "status": "SUSPICIOUS"
    },
    "webrtc": {
      "status": "SUSPICIOUS"
    }
  }
}

より完全な Lite surface の例:

戻り値例
{
  "analysis": {
    "browser": {
      "brand": "Google Chrome",
      "browser_version": "126.0.x",
      "rendering_engine": "Chromium",
      "browser_version_consistency_status": "PASS"
    },
    "os": {
      "os": "Windows",
      "version": "11",
      "os_consistency_status": "PASS"
    },
    "hash": {
      "accessCount": 7,
      "stableHash": "stb_8f4d2c1a",
      "uniqueHash": "unq_3a9b7e42"
    }
  },
  "lyingCount": 0,
  "projection": {
    "audio": {
      "status": "PASS"
    },
    "canvas": {
      "status": "PASS"
    },
    "font": {
      "status": "PASS"
    },
    "ip-geo-timezone": {
      "status": "PASS"
    },
    "navigator": {
      "status": "PASS"
    },
    "screen": {
      "status": "PASS",
      "resolution": "1920x1080"
    },
    "speech": {
      "status": "PASS",
      "default_voice_name": "Microsoft Jenny Online"
    },
    "webgl": {
      "status": "PASS",
      "unmasked_vendor": "Google Inc. (NVIDIA)",
      "unmasked_renderer": "ANGLE (NVIDIA GeForce RTX 4060)"
    },
    "webrtc": {
      "status": "PASS"
    }
  }
}

フィールド説明

フィールド 意味
analysis { ... } EchoScan が正規化したアクセス環境の要約。ログ、管理画面、リスク調査に利用できます
analysis.browser { ... } ブラウザの要約。ブランド、バージョン、レンダリングエンジン、バージョン整合性を含みます
analysis.browser.brand Google Chrome 検出されたブラウザブランド。Chrome、Firefox、Safari など
analysis.browser.browser_version 126.0.x 検出されたブラウザバージョン
analysis.browser.rendering_engine Chromium ブラウザのレンダリングエンジン。Chromium、WebKit など
analysis.browser.browser_version_consistency_status PASS ブラウザバージョン関連シグナルの整合性結果。FAIL はバージョン偽装または強い不一致を示します
analysis.os { ... } OS の要約。OS 名、バージョン、整合性を含みます
analysis.os.os Windows 検出された OS
analysis.os.version 11 検出された OS バージョン
analysis.os.os_consistency_status PASS OS 関連シグナルの整合性結果
analysis.hash { ... } アクセス環境の識別子と再訪要約
analysis.hash.accessCount 7 安定したアクセス環境に紐づく観測回数。継続性の参考値で、アカウントのリクエスト回数ではありません
analysis.hash.stableHash stb_8f4d2c1a 継続性、再訪、リスク関連付けに使う安定環境識別子
analysis.hash.uniqueHash unq_3a9b7e42 現在のアクセス環境をより細かく区別する識別子
lyingCount 0 素早いリスク分類に使える強いリスク要約
projection { ... } navigatorscreenwebglwebrtc などのモジュール単位の結果
projection.<module>.status SUSPICIOUS サーバー側判断に使う、そのモジュールの公開ステータス
projection.screen.resolution 1920x1080 画面解像度の要約
projection.speech.default_voice_name Microsoft Nanami ブラウザの既定音声名の要約
projection.webgl.unmasked_vendor Google Inc. WebGL グラフィックベンダーの要約
projection.webgl.unmasked_renderer ANGLE WebGL レンダラーの要約

ステータス説明

status 意味 よくある処理
PASS 現在のモジュールで明確な異常は見つかっていません 通常は許可
SUSPICIOUS 不審または低信頼のシグナルがあります 追加認証、観察、リスクスコア加算
DECEPTIVE 強い偽装または不一致シグナルがあります 追加認証、レビュー、拒否

ポリシーコードでは旧値 WARNFAIL との互換性を維持できます。

サーバー側の判断

サーバーが report を受け取ったら、一般的には allowchallengereviewdeny などの最小限の判断結果に変換し、その結果をブラウザへ返します。

これらの判断は、業務リスク、誤判定コスト、ユーザー体験に応じてサーバー側で実装します。よくある処理は次のとおりです。

decision よくある処理
allow このリクエストを許可し、登録、ログイン、購入などの業務処理を続行します
challenge CAPTCHA、SMS、メール認証、二段階確認などの追加確認を求めます
review 人手レビュー、バックオフィスキュー、または遅延処理に回します
deny このリクエストを拒否し、保護対象の業務処理を続行しません

下のコードは最小判断の例です。実際のルールは、業務リスク、誤判定コスト、ユーザー体験に合わせて調整できます。完全な report は、必要に応じてサーバーログ、管理画面、リスク管理基盤に保存してください。

JavaScript
const riskStatuses = new Set([
  'SUSPICIOUS',
  'DECEPTIVE',
  'WARN',
  'FAIL'
])

const hasStrongRisk = report.lyingCount > 0
const hasRiskStatus = Object.values(report.projection ?? {}).some((module) =>
  riskStatuses.has(module?.status)
)

const decision = hasStrongRisk || hasRiskStatus
  ? 'challenge'
  : 'allow'

return Response.json({ decision })

Pro 導入

Pro でもブラウザ imprint とサーバー側 secret key の境界は同じです。より高度なリスクポリシーと運用分析に向いています。

  • Lite と比べて、Pro は Bot、IP / ネットワークリスク、履歴アクセス分析のシグナルがより豊富です
  • Pro はルール設計、帰因分析、社内ダッシュボード向けに、より詳細なモジュール観測値を返します
  • Pro の履歴照会は days または from/to の時間窓を指定でき、summarytimeline を返します

Node.js

インストール
npm install @echoscan/echoscan
リクエスト例
import { createProClient } from '@echoscan/echoscan'

const echoscan = createProClient({
  apiKey: process.env.ECHOSCAN_PRO_KEY
})

const report = await echoscan.getReport(imprint)
const historyByDays = await echoscan.getHistory(imprint, { days: 7 })
const historyByRange = await echoscan.getHistory(imprint, {
  from: '2026-03-01',
  to: '2026-03-18'
})

Go

インストール
go get github.com/echoscan/echoscan-go@latest
リクエスト例
package main

import (
	"context"
	"log"
	"os"

	echoscan "github.com/echoscan/echoscan-go"
)

func main() {
	imprint := "fp_session_xxx"
	days := 7

	echoscanClient, err := echoscan.NewProClient(os.Getenv("ECHOSCAN_PRO_KEY"))
	if err != nil {
		log.Fatal(err)
	}

	report, err := echoscanClient.GetReport(context.Background(), imprint)
	if err != nil {
		log.Fatal(err)
	}

	history, err := echoscanClient.GetHistory(context.Background(), imprint, echoscan.HistoryQuery{
		Days: &days,
	})
	if err != nil {
		log.Fatal(err)
	}

	_, _ = report, history
}

Python

インストール
pip install echoscan
リクエスト例
import os
from echoscan import EchoScanProClient

imprint = "fp_session_xxx"
echoscan_client = EchoScanProClient(os.environ["ECHOSCAN_PRO_KEY"])

report = echoscan_client.get_report(imprint)
history = echoscan_client.get_history(imprint, days=7)

print(report.get("lyingCount"), history.get("summary"))

Rust

インストール
[dependencies]
echoscan = "0.2.1"
リクエスト例
use std::env;
use echoscan::{HistoryQuery, ProClient};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let imprint = "fp_session_xxx";
    let api_key = env::var("ECHOSCAN_PRO_KEY")?;
    let echoscan = ProClient::new(&api_key)?;

    let report = echoscan.get_report(imprint).await?;
    let history = echoscan
        .get_history(imprint, HistoryQuery::Days { days: 7, recent: None })
        .await?;

    println!("{} {}", report["lyingCount"], history["summary"]);
    Ok(())
}

Pro report

戻り値例
{
  "analysis": {
    "browser": {
      "brand": "Google Chrome",
      "browser_version": "146.0.x",
      "browser_version_consistency_status": "PASS",
      "rendering_engine": "Blink"
    },
    "os": {
      "os": "Windows",
      "os_consistency_status": "PASS",
      "version": "11"
    },
    "ip": {
      "status": "PASS"
    },
    "hash": {
      "accessCount": 31,
      "calculatedAt": "2026-03-19T10:27:25+09:00",
      "stableHash": "stb_8f4d2c1a",
      "uniqueHash": "unq_3a9b7e42"
    },
    "proxy": {
      "status": "PASS"
    }
  },
  "lyingCount": 0,
  "projection": {
    "bot_detection": {
      "status": "PASS",
      "data": {
        "is_bot": "No"
      }
    },
    "screen": {
      "status": "PASS",
      "data": {
        "resolution": "1920 x 1080"
      }
    },
    "speech": {
      "status": "PASS",
      "data": {
        "default_voice_lang": "en-US",
        "default_voice_name": "Microsoft David - English (United States)"
      }
    },
    "webgl": {
      "status": "PASS",
      "data": {
        "unmasked_vendor": "Google Inc. (NVIDIA)",
        "unmasked_renderer": "NVIDIA GeForce RTX 3060"
      }
    }
  }
}

Pro history

戻り値例
{
  "imprint": "fp_session_...",
  "range": {
    "from": "2026-03-01",
    "to": "2026-03-18"
  },
  "recent": 20,
  "summary": {},
  "timeline": []
}
  • daysfrom/to は排他です
  • fromto は必ずセットで指定します
  • 日付形式は YYYY-MM-DD 固定です

エラー構造

戻り値例
{
  "code": "auth_failed",
  "httpStatus": 401,
  "message": "Authentication failed",
  "requestId": "req_...",
  "retryable": false
}

分岐には code を使い、message は表示テキストとして扱ってください。

API Key とセキュリティ境界

  • EchoScan Console にログインし、API Keys ページで Lite または Pro key を作成します。
  • プレーンテキストの key は作成時に一度だけ表示されます。すぐにサーバー環境変数または secret manager に保存してください。
  • EchoScan secret key をブラウザコード、フロントエンド環境変数、localStorage、ログ、git、公開ファイルに置かないでください。
  • ブラウザは imprint を生成して送信します。report 照会と最終的なリスク判断はサーバー側で行います。
  • 導入・技術サポート:support@echoscan.org
  • プライバシー・セキュリティ関連:security@echoscan.org

AI コーディングツール

Claude、Cursor、Codex などの AI コーディングツールに EchoScan を導入させる場合は、先に次の文書を読ませてください。

  • https://echoscan.org/llms.txt
  • https://echoscan.org/docs/ai-context.md

これらのファイルは、このページと同じドキュメント事実ソースから生成されます。AI ツールが読めない場合は、EchoScan API コンテキストを確認できないことを明示して停止し、パッケージ名、フィールド、導入パスを推測しないでください。