EchoScan
UNQ
STB
#···
Cn
En
Jp

EchoScan SDK 導入ガイド

導入概要

推奨フロー:ブラウザで Browser Verifier を実行して imprint を取得し、サーバー側で Lite / Pro レポートを照会します。
ブラウザ側は収集・送信のみ。レポート照会とリスク判定はサーバー側で行ってください。

Browser Verifier フロントエンド

NPM ESM

npm install @echoscan/browser-verifier
import { createEchoScan } from '@echoscan/browser-verifier'

const { imprint } = await createEchoScan().run()
await fetch('/your-server/imprint', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ imprint })
})

CDN ESM / UMD

<script type="module">
  import { createEchoScan } from 'https://cdn.echoscan.org/v1/echoscan.esm.js'
  const { imprint } = await createEchoScan().run()
  console.log(imprint)
</script>

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

Lite 導入

Lite は API キー不要で、公開用途や軽量リスク判定に適しています。

Node

npm install @echoscan/echoscan
import { createLiteClient } from '@echoscan/echoscan'

const lite = createLiteClient()
const report = await lite.getReport(imprint)

Go

go get github.com/ozzxzzo/fingerprint-system/echoscan/packages/go@latest
package main

import (
	"context"
	"log"

	echoscan "github.com/ozzxzzo/fingerprint-system/echoscan/packages/go"
)

func main() {
	imprint := "fp_session_xxx"

	lite, err := echoscan.NewLiteClient()
	if err != nil {
		log.Fatal(err)
	}

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

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

Python

pip install echoscan
from echoscan import EchoScanLiteClient

imprint = "fp_session_xxx"
lite = EchoScanLiteClient()
report = lite.get_report(imprint)

print(report.get("lyingCount"))

Rust

[dependencies]
echoscan = "0.1.1"
use echoscan::LiteClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let imprint = "fp_session_xxx";
    let lite = LiteClient::new()?;
    let report = lite.get_report(imprint).await?;
    println!("{}", report["lyingCount"]);
    Ok(())
}

Lite レスポンス対応

{
  "analysis": {
    "browser": {},
    "os": {},
    "hash": {},
    "proxy": {}
  },
  "lyingCount": 0,
  "projection": {
    "audio": { "status": "PASS" },
    "canvas": { "status": "PASS" },
    "font": { "status": "PASS" },
    "ip-geo-timezone": { "status": "PASS" },
    "navigator": { "status": "PASS" },
    "screen": { "status": "PASS" },
    "speech": { "status": "PASS" },
    "webgl": { "status": "PASS" },
    "webrtc": { "status": "PASS" }
  }
}
  • lyingCount:偽装検知数。リスク分岐に直接利用可能
  • projection.<module>.status:モジュール結論(PASS | WARN | FAIL
  • analysis.proxy.status:プロキシリスク状態(PASS/WARN/FAIL)

Pro 導入

Pro はサーバー側 API キーが必要で、不正対策と運用分析向けです。

  • Lite と比べて、Pro は projection.bot_detection(Bot 判定)と analysis.proxy.status(Proxy リスク)を直接利用できます
  • speechscreenwebgl などの観測値がより豊富で、ルール設計と帰因分析に適しています
  • Pro 固有の履歴照会:days または from/to で期間指定し、summarytimeline を返します

Node

npm install @echoscan/echoscan
import { createProClient } from '@echoscan/echoscan'

const pro = createProClient({ apiKey: process.env.ECHOSCAN_PRO_KEY })
const report = await pro.getReport(imprint)
const historyByDays = await pro.getHistory(imprint, { days: 7 })
const historyByRange = await pro.getHistory(imprint, {
  from: '2026-03-01',
  to: '2026-03-18'
})

Go

go get github.com/ozzxzzo/fingerprint-system/echoscan/packages/go@latest
package main

import (
	"context"
	"log"

	echoscan "github.com/ozzxzzo/fingerprint-system/echoscan/packages/go"
)

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

	pro, err := echoscan.NewProClient("es_xxx_yyy")
	if err != nil {
		log.Fatal(err)
	}

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

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

	_, _ = report, history
}

Python

pip install echoscan
from echoscan import EchoScanProClient

imprint = "fp_session_xxx"
pro = EchoScanProClient("es_xxx_yyy")

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

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

Rust

[dependencies]
echoscan = "0.1.1"
use echoscan::{HistoryQuery, ProClient};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let imprint = "fp_session_xxx";
    let pro = ProClient::new("es_xxx_yyy")?;

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

    println!("{} {}", report["lyingCount"], history["summary"]);
    Ok(())
}
  • daysfrom/to は排他
  • fromto は必ずセットで指定
  • 日付形式は YYYY-MM-DD 固定

Pro レスポンス対応

{
  "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"
    },
    "hash": {
      "accessCount": 31,
      "calculatedAt": "2026-03-19T10:27:25+09:00",
      "stableHash": "....",
      "uniqueHash": "...."
    },
    "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"
      }
    }
  }
}
  • analysis.hash.accessCount:過去アクセス回数(既存ユーザー判定に有効)
  • analysis.browser.*analysis.os.*:環境整合性の判定項目
  • projection.bot_detectionanalysis.proxy.status:不正対策・プロキシ判定に直接利用可能

Pro 履歴レスポンス

{
  "imprint": "fp_session_...",
  "range": {
    "from": "2026-03-01",
    "to": "2026-03-18"
  },
  "recent": 20,
  "summary": {},
  "timeline": []
}
  • summary:集計値(運用ダッシュボード向け)
  • timeline:時系列アクセス明細
  • daysfrom/to は排他。日付形式は YYYY-MM-DD

エラー構造

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

業務分岐は code を優先し、message は表示用途に限定してください。

API Key 申請

  • アプリ情報を contact@echoscan.org へ送信
  • 導入・技術サポート:support@echoscan.org
  • プライバシー・セキュリティ関連:security@echoscan.org
  • 審査通過後に Pro key を発行
  • キーはサーバー環境変数のみに保存し、フロントには置かない