なりすまし判定APIを無料プランで試す【curl / Python・最初の判定まで】

なりすまし判定・ライブネス検知
📌 準備: OpenCV の環境構築がまだの方はこちら → C++ 環境構築ガイド / C#(OpenCvSharp)セットアップ

なりすまし判定APIを無料プランで試す【curl / Python・最初の判定まで】

顔認証の前段に「その顔は写真や画面ではないか」の判定を挟みたい。でもシステムに組み込む前に、まず手元の画像で判定結果を見てみたい——という人向けの記事です。

当社のなりすまし判定 API は、顔画像を1枚 POST するだけで、印刷した写真やスマートフォン・タブレットの画面に映した顔かどうかを判定します。ライブラリのインストールは不要で、curl でも Python でも、HTTP が送れれば使えます。

本記事では、無料プラン(月50回)の API キーで最初の判定結果を受け取るところまでを、動くコードで示します。


1. 準備:無料プランの API キーを取得する

API は AWS Marketplace 経由で提供しています(申し込みには AWS アカウントが必要です。Free プランは $0 で、上限に達しても課金されません)。Free プラン(月50回)を選んで申し込むと、登録完了後に顧客ダッシュボードで API キーを発行できます。

申し込みから API キー発行までの画面手順は、ドキュメントのクイックスタートガイドにスクリーンショット付きでまとめています。ここではキーが手元にある前提で進めます。

項目 値
エンドポイント POST https://liveness.api.pas-ta.io/v1/check/liveness
認証 X-API-Key ヘッダー
本文 JSON(image = Base64 文字列、image_format = "jpeg" / "png")
無料プランの上限 月50回(超えると停止。課金されることはありません)

カウントされるのは判定に成功した応答だけです。キーの間違いや画像不備などのエラー応答は、月50回に含まれません。

以降のコードでは、API キーを環境変数に入れておきます(コードに直書きしないため)。

export LIVENESS_API_KEY="lc_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"

2. curl で送る

画像を Base64 にして、JSON の image に入れて送ります。Base64 文字列はコマンドライン引数に直接展開すると、元画像が数百 KB を超えたあたりで argument list too long になるため、標準入力から本文を渡す形にしておくのが安全です。

# macOS は base64 -i、Linux は base64 -w0(tr -d '\n' は改行で JSON が壊れるのを防ぐため)
{ printf '{"image": "'; base64 -i face.jpg | tr -d '\n'; printf '", "image_format": "jpeg"}'; } \
| curl -s -X POST https://liveness.api.pas-ta.io/v1/check/liveness \
  -H "X-API-Key: $LIVENESS_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @-

.jpg も .jpeg も同じ JPEG なので、image_format は "jpeg" を指定します。

成功すると、次のような JSON が返ります(値は例です)。

{
  "metadata": {
    "date": "2026-10-20T03:00:00.000Z",
    "ver": "1.0.2",
    "customer_id": "550e8400-e29b-41d4-a716-446655440000",
    "remaining_calls": 49,
    "over_limit_calls": 0,
    "status": "success"
  },
  "data": {
    "isFakeFace": false,
    "isFakeLikelihood": 0.021,
    "isValidFace": true,
    "faceBrightness": 142.3,
    "faceRectArea": {"x": 120, "y": 80, "width": 200, "height": 200},
    "vFaceRect": [
      {"x": 120, "y": 80, "width": 200, "height": 200}
    ],
    "msg": "",
    "latency_ms": 120
  }
}

3. レスポンスの読み方

見るべきフィールドは多くありません。

フィールド 意味
data.isFakeFace true = 写真・画面などのなりすまし疑い / false = 実物
data.isFakeLikelihood なりすましらしさのスコア(0.0〜1.0)。高いほど偽物寄り
data.isValidFace 判定対象として扱える顔だったか
data.faceRectArea 判定に使った顔の位置 {x, y, width, height}
data.faceBrightness 顔領域の平均輝度(暗すぎる画像の切り分けに使う)
metadata.remaining_calls 今月の残り回数

isFakeFace は、isFakeLikelihood が既定しきい値 0.15 を上回ると true になる参考判定です。上の例は 0.021 なので false(実物)になっています。

では、写真をかざすとどうなるか。人物写真を印刷して手に持ち、Web カメラ(1280×960)で撮った画像を送ってみました(2026-10-20 実測)。

{
  "data": {
    "isFakeFace": true,
    "isFakeLikelihood": 1.0,
    "isValidFace": true,
    "faceBrightness": 148.88,
    "faceRectArea": { "x": 420, "y": 203, "width": 453, "height": 569 },
    "msg": "Error: Detected fake face(livenessH)",
    "latency_ms": 75
  }
}

顔そのものは正しく検出できている(isValidFace: true)うえで、スコアは上限の 1.0、isFakeFace は true です。msg にも、なりすましを検出した旨が入ります。手元にスマートフォンがあれば、自分の顔写真を画面に表示してカメラに向けた画像でも試してみてください。

運用で厳密にしたい場合は、isFakeFace をそのまま使わず、isFakeLikelihood を自分のしきい値で評価してください。しきい値を下げれば偽物を通しにくくなる代わりに、本人を弾く場面が増えます。どちらの誤りが痛いかで決めるのが基本です(指標の考え方は FAR/FRR と APCER/BPCER の違いで解説しています)。

顔検出は API 側で行うので、顔の座標を自前で求めて送る必要はありません。検出した位置は faceRectArea で返ってきます。


4. Python で送る

同じ処理を Python(requests)で書くと次のとおりです。エラー処理まで入れても30行ほどです。

import base64
import os
import sys

import requests

API_URL = "https://liveness.api.pas-ta.io/v1/check/liveness"
API_KEY = os.environ["LIVENESS_API_KEY"]  # キーはコードに直書きしない


def check_liveness(path: str) -> dict:
    with open(path, "rb") as f:
        image_b64 = base64.b64encode(f.read()).decode("ascii")

    fmt = "png" if path.lower().endswith(".png") else "jpeg"  # .jpg も "jpeg"
    resp = requests.post(
        API_URL,
        headers={"X-API-Key": API_KEY},
        json={"image": image_b64, "image_format": fmt},
        timeout=30,
    )

    if resp.status_code == 413:
        # API の手前で弾かれるため、共通エラー構造ではない
        raise RuntimeError("画像が大きすぎます(画像そのもので約 7MB まで)")

    try:
        body = resp.json()
    except ValueError:
        # 502/503 などで JSON 以外が返ることがある。少し待って再送する
        raise RuntimeError(f"{resp.status_code}: 一時的なエラーです。少し待って再送してください")
    if body["metadata"]["status"] != "success":
        err = body["error"]
        # 判定は error.code で行う(message は英語の補足)
        raise RuntimeError(f"{resp.status_code} {err['code']}: {err['message']}")

    return body


if __name__ == "__main__":
    body = check_liveness(sys.argv[1])
    data = body["data"]
    print("なりすまし疑い:", data["isFakeFace"])
    print("スコア:", data["isFakeLikelihood"])
    print("顔の位置:", data["faceRectArea"])
    print("今月の残り:", body["metadata"]["remaining_calls"])
pip install requests
python check_liveness.py face.jpg
なりすまし疑い: False
スコア: 0.021
顔の位置: {'x': 120, 'y': 80, 'width': 200, 'height': 200}
今月の残り: 49

5. エラーの扱い

エラー時は metadata.status が "error" になり、error に理由が入ります。

{
  "metadata": {"ver": "1.0.2", "status": "error"},
  "error": {"code": "invalid_api_key", "message": "Invalid API key"}
}

プログラムで分岐するときは error.code を見てください。error.message は英語の補足で、文言は変わることがあります。

HTTP error.code よくある原因
400 invalid_image 顔が検出できない・顔が画像の端で切れている・顔が大きく写りすぎている・壊れた画像や jpeg/png 以外
400 invalid_request image / image_format の欠落や型違い
401 invalid_api_key キーの貼り間違い・無効化済みのキー
413 (なし) リクエストが大きすぎる(画像そのもので約 7MB 超)
429 quota_exceeded 無料プランの月50回に到達。短時間に連続送信した場合も、公正利用のため 429 になることがある(少し待って再送)

413 だけは形が違う点に注意してください。API に届く手前で弾かれるため、metadata / error の共通構造ではなく {"message": "Request Entity Too Large"} が返ります。上の Python コードで 413 を先に判定しているのはこのためです。

今月の残り回数は GET /v1/usage でも確認できます(この呼び出しは回数に含まれません)。


6. 判定がうまくいかないときに見る3点

顔だけを切り抜いて送らない

いちばん多いのがこれです。前段で顔を検出して、顔の部分だけをクロップしてから送る構成にすると、正しく判定できません。

なりすまし判定は、顔そのものだけでなく、顔のまわりに残る痕跡——スマートフォンのベゼル、画面の映り込みやモアレ、印刷物の縁や持っている手——を手掛かりにしています。顔だけを切り抜くと、その手掛かりが消えます。さらに顔が画像全体の約65%を超えると、判定自体を行わず 400 invalid_image(メッセージ例: Face position error(1005) - Too close)を返します。撮影したままのフレーム全体を送ってください。

顔を画像の中央付近に

顔が画像の端で切れていると、判定は行われず 400 invalid_image(error.message に Face position error を含む)になります。

暗すぎる画像は避ける

顔が暗く沈んでいると判定が不安定になります。faceBrightness が低い場合は、照明や露出を見直してください。

条件の詳細(顔のサイズ・明るさ・向き・撮影距離)は画像入力ガイドラインに実例付きでまとめています。


7. まとめ

  • なりすまし判定 API は、顔画像1枚を Base64 で POST するだけ。ライブラリのインストールは不要
  • 無料プラン(月50回)で試せる。数えるのは判定に成功した応答だけで、エラーは数えない
  • 見るのは isFakeFace と isFakeLikelihood。厳密に運用するならスコアを自分のしきい値で評価(既定は 0.15)
  • エラーの分岐は error.code で。413 だけは共通構造ではない
  • 顔だけを切り抜かず、フレーム全体を送る

手元の画像で傾向がつかめたら、次は既存の顔認証にどこで挟むかです。設計の考え方は既存の顔認証システムに、なりすまし対策を後付けする、抜け漏れの確認はなりすまし対策 設計チェックリスト12項目をどうぞ。

🛡 まずは無料プランで試してみる

本ブログを運営するスワローインキュベートのなりすまし判定 APIは、顔画像1枚から写真・画面によるなりすましを判定します。無料プラン(月50回)から始められ、本番利用に合わせて有料プランへ切り替えられます(切り替えは AWS Marketplace の契約管理画面から)。端末内で動かしたい場合は SDK もご用意しています。

→ 無料プランの始め方(クイックスタート)
→ 料金プラン・SDK の詳細を見る

タイトルとURLをコピーしました