【ITニュース解説】PostHog Capture Treats an Epoch Timestamp as Ingestion Time
2026年08月22日に「Dev.to」が公開したITニュース「PostHog Capture Treats an Epoch Timestamp as Ingestion Time」について初心者にもわかりやすく解説しています。
ITニュース概要
PostHogのAPIでイベント日時を過去に遡って記録するには、`timestamp`をエポックタイムではなくISO 8601形式で送る必要がある。誤るとデータは取り込み時点と記録される。`event`、`distinct_id`、`api_key`も必須だ。
ITニュース解説
PostHog Capture APIを利用して、ウェブサイトやアプリケーションからのユーザー行動データを収集する際、システムエンジニアとしてこのようなデータ収集基盤を構築する際には、データが正しく取り込まれるかどうかを事前に理解しておくことが不可欠である。この記事では、データが期待通りに記録されない主な理由と、それを避けるための方法について解説する。
最もよくある問題の一つが、イベントのタイムスタンプの扱われ方にある。PostHogは、イベントが発生した日時を示すために、ISO 8601という国際標準形式のタイムスタンプを要求している。この形式は「YYYY-MM-DDTHH:MM:SSZ」のように、日付、時間、タイムゾーン情報を含む厳密な文字列形式である。しかし、誤って「エポックタイムスタンプ」と呼ばれる数値形式、具体的には1970年1月1日0時0分0秒(UTC)からの経過秒数で表現された数値を送信してしまうケースがある。例えば「1770000000」のような数値がそれだ。
もしエポックタイムスタンプでイベントを送信した場合、PostHogのCapture APIはリクエストを正常に受け付け、「200 OK」という成功のレスポンスコードを返す。しかし、ここで注意が必要なのは、この成功レスポンスがデータが正しく記録されたことを意味するわけではないという点だ。PostHogは、エポックタイムスタンプをイベントの発生日時としてではなく、そのイベントがPostHogに「取り込まれた(Ingestion Time)」時間として処理してしまう。つまり、半年前のユーザーサインアップイベントを過去のデータとして送信したとしても、PostHog上ではそれが今日発生したイベントとして記録され、分析結果には今日突然の急増として表示されてしまうのだ。これは、過去のユーザー行動を正確に分析したいシステムにとって致命的な問題となる。この問題を解決するためには、タイムスタンプを必ず「2026-07-26T06:00:00Z」のようなISO 8601形式で送信する必要がある。
次に重要なのが、イベントデータに含めるべき必須フィールドだ。PostHog Capture APIでイベントを送信する際には、いくつかの情報が必ず必要となる。まず、「api_key」は、どのプロジェクトにデータを取り込むかを識別するためのキーで、プロジェクトの設定から取得できるプロジェクトキーを使用する必要がある。これは、個人用のAPIキーとは異なる。次に、「event」は、発生した行動の種類を示すイベント名で、例えば「user signed up(ユーザーがサインアップした)」のような具体的な文字列である。そして、「distinct_id」は、そのイベントを行ったユーザーやエンティティを一意に識別するためのIDだ。これは、同じユーザーの異なる行動を関連付けて分析するために非常に重要となる。
これらの必須フィールドのうち、eventまたはdistinct_idが欠けていたり、空の値であったりする場合、APIは「200 OK」を返すことがあるにもかかわらず、そのイベントはPostHogに取り込まれない。これは、APIのステータスコードだけを信頼するのではなく、データが実際に意図通りに記録されているかを確認する必要があることを示している。api_keyが欠けている場合は、通常「401 Unauthorized」といったエラーが返されるため、比較的早期に問題が発見されやすい。
多数のイベントを一度に送信する「バッチ処理」を行う場合も、同様のルールが適用される。バッチ処理では、複数のイベントオブジェクトを配列としてまとめて送信する。この際、配列内の個々のイベントオブジェクトごとに、上記のタイムスタンプ形式や必須フィールドのルールがチェックされる。例えば、500件のイベントをバッチで送信するとして、そのうち1件のイベントにdistinct_idが欠けていた場合、その1件のイベントだけが取り込まれず、残りの499件は問題なく処理される。バッチ処理を行う際には、過去の大量データを一括で取り込む「バックフィル」のシナリオが考えられるが、PostHogがそのデータを通常のイベントスパイクとして扱わないように、「historical_migration: true」というフラグをバッチリクエストに含める必要がある。これはデータ形式の検証とは別の、取り込み方に関する設定である。
このようなデータ送信時の問題を未然に防ぎ、開発者の負担を軽減するために、「Pixellint」というオープンソースツールが役立つ。Pixellintは、アナリティクスデータのペイロード(送信されるデータ本体)を検証するためのリンターツールである。このツールは、PostHogのCapture APIの公式ドキュメントに基づいて作成されたルールパックを持っており、送信しようとしているJSONデータがPostHogの要件を満たしているかをチェックできる。例えば、不適切な形式のタイムスタンプや、必須フィールドの欠落などをAPIに送信する前に検出してくれるのだ。
Pixellintを使うことで、開発者はAPIから「200 OK」が返ってきたにもかかわらずデータが取り込まれていなかったという事態を避けることができる。CLI(コマンドラインインターフェース)ツールとして、またはNode.jsのライブラリとしてプロジェクトに組み込むことも可能で、ブラウザ上で直接データをペーストして検証できるプレイグラウンドも提供されているため、手軽に利用できる。
また、異なるアナリティクスサービスを利用している場合は、それぞれのサービスのタイムスタンプ要件が異なることにも注意が必要だ。例えば、SegmentのHTTP APIはPostHogと同様にISO 8601形式のタイムスタンプを要求するが、Amplitudeは真逆でミリ秒単位のエポックタイムスタンプ(13桁)を要求する。もし10桁のエポックタイムスタンプをAmplitudeに送ってしまうと、それが1970年のデータとして扱われてしまう。このように、複数のシステム間でデータを連携させる場合、各システムのデータ形式の仕様を正確に理解し、適切に変換することが重要となる。
結論として、PostHog Capture APIを通じてユーザーイベントを正確に記録するためには、タイムスタンプをISO 8601形式で送信し、api_key、event、distinct_idといった必須フィールドを必ず含めることが不可欠である。APIからの「200 OK」レスポンスは、必ずしもデータが期待通りに記録されたことを意味しないため、データ形式の事前検証ツールであるPixellintの活用を検討すると良い。これらのポイントを理解し実践することで、データ収集の精度を高め、より信頼性の高いシステムを構築できるだろう。