Server APIは、TRACIOがお客様のワークスペースについてすでに収集した識別データを、 バックエンドから読み取るためのものです: 訪問者の履歴、個々のセッション、そして 短いウィンドウのベロシティカウンターです。
これはWebhooksを置き換えるものではなく、補完するものです:
| Webhooks | Server API | |
|---|---|---|
| 方向 | TRACIOがお客様のエンドポイントへプッシュ | お客様のバックエンドが必要に応じてプル |
| タイミング | 識別が発生するたび | 保持期間の範囲内でいつでも |
| 向いている用途 | イベントへの反応 | 判断中のデータ参照、バックフィル、調査 |
どちらのしくみもProプラン以上でご利用いただけます。
https://api.tracio.ai/v1これはブラウザ用エンドポイント(edge.tracio.ai)とも、ダッシュボード
(app.tracio.ai)とも別のホストです。3つはそれぞれ独立しています: ブラウザは
公開鍵でエッジと通信し、お客様のバックエンドはシークレットキーでServer API
と通信します。
すべてのリクエストは、シークレットキーをbearerトークンとして運びます:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"Server APIはサーバー間通信専用です。 CORSヘッダーは意図的に返されないため、 ブラウザから呼び出すことはできません — これがシークレットキーをクライアント側の コードから遠ざけています。シークレットキーをブラウザへ配布しないでください。
ダッシュボードのAPI Keysで、secretタイプを選んで作成します。
tracio_sk_ に43文字が続く形で、合計53文字です。ダッシュボードは
先頭の数文字で一覧表示するため、キーを見分けられます。ローテーションを行うと新しいキーが発行され、古いキーは7日間動作し続けるため、 ダウンタイムなしで切り替えられます。新しいキーをデプロイし、トラフィックが移ったことを 確認して、古いキーを失効させてください。公開鍵はローテーションできません — 秘密では なく、設計上ページのソースに見えるものだからです。
すべてのルートは GET です。Server APIに書き込み操作はありません: データを読み取る
だけで、設定はダッシュボードにあります。
| メソッド | パス | 返すもの |
|---|---|---|
GET | /v1/visitors/{visitorId} | 1人の訪問者の集計履歴と、その最新セッション |
GET | /v1/visitors/{visitorId}/sessions | その訪問者のセッションのページ分割された一覧 |
GET | /v1/visitors/{visitorId}/sessions/latest | 直近のセッション1件 |
GET | /v1/visitors/{visitorId}/velocity | 短いウィンドウのアクティビティカウンター |
GET | /v1/sessions/{requestId} | リクエスト識別子による1件のセッション |
GET | /.well-known/webhook-keys | Webhookのプラットフォーム署名用の公開鍵(認証不要) |
末尾のスラッシュは受け入れられ、無視されます。未知のパスや誤ったメソッドは、他と同じ JSONのエラーエンベロープを返します — HTMLやプレーンテキストのページが返ることは 決してありません。
すべての読み取りは時間ウィンドウで区切られ、2つの省略可能なクエリパラメーターで 制御します:
| パラメーター | 受け付ける形式 |
|---|---|
from | YYYY-MM-DD またはRFC 3339の完全なタイムスタンプ |
to | YYYY-MM-DD またはRFC 3339の完全なタイムスタンプ |
to に日付だけを指定した場合、その日1日が丸ごと含まれます。400 invalid_request と time must be YYYY-MM-DD or RFC3339 という
メッセージで拒否されます。meta で返されるため、リクエストが
そのまま通ったと決めつけず、meta.from と meta.to を確認してください。curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"レスポンスは集計履歴を運び、最新セッションを埋め込んでいるため、一般的なケースでは 2回ではなく1回のリクエストで済みます:
{ "visitorId": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "firstSeenAt": "2026-05-02T10:11:12Z", "lastSeenAt": "2026-07-25T08:00:00Z", "visits": 42, "incognitoVisits": 3, "uniqueIps": 5, "uniqueCountries": 2, "browsers": ["Chrome"], "os": ["macOS"], "devices": ["desktop"], "risk": { "maxRiskScore": 63, "avgBotScore": 12.5, "botSessions": 7, "lastDecision": "real" }, "network": { "vpnSeen": false, "proxySeen": false, "torSeen": false, "datacenterSeen": true, "lastIsp": "Deutsche Telekom" }, "lastSession": { "requestId": "9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31", "visitorId": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "accountId": "user_8842", "timestamp": "2026-07-25T08:00:00Z", "tag": "checkout", "url": "https://shop.example.com/checkout", "ip": "203.0.113.42", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", "browser": { "name": "Chrome", "version": "126.0" }, "os": { "name": "macOS", "version": "14.5" }, "device": "desktop", "geo": { "country": "DE", "city": "Berlin", "timezone": "Europe/Berlin", "isp": "Deutsche Telekom" }, "network": { "vpn": false, "proxy": false, "tor": false, "datacenter": false, "asn": 3320 }, "bot": { "result": "human", "score": 4.5, "antidetectScore": 2.1 }, "identification": { "confidence": 0.97, "incognito": false, "matchType": "exact", "matchConfidence": 0.99 }, "decision": { "action": "real", "riskScore": 12 } }, "meta": { "plan": "business", "retentionDays": 90, "from": "2026-04-26T00:00:00Z", "to": "2026-07-25T12:00:00Z" }}| フィールド | 意味 |
|---|---|
visits, incognitoVisits | ウィンドウ内の総訪問数と、そのうちプライベートウィンドウでの訪問数 |
uniqueIps, uniqueCountries | ウィンドウ内で観測された異なるアドレスと国の数 |
browsers, os, devices | この訪問者が現れた異なる環境 |
risk.maxRiskScore | ウィンドウ内で記録された最大のリスクスコア、0..100 |
risk.lastDecision | 直近の訪問について記録された判定 |
risk.avgBotScore, risk.botSessions | ボットスコアの平均とボットセッションの数 — Business以上 |
network.*Seen | この訪問者についてVPN、プロキシ、Tor出口ノード、データセンターのアドレスが観測されたことがあるか |
network.lastIsp | 直近のISP — Business以上 |
lastSession | 直近の訪問の完全なセッションオブジェクト |
meta | プラン、その保持日数、そして実際に適用されたウィンドウ |
保持期間内にデータがない訪問者には、visitor not found in the retention window という
メッセージとともに 404 not_found が返ります — これは統合側の誤りではなく、その
訪問者が新規であるか、保持期間を過ぎたことを意味します。
セッションは2つの判定を運び、それぞれ別の問いに答えます — クライアントが自動化されて いたかどうかと、リスクエンジンが全体として下した結論です:
| フィールド | 取りうる値 |
|---|---|
bot.result | human、bot、uncertain |
decision.action | real、fake、suspicious |
bot.score と decision.riskScore はどちらも 0..100 のスケールです。Business以上
では、guidance がそれらを allow → challenge → review → deny というラダー上の
シナリオごとの推奨に変換します — 各段の意味については
Guidanceを参照してください。
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/sessions?limit=100&minRiskScore=50"| パラメーター | 既定値 | 備考 |
|---|---|---|
limit | 50 | 上限は 500。それより大きい値は拒否されず切り詰められます |
from, to | プランの保持期間 | 上で説明した共通の時間ウィンドウ |
cursor | — | 前のページから受け取った不透明なページネーションカーソル |
botResult | — | このボット判定を持つセッションだけを残します |
minRiskScore | — | このリスクスコア以上のセッションだけを残します、0..100 |
セッションは新しいものから順に返されます:
{ "items": [ { "requestId": "9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31", "visitorId": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "timestamp": "2026-07-25T08:00:00Z" } ], "nextCursor": "MTcyMTg5NDQwMDAwMDphYmMxMjM", "hasMore": true, "meta": { "plan": "business", "retentionDays": 90, "from": "2026-04-26T00:00:00Z", "to": "2026-07-25T12:00:00Z" }}ページ送りはカーソル方式です。page や offset のパラメーターはありません: 受け取った
nextCursor を cursor として渡し、hasMore が true である間は続けてください。
async function allSessions(visitorId: string, secretKey: string) { const sessions = [] let cursor: string | undefined
do { const url = new URL(`https://api.tracio.ai/v1/visitors/${visitorId}/sessions`) url.searchParams.set("limit", "500") if (cursor) url.searchParams.set("cursor", cursor)
const res = await fetch(url, { headers: { Authorization: `Bearer ${secretKey}` } }) if (!res.ok) throw new Error(`Server API: ${res.status}`)
const page = await res.json() sessions.push(...page.items) cursor = page.nextCursor } while (cursor)
return sessions}カーソルは不透明なものとして扱ってください — その中身は実装の詳細であり、変更される
可能性があります。編集されたカーソルは 400 invalid_request と malformed cursor
というメッセージで拒否されます。
直近の1件:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/sessions/latest"これはセッションオブジェクトをそのまま返します — 配列でもなく、エンベロープに包まれても
いません。ウィンドウ内にセッションがない訪問者には、
no sessions for this visitor in the retention window とともに 404 not_found が
返ります。
あるいは、Webhookのペイロードにも現れる識別子である requestId で取得します:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/sessions/9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31?visitorId=X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"ここでの visitorId は省略可能ですが、分かっている場合に渡すと検索が大幅に速く
なります。
ベロシティは「この訪問者が最近どれだけ活動しているか」に答えます — クレデンシャル スタッフィング、カードテスティング、大量アカウント作成に共通する形です。
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/velocity?window=1h"window は 1h、24h、7d を受け付け、既定値は 24h です。それ以外の値は
400 invalid_request と window must be one of: 1h, 24h, 7d で拒否されます。
{ "window": "1h", "events": 37, "uniqueIps": 9, "uniqueCountries": 3, "uniqueAccounts": 12, "botEvents": 4, "meta": { "plan": "business", "retentionDays": 90, "from": "2026-07-25T11:00:00Z", "to": "2026-07-25T12:00:00Z" }}uniqueAccounts は、このデバイスについて送信された異なる linkedId の値を数えます —
アカウント連携を参照してください。botEvents はBusiness以上
です。
フィールドがないことは「データなし」を意味し、ゼロを意味することはありません。
値のないフィールドは 0、""、null として送られるのではなく、完全に省略されます:
まったく新しい訪問者には matchConfidence がなく、問題のない訪問には
antidetectScore も suspectScore もありません。意図的な唯一の例外は bot.score で、
これはゼロのときでも常に存在します。フィールドは防御的に読み取ってください。
ペイロードはご利用のプランによって変わります。 APIアクセスを含むすべてのプランで、
基本のセッションが得られます — 各識別子、タイムスタンプ、URL、IP、user agent、
ブラウザ、OS、デバイス、位置情報、ネットワーク、ボット、識別、判定です。Proでは
identification.matchType、identification.matchConfidence、bot.antidetectScore
が加わります。BusinessとEnterpriseでは geo.isp、network.asn、
decision.suspectScore、identification.driftScore、reasons、behavior、
guidance、deviceInfo と、人単位のフィールド(personId、reputation、
linkedAccountsCount、linkedVisitorsCount)が加わります。ProプランでBusinessの
フィールドがないことはエラーではありません。
シグナルレベルの内部情報は、どのプランでも返されません: 個々のシグナル名、その 重み、判定の背後にあるしきい値、生のシグナル値、スコアの内訳は当社側にとどまります。 入力に逆算できてしまうスコアは、防御としての有用性を失います。
すべての失敗は1つのエンベロープを使います:
{ "error": { "code": "unauthorized", "message": "missing Authorization: Bearer <secret key>", "requestId": "8f14e45fceea167a5a36dedd" }}この requestId は訪問識別子ではありません。同じ名前を2つの異なる値が共有して
います: セッションのペイロード内では requestId は訪問のUUIDで、Webhookが配信するのと
同じものです。エラーエンベロープ内では、HTTP呼び出しごとに発行される24文字のトレース
識別子です。トレース識別子は、成功・失敗を問わずすべてのレスポンスの X-Request-Id
ヘッダーでも返されます。サポートへ問い合わせる際には添えてください — それによって
当社はお客様の呼び出しを正確に特定できます。
| HTTP | code | 意味 |
|---|---|---|
| 400 | invalid_request | パラメーターが欠けているか、形式が不正です |
| 401 | unauthorized | キーがない、無効、失効済み、または期限切れです |
| 402 | upgrade_required | ご利用のプランにAPIアクセスが含まれていません |
| 404 | not_found | 保持期間内に一致するものがありません |
| 405 | method_not_allowed | ルートは存在しますが、そのメソッドには対応していません |
| 429 | rate_limited | 秒あたりのリクエスト数、または1日あたりのクォータを超過しました |
| 500 | internal | 当社側で何かが失敗しました |
| 503 | unavailable | バックエンドのストアに一時的に到達できません |
チェックは決まった順序で実行されます — キー、次にプラン、そして上限 — そのため、不正な キーを持つリクエストは常にまずキーの問題を報告し、クォータの問題を報告することは ありません。
2つの 401 は意図的に異なる文面になっています: missing Authorization: Bearer <secret key>
はヘッダーがそもそも届かなかったことを、invalid or revoked API key は届いたが一致
しなかったことを意味します。402 は Data API requires the Pro plan or higher を
運びます。
認証済みのレスポンスはすべて、現在の状況を運びます:
| ヘッダー | 意味 |
|---|---|
X-RateLimit-Limit | 1日あたりのクォータ |
X-RateLimit-Remaining | 本日の残り呼び出し回数 |
X-RateLimit-Reset | リセットのUnix時刻 — UTCの深夜0時 |
Retry-After | 待機する秒数。429 のときのみ送られます |
| プラン | 秒あたりのリクエスト数 | 1日あたりのリクエスト数 | 履歴の深さ |
|---|---|---|---|
| Free | APIアクセスなし | — | 7日 |
| Pro | 10 | 10,000 | 30日 |
| Business | 50 | 100,000 | 90日 |
| Enterprise | 200 | 無制限 | 365日 |