メインコンテンツに移動

使用状況の報告(アクティビティ、スクリーンタイム、トランザクション)

このガイドでは、プロダクトが使用状況データを k-ID に送信し、信頼できる大人が Family Connect で確認できるようにする方法を説明します。同じ取り込みモデルへの入り口が 3 つあります。

  • /activity/push は、プロダクトが宣言したアクティビティタイプに対するレコードを受け取ります。
  • /screentime/push は、完了したスクリーンタイムの使用セグメントを受け取ります。
  • /transaction/push は、完了した購入を受け取ります。

3 つとも報告専用で、保護者の設定は不要です。プロダクトが起きたことを報告し、k-ID がそれを集計し、信頼できる大人向けの画面がその集計を参照します。どのプッシュ経路もリアルタイムの制御を発動しません。スクリーンタイム機能の全体、保護者が設定する制限、静かな時間、休憩リマインダー、セッションステートマシン、そしてそれが発火するイベントについては、スクリーンタイムガイドをご覧ください。トランザクションの可視化、購入の承認、支払いによる確認については、トランザクションガイドをご覧ください。

これらが何か、その境界はどこかについては、アクティビティトランザクションをご覧ください。

始める前に

3 つのエンドポイントはいずれも、送信した内容を k-ID のセッションに帰属させるため、年齢ゲートから受け取った sessionId が必要です。セッションをご覧ください。呼び出しはサーバー間で行い、認証で説明されているとおり API キーで認証します。

セッションに加えて、各経路には前提条件が 1 つあります。

  • アクティビティには宣言済みのアクティビティタイプが必要です。すべてのレコードは、プロダクトが Compliance Studio で宣言したタイプを指定し、タイプは API キーが対象とする環境にプッシュするまでローカルのままです。アクティビティタイプテストと公開をご覧ください。
  • スクリーンタイムにはプロダクトでスクリーンタイム機能が有効になっている必要があります。有効でない場合、/screentime/pushFEATURE_DISABLED を返します。
  • トランザクションにはプロダクトでトランザクション機能が有効になっている必要があります。有効でない場合、/transaction/pushFEATURE_DISABLED を返します。

3 つの取り込みエンドポイント

3 つのエンドポイントは 1 つのモデルを共有し、1 件の項目が持つ内容だけが異なります。

/activity/push/screentime/push/transaction/push
受け取るもの宣言済みアクティビティタイプに対するレコード完了したスクリーンタイムの使用セグメント完了した購入
バッチのフィールドと上限records、最大 1000events、最大 100events、最大 100
各項目が持つものidtypevaluetimestamp、任意の attributesiddurationSecondstimestampidtitleamountcurrencytimestampstatus、任意の descriptionurl
前提条件宣言・プッシュ済みのアクティビティタイプスクリーンタイム機能が有効トランザクション機能が有効
リアルタイムイベントなしなし(ライブ経路はスクリーンタイムガイドにあります)なし(ライブ経路はトランザクションガイドにあります)

共通するのは取り込みモデル全体です。各項目は冪等性のためのクライアント生成 id と直近 7 日以内の timestamp を持ち、1 つのバッチは 1 つのセッションのみを対象とし、項目は 1 件ずつ検証されて項目ごとに受理または拒否され、受理された内容は何かを発動するのではなく信頼できる大人が見る集計に反映されます。

アクティビティレコードのプッシュ

1 つのセッション分のレコードをまとめて /activity/push に送信します。

type はアクティビティタイプのキーで、タイプの作成時に k-ID が生成する識別子(UUID)です。自分で組み立てるのではなく、Compliance Studio のアクティビティタイプの設定からコピーしてください。

timestamp は実際にアクティビティが発生した時刻に置き換えてください。上記の値は説明用です。7 日より前のタイムスタンプは拒否されるため、例をそのままコピーすると古くなります。

リクエストの例

POST /api/v1/activity/push
Content-Type: application/json
Authorization: Bearer your-api-key

{
"sessionId": "b1a6482d-5242-4b4a-aa88-3fa52595a672",
"records": [
{
"id": "7c3e0c6e-9c2a-4f1e-bd2b-1f9a3c6d8e10",
"type": "2f9a1c84-6b3e-4d52-9f08-1a7c3e5d9b20",
"value": { "seconds": 1800 },
"timestamp": "2026-08-19T14:32:05Z",
"attributes": { "mode": "co_op" }
}
]
}

レスポンスの例

{
"sessionId": "b1a6482d-5242-4b4a-aa88-3fa52595a672",
"accepted": 1,
"rejected": 1,
"records": [
{ "id": "7c3e0c6e-9c2a-4f1e-bd2b-1f9a3c6d8e10", "status": "accepted" },
{ "id": "a4f2b8d1-3e7c-4a90-8b6f-2c5d9e0a1b34", "status": "rejected", "reason": "timestamp_too_old" }
]
}

200 レスポンスはすべてのレコードが記録されたことを意味しません。HTTP ステータスだけでなく、rejected とレコードごとの status を確認してください。

値の形式

各アクティビティタイプはメトリックタイプを宣言し、レコードの value オブジェクトはそのメトリックタイプのフィールドのみを含む必要があります。secondscount のようにフィールドが混在したレコードは、個々には有効であっても拒否されます。

メトリックタイプvalue備考
duration{ "seconds": 1800 }秒単位の整数、0 以上
currency{ "amount": 999, "currency": "USD" }amount は最小単位で 0 以上。currency は ISO 4217 のコード
count{ "count": 7 }0 以上
gauge{ "number": 0.85 }任意の倍精度浮動小数点数
boolean{ "bool": true }

通貨コードは ISO 4217 と照合されるため、GEMS のようなゲーム内通貨名は拒否されます。仮想通貨での購入はカウントとして報告するか、保護者に見せたいのが実際の金額であれば実通貨の金額として報告してください。

属性

attributes は任意のキー/値メタデータで、プロダクトのどのモードで時間が使われたかなど、内訳として見せたい観点に使います。各タイプは受け入れる属性キーを宣言し、ルールは厳格です。

  • 1 レコードに含められる属性は最大 20 個です。
  • キーは最大 64 文字、値は最大 256 文字です。
  • タイプが宣言していないキーは拒否されます。属性キーを 1 つも宣言していないタイプは、属性を一切受け付けません。
  • メールアドレス、電話番号、支払いカード番号に見える値は拒否されます。

個人データではなく、自社システムで解決できる不透明な識別子を送信してください。

アクティビティの拒否理由

理由内容
invalid_idid が UUID ではありません
unknown_typeAPI キーのモードが提供する設定に、その type がプロダクトのものとして宣言されていません
invalid_valuevalue がタイプのメトリックタイプと一致しない、負の値である、または複数のメトリックタイプのフィールドを含んでいます
timestamp_in_futuretimestamp が現在時刻より後です
timestamp_too_oldtimestamp が 7 日より前です
attributes_too_many属性が 20 個を超えています
attribute_key_too_long属性キーが 64 文字を超えています
attribute_value_too_long属性値が 256 文字を超えています
attribute_key_not_allowed属性キーがこのタイプに宣言されていません
attribute_value_forbidden_content属性値がメールアドレス、電話番号、または支払いカード番号に見えます
type_metric_type_unsupportedタイプのメトリックタイプをこの API バージョンが扱えません
transient_errorレコードは有効でしたが保存できませんでした。再試行してください

transient_error 以外の理由は、いずれもプロダクト側の修正が必要なレコードを示します。変更せずに再送しても同じ理由で拒否されるため、再試行キューではなくログに送ってください。

スクリーンタイム使用状況のプッシュ

/screentime/push は、完了した使用セグメントを事後に報告します。セグメントをバッファリングするサーバーや、シャットダウン時に合計を報告するゲームエンジンのための経路です。受理された各セグメントは durationSeconds を子どもの 1 日のスクリーンタイム合計に加算し、保護者の Family Connect のチャートに表示されます。アクティビティレコードと同じ形の取り込みです。

これは報告専用です。休憩リマインダー、制限警告、制限到達イベントは発火しません。これらはセッション開始時にスケジュールされるものであり、事後に再構成できないためです。プロダクトがこうしたリアルタイムのシグナルや、その背後にある保護者設定の制限・静かな時間・オーバーライドを必要とする場合、それはこのエンドポイントではなくスクリーンタイムガイドにあるライブ経路です。

リクエストの例

POST /api/v1/screentime/push
Content-Type: application/json
Authorization: Bearer your-api-key

{
"sessionId": "b1a6482d-5242-4b4a-aa88-3fa52595a672",
"events": [
{
"id": "9d4e2f81-7a3b-4c56-8e90-1f2a3b4c5d6e",
"durationSeconds": 1800,
"timestamp": "2026-06-24T09:00:00Z"
}
]
}

レスポンスの例

{
"sessionId": "b1a6482d-5242-4b4a-aa88-3fa52595a672",
"accepted": 1,
"rejected": 1,
"events": [
{ "id": "9d4e2f81-7a3b-4c56-8e90-1f2a3b4c5d6e", "status": "accepted" },
{ "id": "c1b2a3d4-5e6f-4708-9a1b-2c3d4e5f6071", "status": "rejected", "reason": "invalid_input" }
]
}

アクティビティと同様に、HTTP ステータスだけでなく rejected とイベントごとの status を確認してください。

セグメントのルール

各イベントは 1 つの完了したセグメントで、冪等性のための独自の id、使用の期間が始まった timestamp(UTC)、そして durationSeconds を持ちます。

  • durationSeconds は 1 秒から 24 時間までです。それより長い期間は複数のセグメントに分割してください。
  • セグメントはすでに完了している必要があります。timestamp + durationSeconds を未来にはできません。
  • timestamp は直近 7 日以内である必要があります。
  • 保護者が設定したタイムゾーンで深夜をまたぐセグメントは両方の日付に分割され、各日の合計にその日に実際に発生した使用が反映されます。
  • 1 回の呼び出しで最大 100 セグメントです。

スクリーンタイムの拒否理由

理由内容
invalid_inputセグメントが検証ルールに違反しました。不正な id、1 秒から 24 時間の範囲外の durationSeconds、範囲外の timestamp など。変更せずに再試行しても失敗します
internal_error一時的な保存の失敗です。再試行しても安全です

トランザクションのプッシュ

1 つのセッション分の完了した購入をまとめて /transaction/push に送信します。これは他の 2 つのプッシュと同じく報告専用です。報告した各購入は記録され、Family Connect でリンクされた保護者に表示されます。購入を報告しても、決済がブロックされることは決してありません。

プロダクトでトランザクション機能が有効になっている必要があります。有効でない場合、/transaction/pushFEATURE_DISABLED を返します。受理された各購入は通貨メトリックのイベントとしてアクティビティにも反映されるため、報告された購入は信頼できる大人が読む集計と同じ流れを通ります。

各項目は購入の内容を持ちます。title、通貨の最小単位での amountcurrency、購入が完了した timestamp、そして successful または failedstatus です。フィールドの全体、リクエストとレスポンスの形式、イベントごとのステータスについては、トランザクションガイドの購入の報告をご覧ください。

バッチ単位のエラー

一部の条件では呼び出し全体が失敗し、レスポンスには項目ごとの結果ではなく error コードが含まれます。エラー処理をご覧ください。

エラー原因
NOT_FOUNDこのプロダクトに、その sessionId のセッションが存在しません
INVALID_INPUTセッションが失効している、バッチが空またはサイズ上限を超えている、あるいはボディを解析できません
FEATURE_DISABLEDスクリーンタイム機能が有効でない状態で /screentime/push が呼び出された、またはトランザクション機能が有効でない状態で /transaction/push が呼び出されました

再試行と冪等性

3 つのエンドポイントはいずれも各項目にクライアント生成の id を取ります。/activity/push ではレコードの id/screentime/push ではセグメントの id/transaction/push では購入の id で、この id が再試行を安全にします。すでに受理された id の項目を再度プッシュしても、受理として数えられるだけで新たに保存されることはありません。そのため、途中でタイムアウトしたバッチはそのまま送り直せます。

この性質は id が安定している場合にのみ成り立ちます。ID は使用が発生した時点で 1 度だけ生成し、送信予定の項目とともに保存してください。送信時に生成した id は、再試行のたびに重複を生みます。

バッチ戦略の選び方

7 日のタイムスタンプ期間は上限であって目標ではありません。より小さく頻繁なバッチが望ましい理由が 2 つあります。

  • 信頼できる大人が見られるのは届いた使用状況だけなので、1 日 1 回プッシュするプロダクトでは前日の状況しか見せられません。
  • 7 日より古い項目は拒否されます。アクティビティの場合、その期間を超えるバックフィルは非同期のファイルアップロード経路を使用する必要があります。スクリーンタイムのセグメントにはそのような経路はないため、期間内に報告してください。

各エンドポイントのサイズ上限(1000 レコード、100 セグメント、または 100 購入)の範囲で、数分のプレイ分をセッションごとにバッチ化すれば、どちらの問題も避けられます。

統合の検証

/activity/send-test-digest は、リンクされた大人が受け取るダイジェストメールを、直近 7 日間の実際のデータを使って生成し送信します。ダイジェストにはセッションが蓄積したスクリーンタイム、アクティビティ、購入が反映されるため、プッシュした内容が保護者の読める形になっているかを確認する最も早い方法です。

リクエストの例

POST /api/v1/activity/send-test-digest
Content-Type: application/json
Authorization: Bearer your-api-key

{
"sessionId": "b1a6482d-5242-4b4a-aa88-3fa52595a672"
}

レスポンスの例

{
"sent": true
}

このエンドポイントについて知っておくべき点が 4 つあります。

  • テストモード専用です。 ライブの API キーでは NOT_FOUND エラーになります。実際にリンクされた大人にメールが送られることはありません。
  • セッションにリンクされた大人が必要です。 hasApproverEmail が false のセッションでは INVALID_INPUT が返ります。
  • sent: false は成功です。 直近 1 週間にまとめる対象がなかったことを意味し、メールは送信されていません。
  • 直近 7 日間が対象です。 期間は当日までなので、このセッションにプッシュしたデータも含まれます。

任意の localeja など)を指定すると、その言語のメールをプレビューできます。

統合チェックリスト

  • Compliance Studio でアクティビティタイプを宣言し、API キーが対象とする環境に設定をプッシュしている。スクリーンタイムをプッシュする場合はスクリーンタイム機能を、トランザクションをプッシュする場合はトランザクション機能を有効にしている。
  • 項目 ID を使用の発生場所で生成し、再試行で再利用できるよう項目とともに保存している。
  • rejected と項目ごとの reason を読み取り、拒否率の変化を検知し、一時的な理由(アクティビティは transient_error、スクリーンタイムとトランザクションは internal_error)のみを再試行するレスポンス処理を実装している。
  • タイムスタンプは UTC で、プッシュ間隔は 7 日の期間に対して十分に短い。
  • 属性は宣言済みのキーのみで、個人データを含まない。
  • テストダイジェストを送信し、エンドツーエンドで内容を確認している。