PII-FI API v2 Docs
API v2 APIキーを管理
DEVELOPER GUIDE · API V2

PII-FI API v2

個人情報を含む日本語テキストを、見つける渡せる形へ置き換える必要な場合だけ手元の対応表で戻すためのHTTP APIです。

問い合わせ記録、議事録、業務文書、ログなどを別のシステムや担当者へ渡す前に、個人情報候補を検出したり、元の値を直接含まない文章へ変換したりできます。少量は同期処理、大量・複数件はBatchで扱えます。

BASE URLhttps://api.pii-fi.com/v2
AUTHBearer API_KEY
FORMATapplication/json
1
FIND

見つける

detectが氏名・連絡先などの候補と位置を返します。

2
DEIDENTIFY

渡せる形にする

deidentifyが検出と置換を一度に行い、値を直接含まない文章を返します。

3
RESTORE

必要なら戻す

利用者が保管したmappingだけを使い、restoreで元の値へ戻します。

PII-FIが保持しない値と、呼び出し側の責任

同期処理の入力本文、検出値、mapping、変換結果、復元結果は通常の記録へ残しません。ただし、呼び出し側のアプリ、HTTPクライアント、監視基盤が本文や応答を記録すれば、そこには残ります。request/response bodyをログへ出さない設定を呼び出し側でも行ってください。

INTRODUCTION · 1 / 3

概要 — PII-FI API v2 とは#

PII-FI API v2 は、日本語テキストに含まれる個人情報(PII)と機微情報を検出し、仮名化・マスキングした文章を返す HTTP API です。氏名・電話番号・住所・メールアドレスのような識別子から、マイナンバーなどの公的番号、API キーなどの認証情報まで、84 種類の型を対象にします。

日本語向けに設計した検出エンジンを使い、敬称・役職つきの氏名(「山田部長」「田中さま」)、丁目・番地の表記ゆれがある住所、全角・半角が混在する電話番号のような、汎用の多言語ツールが取りこぼしやすい日本語固有の書き方をそのまま扱います。

項目内容
対応言語日本語(日本語テキストに特化。英語のメールアドレス・URL・API キーなど、言語に依存しない型は日本語文中でも検出します)
提供形態SaaS の HTTP API(https://api.pii-fi.com/v2)。同じ検出エンジンをブラウザだけで使う PII-Fi Scan(Web アプリ)と、社内ネットワーク内で完結するオンプレミス構成(個別提案)があります
できることdetect(候補の型・値・位置を返す)、deidentify(検出と置換を一度に行う)、restore(利用者が保管した mapping で戻す)、Batch(複数件の非同期処理)
認証API キー(Authorization: Bearer)。キーごとに必要最小限の scope を付けます
データの扱い同期処理の入力本文・検出値・mapping・変換結果は通常の記録へ残しません。Batch の結果は 24 時間で削除されます

他社の PII 検出 API(Microsoft Presidio、Azure AI Language、Google Sensitive Data Protection、Amazon Comprehend)との違いは日本語 PII 検出 API の比較にまとめています。

FIRST REQUEST · 2 / 3

クイックスタート — curl 1 本で試す#

API キーを取得してから最初の応答を受け取るまで、手順は 3 つです。細かい確認(scope の設計、/capabilities の確認、Node.js からの呼び出し)は詳しい Quickstart に続きます。

  1. 1
    API キーを発行する

    app.pii-fi.com の API キー画面で、deidentify scope を付けたキーを発行します。発行値は一度だけ表示されるので、環境変数 PIIFI_API_KEY に保存します。

  2. 2
    curl を 1 本送る

    ダミーの文章を POST /deidentify へ送ります。実データで試す前に、必ずダミーデータで接続を確認してください。

  3. 3
    応答を確認する

    メールアドレスがラベルに置き換わった text と、値を含まない usage が返れば成功です。

Request · cURL(Bash)
export PIIFI_API_KEY='発行直後に受け取った値'

curl --request POST 'https://api.pii-fi.com/v2/deidentify' \
  --header "Authorization: Bearer $PIIFI_API_KEY" \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'Idempotency-Key: demo-order-0001' \
  --data '{"text":"担当者Aの連絡先はsample@example.testです。"}'
Response · example
{
  "request_id": "req_example_quickstart_02",
  "text": "担当者Aの連絡先はメールアドレスAです。",
  "usage": {
    "processed_characters": 31,
    "consumed_units": 1
  }
}

同期処理 1 要求の上限は 1,000,000 Unicode コードポイントです。検出だけ行いたい場合は POST /detect、複数件をまとめて処理したい場合は Batch を使います。

ENTITY TYPES · 3 / 3

検出エンティティ一覧 — 84 種類の型#

検出・仮名化の対象は 84 種類の型(識別子 40 型・属性 35 型・認証情報 9 型)に体系化されています。カテゴリごとの内訳は次のとおりです。各型の詳しい検出パターンはトップページの型カタログで確認できます。

カテゴリ型数含まれる型
人物・生体5氏名、生年月日、年齢、性別、生体・遺伝情報の言及
連絡先・住所4電話番号、メールアドレス、住所、地名(地理的地点)
公的番号10マイナンバー、旅券番号、運転免許証番号、在留カード番号、住民票コード、各種保険番号、基礎年金番号、法人番号、車両ナンバープレート、車台番号(VIN)
金融5クレジットカード番号、銀行口座番号、IBAN、SWIFT/BIC コード、暗号資産アドレス
認証情報9API キー、アクセストークン(JWT/OAuth)、秘密鍵、パスワード・ハッシュ、DB 接続文字列、クラウド鍵、SSL 証明書、Cookie・セッショントークン、汎用シークレット
ネットワーク・技術情報10IP アドレス、MAC アドレス、端末識別子(IMEI 等)、広告 ID、ユーザー名・ハンドル、ホスト名・FQDN、Windows SID、ファイルパス、URL、GPS 座標
健康・医療7病名・診断、検査結果、処方・薬、症状・徴候、病歴、医療コード(ICD 等)、医療機関番号
要配慮情報3国籍・在留資格、犯罪歴・犯罪被害、要配慮属性(汎用)
財務・税務7個人の収入、個人の資産、個人の負債、企業業績・財務、税・社会保険、取引情報、人事報酬
人事・労務5人事評価、懲戒、勤怠、休職、異動
経営戦略・法務10M&A 情報、業績予想(未公開)、取締役会情報、経営戦略、インサイダー情報、契約情報、NDA・秘密保持、知的財産、訴訟、違約金
組織・社内情報7組織名、社員番号、顧客番号、文書番号、社内案件・システム名、社内用語、社内 URL
日時2日付(和暦・西暦)、時刻
API で使う型 ID は GET /entity-types で取得する

要求の entity_types や応答の span.entity_type に現れる型 ID(例: JPII_PERSON_NAMEJPII_CONTACT_EMAIL_ADDRESSJPII_DATETIME_DATE)は、契約とランタイムによって利用できる範囲が変わります。上の表を固定値としてコードへ埋め込まず、GET /entity-types が返す現在の一覧から選んでください。

PURPOSE

何ができるのか#

01

共有前の検査

外部サービス、委託先、別部署へ文章を渡す前にdetectし、どこに個人情報候補があるかを確認します。

02

非識別化した文章の生成

deidentifyで、氏名や連絡先などをラベルへ置き換えた文章を作り、その文章だけを後続処理へ渡します。

03

一時的に戻せるワークフロー

return_mappingで受け取ったmappingを利用者側だけで保管し、必要な業務境界でrestoreします。

04

複数件の非同期処理

複数のテキストをBatchへ登録し、polling、SSE、Webhookのいずれかで進捗を受け取り、完了後に結果を取得します。

検出結果だけで「安全」と自動判定しない

detectが返すのは個人情報の候補です。最終的な共有可否や法令上の区分をAPIが決めるものではありません。見逃しや業務固有の判断が重要な用途では、呼び出し側に確認工程を設けてください。

DECISION GUIDE

どの処理を選ぶか#

「何を返してほしいか」と「処理完了を同じ接続で待てるか」で選びます。

やりたいこと選ぶ処理返るもの実装上の要点
候補だけを確認したいPOST /detect型、値、位置を持つspans検出結果を使って呼び出し側で確認・表示・判断する。
すぐに置換済み文章がほしいPOST /deidentify置換済みtext元の値へ戻さないならmappingを要求しない。
あとで元の値へ戻したい/deidentify/restore置換済みtextと任意のmappingmappingには元の値が入る。利用者側で暗号化・アクセス制御・削除を行う。
長めの同期処理で接続切れを検知したいstreamable HTTPacceptedprogress、終端eventAccept: text/event-streamstream: trueを使う。
複数件をバックグラウンド処理したいPOST /batchesBatch receiptと後続URL完了通知はpolling、SSE、Webhookから選ぶ。結果は期限内に取得する。
同期処理を選ぶ

1回のHTTP要求で結果まで受け取り、呼び出し側が接続を維持できる処理。

streamable HTTPを選ぶ

処理は同期のまま、同じ接続で進捗とkeep-aliveを受け取りたい処理。

Batchを選ぶ

複数件を登録後に切断し、別要求や通知で完了を追跡したい処理。

QUICKSTART

最初の非識別化を実行する#

この手順では、APIキーが現在使えることを確認してから、ダミーの文章をdeidentifyします。実データで試す前に、必ずダミーデータで接続とエラー処理を確認してください。

まずはプロファイルを指定しない最小の要求を示します。画面で編集した設定を使いたい場合は、プロファイルの選択手順に従ってprofiles:readの権限とprofile_idを追加してください。

  1. 1
    APIキーを必要最小限のscopeで発行する

    API画面capabilities:readdeidentifyを付けます。元に戻す必要がある場合だけmapping:readrestoreも付けます。

  2. 2
    キーをサーバー側の秘密として設定する

    発行値は一度だけ表示されます。ソースコード、Git、ブラウザ向けJavaScript、モバイルアプリへ埋め込まず、secret managerまたは実行環境の秘密変数へ保存します。

  3. 3
    /capabilitiesで現在の利用条件を確認する

    plan名をコードへ固定せず、返されたcapabilitieslimitsを実行時の判断に使います。

  4. 4
    一意なIdempotency-Keyで処理する

    業務処理1件につき1つ生成し、同じ業務処理の再送でだけ同じ値を使います。異なる本文へ使い回さないでください。

1. キーを環境変数へ設定

Bash(以降のcurl例もBash用)
export PIIFI_API_KEY='発行直後に受け取った値'

共有端末のshell履歴へ残る方法は避け、実際の配備では利用中のsecret managerを使ってください。

2. 利用可能な機能を確認

cURL · capabilities
curl --request GET 'https://api.pii-fi.com/v2/capabilities' \
  --header "Authorization: Bearer $PIIFI_API_KEY" \
  --header 'Accept: application/json'
Response · example
{
  "request_id": "req_example_quickstart_01",
  "occurred_at": "2026-08-08T00:00:00.000Z",
  "plan": "standard",
  "workspace": "personal",
  "capabilities": {
    "api": true,
    "sync": true,
    "batch": false
  },
  "limits": {
    "requests_per_minute": 60,
    "concurrency": 2,
    "sync_unicode_code_points": 1000000,
    "batch_result_retention_hours": 24,
    "webhook_retry_hours": 24
  }
}

3. ダミー文章を非識別化

Request · cURL
curl --request POST 'https://api.pii-fi.com/v2/deidentify' \
  --header "Authorization: Bearer $PIIFI_API_KEY" \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'Idempotency-Key: demo-order-0001' \
  --data '{"text":"担当者Aの連絡先はsample@example.testです。"}'
Response · example
{
  "request_id": "req_example_quickstart_02",
  "text": "担当者Aの連絡先はメールアドレスAです。",
  "usage": {
    "processed_characters": 31,
    "consumed_units": 1
  }
}

4. Node.jsから呼ぶ

Node.js · server side
import {randomUUID} from 'node:crypto';

const response = await fetch('https://api.pii-fi.com/v2/deidentify', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.PIIFI_API_KEY}`,
    'Content-Type': 'application/json',
    Accept: 'application/json',
    'Idempotency-Key': randomUUID()
  },
  body: JSON.stringify({
    text: '担当者Aの連絡先はsample@example.testです。'
  })
});

const body = await response.json();
if (!response.ok) {
  throw new Error(`${body.code}: ${body.title} (${body.request_id})`);
}

console.log(body.text); // request bodyやmappingはログへ出さない
ここまでで確認できたこと
  • APIキーが有効で、必要なscopeと現在の利用上限が取得できた。
  • ダミー文章の個人情報候補が、元の値を直接含まない文章へ置き換わった。
  • request_idusageを、値を含まない運用情報として扱える。
CONCEPTS

実装前に知っておく概念#

workspace
利用量と上限を共有する単位

Personalは本人、Teamは組織がworkspaceです。APIとWebUIは同じ契約枠・同じ月次ユニット・同じ追加ユニットを使います。

scope
APIキーごとの最小権限

planが機能を持っていても、キーに必要なscopeがなければ403です。用途の異なるシステムではキーを分けてください。

entity_type
検出対象の種類

利用可能な型は固定値として埋め込まず、GET /entity-typesで現在の一覧を取得します。

span
検出候補の型・値・位置

detectが返します。入力文字列と対応させて確認画面や後続判断に使います。

mapping
置換後ラベルと元の値の対応表

要求したdeidentify応答にだけ含まれます。元の値を含むため、通常の結果より強い保護が必要です。

Idempotency-Key
二重処理と二重計上を防ぐ業務ID

8〜160文字。同じworkspace・操作で24時間一意にします。同期処理とBatchでは再送時の応答が異なります。

request_id
値を含まない追跡ID

応答headerとbodyで返ります。失敗調査では本文の代わりにrequest IDとUTC日時を記録してください。

Unicode code point
文字数上限と利用量の数え方

バイト数やUTF-16 code unitではありません。事前検査もAPIと同じUnicodeコードポイントで数えてください。

AUTHENTICATION

認証とAPIキーの管理#

全ての要求でAPIキーをBearer値として送ります。キーの平文は発行直後に一度だけ表示され、その後は再表示できません。

HTTP header
Authorization: Bearer $PIIFI_API_KEY

本番で守ること

行う
  • バックエンド、ジョブworker、CIなど管理できる実行環境から呼ぶ。
  • 用途ごとにキーを分け、必要なscopeだけを付ける。
  • secret managerまたは保護された環境変数へ保存する。
  • 利用停止や漏えいの疑いがある場合は、新しいキーへ切り替えて古いキーを停止する。
行わない
  • ブラウザ向けJavaScript、モバイルアプリ、配布バイナリへ埋め込まない。
  • Git、設定例、CIログ、例外メッセージへ書かない。
  • 複数システムで1本のキーを共有しない。
  • キーの全権限を前提にしない。現在のplanとscopeを実行時に確認する。

安全な切り替え手順

  1. 1

    既存キーを残したまま、同じ用途・必要最小限のscopeで新しいキーを発行します。

  2. 2

    新しいキーをsecret managerへ登録し、対象システムを再配備します。

  3. 3

    新しいキーでGET /capabilitiesが200になり、必要な機能・上限が返ることを確認します。

  4. 4

    古いキーをAPI画面で利用停止し、古いキーが401になることを確認します。

Scope

実際の許可は、現在のplan機能、APIキーscope、workspace、Team roleの共通部分で決まります。Teamのキー管理はownerまたはadminが行います。

scope許可される操作付ける判断
capabilities:read契約・キーで利用できる機能を確認するこの操作を行うシステムだけ。
entity-types:read検出対象の種別を確認するこの操作を行うシステムだけ。
profiles:readワークスペースのプロファイルを確認するこの操作を行うシステムだけ。
usage:read共通ユニットの利用量を確認するこの操作を行うシステムだけ。
detect同期検出を実行するこの操作を行うシステムだけ。
deidentify同期検出と仮名化を一度に実行するこの操作を行うシステムだけ。
mapping:readdeidentify応答でmappingを受け取る元の値へ戻す業務がある場合だけ。
restore利用者が保持するmappingで復元する元の値へ戻す業務がある場合だけ。
batches非同期Batchを登録・参照する複数件の非同期処理を使う場合だけ。
HTTP BASICS

接続先・形式・共通ヘッダー#

パスは全てbase URL https://api.pii-fi.com/v2へ連結します。本文を送る要求はJSON、通常応答もJSONです。SSEを選ぶ場合だけ応答形式がtext/event-streamになります。

方向ヘッダー必須実装上の扱い
RequestAuthorization全要求Bearer API_KEY。値をログへ出さない。
RequestContent-Type本文ありapplication/json
RequestAccept推奨通常はapplication/json。streamingではtext/event-stream
RequestIdempotency-Key処理系POST8〜160文字。業務処理ごとに一意な値を作る。
RequestLast-Event-IDSSE再接続時最後に処理済みのevent IDを送る。
ResponseX-Request-ID値を含まない追跡ID。bodyのrequest_idと合わせて記録する。
ResponseX-Occurred-At受付時刻。UTCのRFC 3339。
ResponseRetry-After429など秒数が返った場合、その時間より前に再送しない。

成功時にも確認する値

HTTP status

本文だけで成功判定せず、通常同期処理は200、Batch登録は202などendpointのstatusを確認します。

request_id

本文や検出値を記録する代わりに、調査へ使う追跡IDとして保存します。

usage

処理文字数と今回の消費ユニットを確認し、自システムの業務IDと値を含めず関連付けます。

ERROR HANDLING

エラーをどう処理するか#

エラーはapplication/problem+jsonで返ります。呼び出し側はHTTP statusと機械判定用のcodeで分岐し、調査用にrequest_idoccurred_atを記録してください。入力本文や検出値はエラー本文へ含まれません。

Problem response
{
  "type": "about:blank",
  "title": "Invalid API key",
  "status": 401,
  "code": "invalid_api_key",
  "detail": "Authentication failed",
  "request_id": "req_example_error_01",
  "occurred_at": "2026-08-08T00:00:00.000Z"
}
HTTP何が起きたか自動再試行呼び出し側の処置
400JSON、query、必須fieldなどが不正しないcodeと対象fieldを確認し、要求を修正する。
401APIキーがない、無効、期限切れ、停止済みしない秘密の設定とキー状態を確認する。別のキーへ無条件にfallbackしない。
403plan、scope、workspace、roleの許可が不足しない/capabilitiesとキーscopeを確認する。
409同期処理の冪等性キーが処理中・使用済み、または別本文に再利用された同じ要求を連打しない新しいキーで即再実行せず、業務側で結果不明として扱う。詳細は冪等性節。
410Batch結果が削除済みまたは保持期限後しない同じ結果は取得できない。取得・削除時刻の運用を見直す。
413Unicodeコードポイント上限を超えた同じ本文ではしない入力を小さくするか、複数件ならBatchへ分ける。この要求ではユニットを消費しない。
429workspaceのrequest頻度または同時処理上限条件付きRetry-After後に再送する。呼び出し側へqueueを置く。
502必要な内部応答を正しい形式で取得できない条件付き短い待機後に回数上限つきで再試行し、継続時はrequest IDを添えて調査する。
503処理に必要な互換ランタイムまたは認可状態を利用できない条件付き指数的に待機時間を延ばし、回数上限を設ける。

エラー本文を捨てずに分岐する

Node.js · error handling
async function readPiifiResponse(response) {
  const contentType = response.headers.get('content-type') || '';
  const body = contentType.includes('json')
    ? await response.json()
    : { title: await response.text() };

  if (response.ok) return body;

  const error = new Error(body.title || `HTTP ${response.status}`);
  error.status = response.status;
  error.code = body.code;
  error.requestId = body.request_id || response.headers.get('x-request-id');
  error.occurredAt = body.occurred_at || response.headers.get('x-occurred-at');
  error.retryAfter = Number(response.headers.get('retry-after')) || null;
  throw error;
}
本文を例外ログへ付けない

上の例はstatus、code、request ID、UTC日時だけを例外へ移します。要求body、応答のtextspansmappingはログへ添付しないでください。

PRE-FLIGHT

契約・検出型・利用量を先に確認する#

処理を始める前に使う3つの参照endpointです。plan名や検出型一覧をコードへ固定する代わりに、現在の応答を使って判断できます。

GET/capabilitiescapabilities:read

使う場面:起動時、キー切替後、403を受けたとき。現在のworkspace、機能、request頻度、同時処理、保持時間を確認します。

field意味
plan

現在の契約を表す機械判定用の値。

workspace

personalまたはteam。利用量と上限を共有する範囲。

capabilities

現在利用できる機能の真偽値。少なくともapisyncbatchを判断に使えます。

limits

request/分、同時処理数、同期文字数、Batch結果保持、Webhook再送期間。

GET/entity-typesentity-types:read

使う場面:entity_typesを指定するUIや設定を作るとき。現在のランタイムが扱える型だけを返します。

Response · example
{
  "request_id": "req_example_metadata_01",
  "occurred_at": "2026-08-08T00:00:00.000Z",
  "entity_types": [
    "JPII_PERSON_NAME",
    "JPII_CONTACT_EMAIL_ADDRESS"
  ]
}

一覧は設定の選択肢として扱い、未取得時に過去の全型を送るfallbackは避けてください。

GET/usage?period=2026-08usage:read

使う場面:実行前の残量表示、月次集計、APIとWebUIを合わせた利用量の確認。periodは省略可能で、指定する場合はYYYY-MMです。

Response · example
{
  "request_id": "req_example_usage_01",
  "occurred_at": "2026-08-08T00:00:00.000Z",
  "period": "2026-08",
  "monthly_units": 100,
  "additional_units": 0,
  "consumed_units": 12
}
field意味
monthly_units

現在の契約で当月に付与される基本ユニット。

additional_units

追加分として利用できるユニット。

consumed_units

指定月に確定した消費ユニット。WebUIとAPIの処理を合算します。

PROFILES · SHARED SETTINGS

画面と同じプロファイルで処理する#

プロファイルは「何を検出し、どのように置き換えるか」をまとめた設定です。プロファイル画面で編集した設定をAPIでも使えます。標準プロファイル、ソースコード用プロファイル、自作・複製したプロファイルは同じ仕組みで、名前によって利用先が制限されることはありません。

初めからあるユーザープロファイル向いている用途と初期状態
標準プロファイル一般的なドキュメント向け。氏名や連絡先などをダミーへ置き換え、認証情報は伏せ字にします。
ソースコード用プロファイルGitHubの監視やソースコードフォルダ向け。コード内の情報はラベルで置き換え、認証情報は伏せ字にします。単独の日付は初期状態では検出対象から外します。

どちらも利用者が編集できます。上の説明は初期状態であり、現在の設定は詳細APIで確認してください。GitHubでも標準プロファイルを選べます。

必要な権限を確認する

一覧・詳細の取得にはprofiles:readが必要です。処理でprofile_idを指定する場合も、処理用scopeに加えてこの権限が必要です。既存キーの権限は自動追加されません。403の場合はキーを繰り返し送らず、API画面で現在の権限を確認してください。

操作必要なscope
プロファイルの一覧・詳細profiles:read
プロファイルを指定して検出detectprofiles:read
プロファイルを指定して置換deidentifyprofiles:read。mappingを受け取るときはmapping:readも必要。
プロファイルを指定してBatch登録batchesprofiles:read。現在の契約がBatchに対応している必要があります。

1. 一覧から使いたい設定のIDを選ぶ

GET/profilesprofiles:read

画面で保存したユーザープロファイルを選ぶには、source=workspaceで絞り込みます。返された一覧のidを、処理要求のprofile_idへ渡してください。名前では指定しません。

成功応答はrequest_idoccurred_atprofiles配列です。各要素にid、名前・説明・保存元、初期設定属性、enabled_entity_type_counttotal_entity_type_countupdated_at、著名人名設定を含みます。具体的な検出型や処理方式は次の詳細APIで確認します。

Bash · ユーザープロファイルの一覧
curl --request GET 'https://api.pii-fi.com/v2/profiles?source=workspace' \
  --header "Authorization: Bearer $PIIFI_API_KEY" \
  --header 'Accept: application/json'

source省略時は内蔵設定とユーザープロファイルの両方、source=built_inでは内蔵設定だけを返します。それ以外の値は400です。APIキーが属するワークスペースの範囲で選んでください。

固定IDと、画面で編集できる設定は別です

既存のdefaultpreset:*という内蔵IDも引き続き利用できます。ただし、defaultは画面の「標準プロファイル」を自動選択するIDではありません。画面で編集した内容を使う場合は、source=workspaceで取得した実際のIDを指定してください。

2. 詳細で現在の設定を確認する

GET/profiles/{profile_id}profiles:read

次の例のpol_example_replace_meは説明用です。一覧で受け取ったidに置き換えてください。成功時はrequest_idoccurred_atと、以下の項目を含むprofileオブジェクトを返します。

Bash · プロファイルの詳細
curl --request GET 'https://api.pii-fi.com/v2/profiles/pol_example_replace_me' \
  --header "Authorization: Bearer $PIIFI_API_KEY" \
  --header 'Accept: application/json'
field意味と注意
profile_id

string

処理要求に使うID。一覧では同じ値がidとして返ります。

name / description / source

string

名前、説明、保存元。sourceはworkspaceまたはbuilt_in

template_id / is_default_preset

string|null / boolean

初期状態に戻す設定のIDと、その設定が付いたユーザープロファイルかを示します。利用先の制限ではありません。複製には初期設定属性を引き継ぎません。

entity_types

string[]

現在の検出対象型。ソースコード用の初期状態では単独の日付JPII_DATETIME_DATEを含みません。

mask_overrides

object

型ごとの処理方式。methodfake(ダミー)、replace(ラベル)、full_mask(伏せ字)、keep(そのまま)。keepの情報は置き換えられません。

fake_scope

file | job

Batchでダミーを共有する範囲。fileはitemごと、jobは同じBatch全体。別のAPI要求の間では共有しません。

active_custom_rule_count

integer

現在の契約で実行できる、有効な追加ルール数。停止済みルールは含みません。

public_person_mode / public_person_protection_level

enum

著名人名の扱いと保護レベル。下の説明を確認してください。

configuration_fingerprint

string

実行設定を識別する64文字の指紋。設定や実行対象の追加ルールの変更は、再送時の同一要求判定にも反映します。

この応答には、辞書語句、正規表現、追加ルール本文、入力本文を含めません。追加ルールの編集内容はプロファイル画面で確認してください。存在しないIDと別ワークスペースのIDは、どちらも404です。

503の場合は必要な設定や稼働情報を取得できていません。別のプロファイルへ自動的に切り替えず、エラー処理の手順に従ってください。

3. 1件ずつ処理する場合

POST /detectまたはPOST /deidentifyのJSON本文へprofile_idを加えます。以下はdeidentifyの例です。detectではreturn_mappingを除いてください。URL、認証、Idempotency-KeyはQuickstartと同じです。

JSON · プロファイルで置換
{
  "text": "連絡先はsample@example.testです。",
  "profile_id": "pol_example_replace_me",
  "return_mapping": false
}

検出対象、置換方式、著名人名の扱い、有効な追加ルールが現在の契約に従って適用されます。設定を二重指定しないよう、entity_typesや著名人名設定の直接指定とは併用できません(400)。

4. 複数件を一括処理する場合

POST /batches最上位profile_idを指定します。itemsの中ではありません。全itemへ同じプロファイルを適用し、itemのentity_typesとは併用できません(400)。登録後の追跡と結果取得はBatchの手順に従います。

JSON · 同じプロファイルでBatch登録
{
  "operation": "deidentify",
  "profile_id": "pol_example_replace_me",
  "items": [
    {"id": "document-001", "text": "連絡先はalpha@example.testです。"},
    {"id": "document-002", "text": "連絡先はbeta@example.testです。"}
  ]
}

受付済みBatchは受付時の設定を保持します。後からプロファイルを編集したり追加ルールを停止したりしても、そのBatchの内容は変わりません。次の同期要求や新しいBatchから変更が適用されます。成功itemにはprofile_idが加わり、著名人名の扱いを使う場合はpublic_person_policyも返ります。

著名人名の扱いを選ぶ

プロファイルに保存した設定をそのまま使えます。プロファイルを使わない同期detect/deidentifyでは、以下をJSONへ直接指定することもできます。Batchでは直接指定せず、プロファイルに保存してください。

public_person_mode動作
off(省略時)著名人名という理由で人名候補を外しません。
review人名候補を残し、呼び出し側で確認するための判断理由を返します。
allow_high_confidence選択した保護レベルの条件に合う人名候補を対象から外します。

public_person_protection_levelpublic_person_modeと一緒に指定します。strong(既定)は辞書情報と公開人物を扱う文脈がそろい、私的な文脈がない場合に限定します。balancedは私的な文脈を除きつつ、歴史人物・故人の単独言及にも広げます。weakは辞書内の一意な正式名との完全一致を条件とし、患者・連絡先などの文脈でもその人名候補を外すため、用途を十分確認してください。住所・電話番号など別の型は通常どおり処理します。

off以外ではpublic_person_policyに位置と一般化した判断理由が加わります。この項目には氏名・周辺文を含めませんが、通常の検出応答やmappingの取り扱いには引き続き注意が必要です。

設定を変えるとき・これまでの呼び出しを続けるとき

  • profile_idを指定しない:これまでの動作を維持します。同期のentity_types指定、Batchのitemごとのentity_types指定もそのまま使えます。画面の標準プロファイルが自動適用されることはありません。
  • 追加ルール:有効でも現在の契約で利用できないルールは実行対象に入りません。active_custom_rule_countで確認します。実行対象のルールを処理できない場合は、黙って省略せずエラーを返します。
  • 設定変更後の再送:同じIdempotency-Keyで異なる設定を送ると409です。変更した設定で新しく処理する場合は新しいキーを使います。通信切断だけを理由にキーを変えず、再送時の判断に従ってください。
  • 編集・複製・初期状態に戻す:プロファイル画面で行います。これらの書込み操作やGitHub監視の管理は公開APIでは提供していません。
  • 画面から試す:API Sandboxでもプロファイルを選べ、要求JSONとBash用curlへ反映されます。実行すると通常のAPIと同じ使用量へ加算されます。
SYNCHRONOUS · FIND

detect — 候補を見つける#

POST/detectdetect

使う場面:文章を置き換える前に、何がどこで検出されたかを呼び出し側で確認・表示・判断したいとき。入力そのものは変更せず、個人情報候補のspansを返します。

処理単位

1要求のAPI上限は1,000,000 Unicodeコードポイントです。実効上限はこの値と現在のランタイム上限の小さい方です。PII-FIは本文を自動分割しません。

Request fields

field型・必須意味と注意
text

string · 必須

検出する本文。1文字以上、実効上限以下。request bodyをログへ残さない。

profile_id

string · 任意

保存済みプロファイルのID。detectに加えprofiles:readが必要。entity_typesや著名人名設定の直接指定とは併用できません。

entity_types

string[] · 任意

検出対象を絞る場合に指定。値はGET /entity-typesの現在の応答から選ぶ。

public_person_mode / public_person_protection_level

enum · 任意

著名人名の扱い。profile_idなしの場合だけ直接指定できます。保護レベルだけの指定は400。

stream

boolean · 任意

既定false。streamable HTTPを使う場合はtrueにし、Accept headerもSSEへ変える。

Response fields

field意味と次の処理
request_id

string

値を含まない追跡ID。調査用に保存できる。

profile_id / public_person_policy

条件付き

指定したプロファイルのIDと、off以外の著名人名設定を使った場合の判断情報。

spans

array

候補ごとのentity_type、検出値text、入力上のstartend

usage

object

processed_charactersconsumed_units。値を含まない利用情報。

Request
{
  "text": "担当者Aの連絡先はsample@example.testです。",
  "entity_types": [
    "JPII_CONTACT_EMAIL_ADDRESS"
  ]
}
Response
{
  "request_id": "req_example_detect_01",
  "spans": [{
    "entity_type": "JPII_CONTACT_EMAIL_ADDRESS",
    "text": "sample@example.test",
    "start": 9,
    "end": 28
  }],
  "usage": {
    "processed_characters": 31,
    "consumed_units": 1
  }
}

受け取った後に行うこと

  • 確認画面:spanを入力へ重ねて表示し、業務上の共有可否を利用者が判断できるようにする。
  • 機械判定:entity_type単位のルールは、現在の型一覧に存在する値だけで構成する。
  • 記録:監査や集計が必要でも、検出値span.textは保存せず、request ID、型、件数など必要最小限にする。
  • 分割:呼び出し側で本文を分割する場合、順序、各断片の対応、境界をまたぐ文脈の扱いは呼び出し側で管理する。
SYNCHRONOUS · TRANSFORM

deidentify — 渡せる形へ置き換える#

POST/deidentifydeidentify

使う場面:検出候補を元の値を直接含まないラベルへ置き換えた文章が必要なとき。検出と置換を一続きで行い、入力文字数を共通台帳へ1回だけ計上します。

Request fields

field型・必須意味と注意
text

string · 必須

検出して置き換える本文。同期上限はdetectと同じ。

profile_id

string · 任意

保存済みプロファイルのID。deidentifyに加えprofiles:readが必要。entity_typesや著名人名設定の直接指定とは併用できません。

entity_types

string[] · 任意

対象型を絞る場合だけ指定。省略時の利用可能型は現在のランタイム契約に従う。

public_person_mode / public_person_protection_level

enum · 任意

著名人名の扱い。profile_idなしの場合だけ直接指定できます。保護レベルだけの指定は400。

return_mapping

boolean · 任意

既定false。trueにはmapping:read scopeが必要。戻す必要がなければfalseのままにする。

stream

boolean · 任意

streamable HTTPを使う場合だけtrue。

Response fields

field意味と次の処理
request_id

string

値を含まない追跡ID。

profile_id / public_person_policy

条件付き

指定したプロファイルのIDと、off以外の著名人名設定を使った場合の判断情報。

text

string

置換済み本文。後続システムへ渡す対象。

mapping

object · 条件付き

return_mapping: trueのときだけ返る対応表。元の値を含む。

usage

object

今回処理した文字数と消費ユニット。

Request
{
  "text": "担当者Aの連絡先はsample@example.testです。",
  "return_mapping": true
}
Response
{
  "request_id": "req_example_deidentify_01",
  "text": "担当者Aの連絡先はメールアドレスAです。",
  "mapping": {
    "メールアドレスA": "sample@example.test"
  },
  "usage": {
    "processed_characters": 31,
    "consumed_units": 1
  }
}
mappingは復元素材であり、非識別化済みデータではありません

mappingには元の値が入ります。PII-FIは応答後に保存しないため、必要な場合は利用者側で暗号化し、閲覧者を制限し、対応する置換済み文章と処理IDを取り違えないよう管理し、不要になったら削除してください。ログ、分析基盤、例外監視へ送らないでください。

用途別の推奨

用途return_mapping理由
外部サービスへ渡す文章を作るだけfalse元に戻す必要がなければ、復元素材を作らない。
一時処理後に内部で復元するtruemappingを呼び出し側の保護領域で短期間だけ保管する。
確認画面で検出候補を選別したいまず/detectdeidentifyは検出と置換を一度に行うため、候補確認が先ならdetectを選ぶ。
SYNCHRONOUS · RESTORE

restore — 利用者のmappingで戻す#

POST/restorerestore

使う場面:deidentifyで置き換えた文章を、利用者が保管しているmappingで元の値へ戻すとき。PII-FIはmapping、対象本文、復元結果を通常の記録へ残さず、共通ユニットも消費しません。

field型・必須意味と注意
text

string · 必須

mappingのラベルを含む置換済み本文。

mapping

object · 必須

ラベルをkey、元の値をvalueとする対応表。request bodyをログへ残さない。

Request
{
  "text": "連絡先はメールアドレスAです。",
  "mapping": {
    "メールアドレスA": "sample@example.test"
  }
}
Response
{
  "request_id": "req_example_restore_01",
  "text": "連絡先はsample@example.testです。"
}
接続が切れた場合

完了済みのIdempotency-Keyを再送しても、復元結果は再表示されず409になります。新しいキーで自動再実行すると処理結果を二重に扱うおそれがあるため、呼び出し側で「結果不明」の状態を持ち、業務上の再実行判断を分けてください。

SYNCHRONOUS · STREAM

streamable HTTP — 同じ接続で進捗を受け取る#

/detect/deidentifyAccept: text/event-streamstream: trueを送ると、受付・進捗・終端結果をSSEで受信できます。処理モデルと利用量は通常の同期処理と同じで、別のBatchは作りません。

Streaming request
curl --no-buffer --request POST 'https://api.pii-fi.com/v2/detect' \
  --header "Authorization: Bearer $PIIFI_API_KEY" \
  --header 'Accept: text/event-stream' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: demo-stream-0001' \
  --data '{"text":"sample@example.test","stream":true}'
Event sequence
event: accepted
data: {"request_id":"req_example_stream_01","occurred_at":"2026-08-08T00:00:00.000Z"}

event: progress
data: {"request_id":"req_example_stream_01","stage":"processing","done":false}

event: result
data: {"request_id":"req_example_stream_01","spans":[],"usage":{"processed_characters":19,"consumed_units":1}}

クライアント実装の順序

  1. 1

    HTTP statusとContent-Type: text/event-streamを確認します。

  2. 2

    空行までを1eventとして読み、eventdataを分けます。TCP chunkの境界をevent境界として扱わないでください。

  3. 3

    acceptedのrequest IDを保持し、progressは値を含まない進捗として表示します。

  4. 4

    resultまたはerrorだけを終端として扱います。keep-aliveは15秒以内です。

同期streamは途中からの結果再取得APIではありません

接続が切れた後に同じIdempotency-Keyを再送すると409になり、完了結果は再表示されません。切断後も確実に状態と結果を取り直したい処理にはBatchを選んでください。

ASYNCHRONOUS · BATCH

Batch — 複数件を登録して後から受け取る#

POST/batchesbatches

使う場面:複数の文章をまとめて処理する、HTTP接続を結果まで維持したくない、切断後にも状態と結果を取り直したい場合。登録時にBatch IDと後続URLを受け取り、処理はバックグラウンドで進みます。

REGISTER202で受付

Batch IDとstatus/events/result URLを保存する。

TRACK進捗を追う

polling、SSE、Webhookから必要な方式を選ぶ。

FETCH結果を取得

終端状態を確認し、保持期限内にresult URLを読む。

DELETE不要なら削除

結果とmetadataを明示削除する。

ITEMS最大 200件
EACH ITEM同期の実効上限以下
TOTAL12,000,000 code points
RESULT24時間保持

Batch request fields

field型・必須意味と注意
operation

enum · 必須

detectまたはdeidentify。Batch全体で1種類。

profile_id

string · 任意

最上位に指定して全itemへ適用するプロファイルのID。batchesに加えprofiles:readが必要。itemのentity_typesとは併用できません。受付時の設定を使います。

items

array · 必須

1〜200件。同じBatch内でitem IDを重複させない。

items[].id

string · 必須

呼び出し側の一意ID。1〜160文字、英数字と._:-を使用。結果の対応付けに使う。

items[].text

string · 必須

処理本文。入力は暗号化して一時保管され、完了・失敗・取消で削除される。

items[].entity_types

string[] · 任意

itemごとに検出対象を絞る場合だけ指定。

webhook_endpoint_id

string · 任意

API画面で事前登録した通知先。結果そのものではなく、値を含まない状態・進捗通知を受け取る。

Create Batch · request
curl --request POST 'https://api.pii-fi.com/v2/batches' \
  --header "Authorization: Bearer $PIIFI_API_KEY" \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: demo-batch-20260808-001' \
  --data '{
    "operation": "deidentify",
    "items": [
      {"id":"document-001","text":"連絡先はalpha@example.testです。"},
      {"id":"document-002","text":"担当者Bへ連絡してください。"}
    ],
    "webhook_endpoint_id": "whe_example_00000001"
  }'
202 receipt · response
{
  "request_id": "req_example_batch_01",
  "occurred_at": "2026-08-08T00:00:00.000Z",
  "batch_id": "bat_example_0001",
  "status_url": "https://api.pii-fi.com/v2/batches/bat_example_0001",
  "events_url": "https://api.pii-fi.com/v2/batches/bat_example_0001/events",
  "result_url": "https://api.pii-fi.com/v2/batches/bat_example_0001/results",
  "created_at": "2026-08-08T00:00:00.000Z",
  "usage": {
    "processed_characters": 40,
    "consumed_units": 1
  }
}

receiptを受け取った直後に行うこと

  • 保存する:batch_id、3つの後続URL、自システムの業務ID、作成時刻。本文は保存要件に従い別管理する。
  • 保存しない:APIキー、request body、各itemの本文をジョブログへ複製しない。
  • 確認する:HTTP 202を受付成功として扱い、まだ処理完了ではないことを画面・状態機械へ反映する。
  • 再送する場合:同じBatch登録には同じIdempotency-Keyを使う。既存receiptが返り、二重登録・二重計上されない。

Batch endpoint一覧

メソッドパス成功いつ使うか
GET/batches200workspace内のBatch一覧を取得する。
GET/batches/{batch_id}200現在の状態と完了件数をpollingする。
GET/batches/{batch_id}/events200 SSE進捗を接続中に受信し、切断後に続きから再接続する。
GET/batches/{batch_id}/results200完了後、item順の結果を取得する。
POST/batches/{batch_id}/cancel202未完了Batchへ取消を要求する。Idempotency-Keyが必要。
DELETE/batches/{batch_id}204保管結果とmetadataを明示削除する。

状態をpollingする

固定のpolling間隔はAPI契約で強制しません。workspaceのrequest/分上限を超えないよう、状態が変わらない間は呼び出し間隔を広げ、429ではRetry-Afterに従ってください。

GET status · response
{
  "request_id": "req_example_batch_02",
  "occurred_at": "2026-08-08T00:00:01.000Z",
  "batch_id": "bat_example_0001",
  "operation": "deidentify",
  "status": "running",
  "progress": {"completed": 1, "total": 2},
  "created_at": "2026-08-08T00:00:00.000Z",
  "updated_at": "2026-08-08T00:00:01.000Z",
  "result_expires_at": null,
  "error_code": null
}
queued実行待ち。結果取得はまだ行わない。
running処理中。progressを更新する。
completed全item完了。resultsを取得する。
partial成功と失敗が混在。resultsを取得しitemごとに処理する。
failedBatchが失敗。error_codeとrequest IDで判断する。
canceled取消完了。未処理itemの結果を成功として扱わない。

結果をitem IDで対応付ける

結果は登録したitem順です。ただし、順番だけに依存せずidで自システムの対象へ対応付けてください。partialでは成功itemと失敗itemを分けて扱います。

Batch result · response
{
  "request_id": "req_example_batch_03",
  "occurred_at": "2026-08-08T00:00:03.000Z",
  "batch_id": "bat_example_0001",
  "operation": "deidentify",
  "items": [
    {"id":"document-001","status":"succeeded","text":"連絡先はメールアドレスAです。"},
    {"id":"document-002","status":"succeeded","text":"担当者Bへ連絡してください。"}
  ]
}

detect成功itemにはspans、deidentify成功itemには置換済みtextが入ります。失敗itemには値を含まないerror.codeと定型messageだけが入ります。

ASYNCHRONOUS · SSE

SSE — Batch進捗を続きから受け取る#

GET/batches/{batch_id}/eventsbatches

使う場面:サーバーまたは画面が接続中のあいだ、pollingより少ない要求で進捗を更新したいとき。progresscompleteerrorを受信します。

Initial connection
curl --no-buffer 'https://api.pii-fi.com/v2/batches/bat_example_0001/events' \
  --header "Authorization: Bearer $PIIFI_API_KEY" \
  --header 'Accept: text/event-stream'
Reconnect after event 12
curl --no-buffer 'https://api.pii-fi.com/v2/batches/bat_example_0001/events' \
  --header "Authorization: Bearer $PIIFI_API_KEY" \
  --header 'Accept: text/event-stream' \
  --header 'Last-Event-ID: 12'

再接続アルゴリズム

  1. 1

    受信したeventのidを、本文を含めずBatch IDと一緒に保存します。

  2. 2

    切断したら、最後に処理済みのIDをLast-Event-IDへ設定して再接続します。

  3. 3

    同じevent IDを再受信しても状態更新を二重適用しないようにします。

  4. 4

    completeまたはerrorを終端として接続を閉じます。complete後はresults endpointを呼びます。

keep-alive

15秒以内に接続維持用データが送られます。proxyやロードバランサーのidle timeoutは、この接続を不必要に切らないよう設定してください。

ASYNCHRONOUS · WEBHOOK

Webhook — 接続を維持せず完了を受け取る#

使う場面:Batch登録後に接続を閉じ、PII-FIから自システムの公開endpointへ状態・進捗通知を届けたいとき。送信先はAPI画面の「完了通知」で事前登録し、Batch登録時にwebhook_endpoint_idで選びます。

通知に処理値は含まれません

Webhook bodyはevent ID、種別、Batch ID、作成日時、状態、完了数/全件数だけです。入力、検出値、mapping、結果、secretは含みません。完了通知を受けた後、認証済みのresults endpointから結果を取得します。

受信endpointの条件

HTTPS・443

公開HTTPS endpointだけを登録できます。redirectは追跡しません。

public address

送信ごとにDNSを解決し、loopback、private、link-local、reserved、multicastのIPv4/IPv6を拒否します。

10秒以内に2xx

timeoutは10秒。2xxだけを成功として扱い、それ以外は再送対象です。

Headersとbody

Headers
Content-Type: application/json
PII-FI-Webhook-ID: evt_example_0001
PII-FI-Webhook-Timestamp: 1786147200
PII-FI-Webhook-Signature: v1=<hex-digest>
Body
{
  "event_id": "evt_example_0001",
  "type": "batch.progress",
  "batch_id": "bat_example_0001",
  "created_at": "2026-08-08T00:00:01.000Z",
  "status": "running",
  "progress": {"completed":1,"total":2}
}

署名をraw bodyで検証する

timestamp + "." + raw_bodyのHMAC-SHA256をWebhook secretで計算し、header内のいずれかのv1署名と定数時間比較します。JSON parseや再serializeをするのbodyが必要です。

Node.js · signature verification
import crypto from 'node:crypto';

function verifyPiifiWebhook({ rawBody, timestamp, signatureHeader, secret }) {
  const ageSeconds = Math.abs(Date.now() / 1000 - Number(timestamp));
  if (!Number.isFinite(ageSeconds) || ageSeconds > 300) return false;

  const expected = crypto.createHmac('sha256', secret)
    .update(`${timestamp}.`)
    .update(rawBody)
    .digest();

  return String(signatureHeader).split(',').some((entry) => {
    const [version, hex] = entry.trim().split('=', 2);
    if (version !== 'v1' || !/^[0-9a-f]+$/i.test(hex || '')) return false;
    const received = Buffer.from(hex, 'hex');
    return received.length === expected.length
      && crypto.timingSafeEqual(received, expected);
  });
}

受信処理の安全な順序

  1. 1
    raw bodyのまま署名を検証

    秘密が一致しない、timestamp差が5分を超える場合は受け付けません。

  2. 2
    Webhook IDの重複を確認

    PII-FI-Webhook-IDまたはbodyのevent_idを一意制約つきで記録し、同じeventの再適用を防ぎます。

  3. 3
    受領を永続化して2xxを返す

    重い業務処理やresults取得は自システムのqueueへ渡し、10秒の送信timeout内に応答します。

  4. 4
    完了時にresultsを取得

    Webhook body自体を処理結果として扱わず、APIキーでBatch statusとresultsを取得します。

secret rotationと再送

secretは作成・rotation直後に一度だけ表示されます。rotation後24時間は新旧両方のv1署名がheaderへ入り、その後に旧secret暗号文を削除します。受信側は切替期間中、新旧secretのどちらでも検証できるようにしてください。

送信失敗時は1分、5分、15分、1時間、3時間、6時間の間隔で再送し、最長24時間で打ち切ります。再送ごとに重複を無害化してください。

RELIABILITY

冪等性と再試行を正しく実装する#

処理系POSTには8〜160文字のIdempotency-Keyが必要です。同じworkspace・操作で24時間一意にし、業務上の1処理と1対1で対応させます。ネットワークエラーのたびに新しいキーを生成すると、二重処理・二重計上を防げません。

キーを作るタイミング

プロファイルを使う要求では、IDだけでなく実行設定も同一要求の判定に含めます。プロファイルや有効な追加ルールを変更して同じキーで送ると409です。新設定での新しい処理と、同じ処理の通信再送を区別してください。受付済みBatchは受付時の設定を保持します。

  1. 1
    要求を送る前に生成する

    UUIDなど衝突しにくい値を作り、自システムの値を含まない業務処理IDと対応付けます。

  2. 2
    送信開始前に保存する

    process再起動後も同じ業務処理で同じキーを使えるようにします。本文を冪等台帳へ複製しないでください。

  3. 3
    異なる処理へ使い回さない

    endpoint、workspace、本文、operationが異なる処理には新しいキーを使います。

  4. 4
    結果の扱いを記録する

    成功、明示エラー、結果不明を分けます。「timeout=未実行」と決めつけないでください。

同期処理とBatchの違い

同期detect/deidentify/restoreBatch登録
同じキーの再送処理中・完了後とも409既存receiptを200で返す
前回結果の再表示しないBatch IDと後続URLを再取得できる
二重計上行わない行わない
接続切断後の回復APIから完了結果を取り直せないreceipt再取得後、status/resultsで追跡できる
向く処理同じ接続で結果を受け取れる短い処理切断後にも確実に状態・結果を回復したい処理
同期要求がtimeoutしたら、新しいキーで自動再実行しない

応答を受け取れなくても、サーバー側では処理と計上が完了している可能性があります。同じキーは409になり、新しいキーは別処理として扱われます。結果回復が必須の業務は最初からBatchを使ってください。

再試行の判断表

状況判断Idempotency-Key
400/401/403/413/410同じ要求を自動再試行しない。原因を直す。修正した別処理なら新規キー。
429Retry-After後に、回数上限つきで再試行。同じ業務処理なら同じキー。
502/503を明示応答で受信待機時間を延ばしながら限定回数で再試行。継続時は停止。同じ業務処理なら同じキー。
接続timeout/切断でstatus不明同期は結果不明として自動再実行しない。Batchは同じキーでreceiptを再取得。新しいキーへ切り替えない。
Webhookの同一eventを再受信成功応答を返し、業務処理を二重適用しない。Webhook IDで重複排除。
CAPACITY

rate・concurrency・文字数上限#

request頻度と同時処理数はAPIキーごとではなくworkspace全体の合算です。同じPersonalまたはTeamで複数キー・複数serverを使っても、枠は共有します。同時処理数には同期処理と実行中Batchの両方が入ります。

プラン有効キー上限request/分同時処理Batch
Personal Standard2602
Personal Pro103005対応
Team Small51203
Team Growth2060010対応
Team Enterprise501,20020対応

三つの上限を別々に扱う

request/分

参照系を含むHTTP要求の流量。429ではRetry-Afterに従う。

同時処理

実行中の同期処理とBatchの合計。処理完了までworker slotを占有する。

入力文字数

同期は最大1,000,000、Batch全体は最大12,000,000 Unicodeコードポイント。

呼び出し側へqueueを置く

複数serverから直接一斉送信すると、各serverは自分以外の同時処理を把握できません。workspace単位のqueueまたは共有semaphoreを置き、/capabilitiesの現在値を上限として流量を制御してください。

Queue policy · pseudocode
limits = GET /capabilities → limits

enqueue(job)

while queue has jobs:
  wait until active_processing < limits.concurrency
  wait until request_budget is available
  send job with its persisted Idempotency-Key

  if response is 429:
    pause until Retry-After
  if response is 502 or 503:
    retry with bounded exponential backoff
  otherwise:
    do not retry automatically

上限超過の要求ではユニットを消費しません。実際の受付数はplan上限とサービス全体の稼働上限の小さい方です。

DATA SAFETY

どこに何が残るか#

「PII-FIが通常の記録へ残さないこと」と「呼び出し側が保存してよいこと」は別です。以下の表を、自システムのログ・DB・queue・監視・backupまで含めて確認してください。

データPII-FI側呼び出し側で必要な対応
同期request本文通常の記録へ残さないHTTP debug log、APM、例外監視、reverse proxyでbody記録を無効化する。
検出値・spans応答後に通常の記録へ残さない保存が不要ならメモリ内だけで扱う。監査では値でなく型・件数・request IDを検討する。
非識別化済みtext同期では通常の記録へ残さない後続システムへ渡す前に、想定どおり置換されたか確認する。
mapping要求した応答でだけ返し、保存しない元の値を含む。暗号化、アクセス制御、対応するtextとの関連付け、期限削除を行う。
restore対象・結果処理後に破棄し、通常の記録へ残さない復元境界を限定し、復元結果が低い保護領域へ流れないようにする。
Batch入力AES-256-GCMで一時保管。完了・失敗・取消で暗号文とDEKを削除登録後も自システム側のqueueやretry payloadに複製されていないか確認する。
Batch結果完了後24時間。明示削除可能。期限後は410期限内に取得し、取得後不要ならDELETEする。
APIキー平文は一度だけ表示。salted derivation、prefix、metadataを保持secret managerへ保管し、ログ・Git・clientへ出さない。不要時に利用停止する。
利用量台帳値を含まない月次ユニット情報を保持本文や検出値を自システムの課金・監査台帳へ結合しない。
Webhook通知値を含まない状態・進捗eventを最大24時間再送event IDで重複排除し、結果はAPIから取得する。

データ経路の確認範囲

入力元upload / DB / queue
自システムbody log / APM / retry
PII-FI処理・応答
出力先保存 / 共有 / 外部処理

PII-FIへの送信部分だけでなく、入力前と応答後を含む経路全体で値の保持を設計してください。

GO-LIVE CHECKLIST

本番投入前のチェックリスト#

ダミーデータによる結合試験で、次を全て確認してから実データを扱ってください。

認証

  • APIキーはserver-sideのsecret managerにある。
  • 用途ごとにキーを分け、必要最小限のscopeだけを付けた。
  • キー切替と利用停止の手順を試した。
  • /capabilitiesの現在値で機能と上限を判定している。

値の保護

  • request/response bodyをHTTP log、APM、例外監視へ送らない。
  • 検出値、mapping、復元結果をconsoleへ出さない。
  • mappingを使う場合は暗号化・権限・期限削除がある。
  • ダミーデータだけで正常系・異常系を試した。

信頼性

  • 業務処理ごとにIdempotency-Keyを送信前保存する。
  • timeoutを未実行と決めつけて新しいキーで再送しない。
  • 429のRetry-Afterと502/503の回数上限つきbackoffがある。
  • workspace全体のconcurrencyをqueueで制御する。

Batch・通知

  • Batch receiptを202受付として保存し、完了とは扱わない。
  • 結果を24時間以内に取得し、不要なら削除する。
  • SSE再接続で最後に処理済みのevent IDを使う。
  • Webhookはraw body署名、timestamp、重複、短時間2xxを確認する。
TROUBLESHOOTING

困ったときの確認順序#

401になり、同じキーが使えない

AuthorizationがBearer API_KEY形式か、余分な引用符や改行がないかを確認します。次にAPI画面で期限切れ・利用停止を確認します。キー値をログへ出して比較しないでください。

403になり、planが対応しているはずなのに使えない

planだけでは許可されません。キーのscope、現在のworkspace、Team roleを含む共通判定です。GET /capabilitiesとAPI画面のscopeを確認します。

プロファイルを指定したら400・403・404・409になる

400ではprofile_idとentity_types・著名人名設定を二重指定していないか、Batchではprofile_idが最上位かを確認します。403では処理scopeに加えてprofiles:readがあるか、404では同じキーのワークスペースで一覧に出るIDかを確認します。409では設定変更後に同じIdempotency-Keyを使っていないかを確認し、通信切断だけを理由に新しいキーで再実行しないでください。プロファイルの手順へ戻れます。

409になり、再試行できない

同じIdempotency-Keyが処理中・完了済み、または別の本文へ使われています。同期処理は結果を再表示しません。新しいキーで機械的に再送せず、業務側の状態を確認します。回復可能性が必要な処理はBatchへ切り替えます。

429が続く

複数キー・複数serverでもworkspaceの枠は共有です。Retry-Afterまで停止し、共有queue/semaphoreのactive数を確認します。/capabilitiesの現在のrequest/分とconcurrencyを使ってください。

SSEが途中で切れる、まとめて届く

proxy bufferingとidle timeoutを確認します。SSE parserはTCP chunkではなく空行をevent境界として扱い、Batch SSEでは最後に処理済みのIDをLast-Event-IDで送ります。

Webhook署名が一致しない

JSON parse後のbodyではなく受信したraw bodyを使っているか、timestampとbodyの間に.を入れているか、hex digestかを確認します。rotation期間は署名が複数入り得るため、全てのv1候補を検証します。

Webhookは届いたが結果が入っていない

仕様どおりです。Webhookは値を含まない状態・進捗通知です。batch_idを使い、APIキーでstatusとresults endpointを呼びます。

Batch結果が410になった

結果は完了後24時間で削除され、明示削除後も410です。同じ結果は再取得できません。完了通知から取得までのqueueと監視を見直してください。

調査時に用意するものrequest ID、UTC日時、endpoint、HTTP status、error code

入力本文、検出値、mapping、APIキー、Webhook secretは問い合わせへ含めないでください。

上限値・scope・APIパスは、④アプリ側の契約JSONとOpenAPIから生成・照合しています。例は全てダミーデータです。