Python
開封とクリックのトラッキング
`emails.get_tracking` と `tracking` リソース全体。
1 通のメッセージ
from openemail import openemail report = openemail.emails.get_tracking('msg_…') print(report['openCount'], 'opens from', len(report['recipients']), 'recipients')for link in report['links']: print(link['url'], link['clickCount'])一度もトラッキングされなかったメッセージは、空のレポートではなく is_not_found が true の OpenEmailApiError を送出します。「何も記録していない」と「誰も開かなかった」は別の答えであり、同じレスポンスを共有してはなりません。
メールボックス全体
import time from openemail import openemail openemail.tracking.list(opened=False, days=7, limit=100)openemail.tracking.get_stats(days=30, offset_minutes=time.localtime().tm_gmtoff // 60)openemail.tracking.get('msg_…')openemail.tracking.list_opens('msg_…', include_machine=True)openemail.tracking.list_clicks('msg_…')list、list_opens、list_clicks は 1 ページ分の {'items': [...], 'hasMore': ..., 'nextCursor': ...} を返し、list_all、iterate、list_all_opens、iterate_opens、list_all_clicks、iterate_clicks がすべてのページをたどってくれます。get、list_opens、list_clicks は、msg_… の送信 id とトラッキング記録自身の tmsg_… のどちらでも受け取ります。
emails 上のフィールドではなく独立したリソースであり、その理由は網羅性です。emails が一覧するのは送信記録であり、それはこの API が扱ったメールにしか存在しません。コンポーザー、MCP ツール、アシスタントはいずれも送信記録なしで送るので、emails の上に作ったレポートは、メールボックスについてではなくあなたの API トラフィックについてのレポートになってしまいます。
数字を正直に読む
| 組 | 意味 |
|---|---|
| opens / clicks | 適用されたもの。メッセージがピクセル付きで、あるいは書き換えられたリンク付きで出ていったかどうかです。 |
| opened / clicked | 実際に起きたこと。 |
| openCount | カウント対象のヒット。スキャナーとプライバシープロキシは除外されます。 |
| openCountRaw | すべてのヒット。これをエンゲージメントとして引用すると、開封率が 100% を超えます。 |
| attributable | 読まれたことを、そもそも特定の受信者に結び付けられるかどうか。 |
tracking.get_stats の比率は、送信したすべてではなく、トラッキングされたメッセージを母数とします。そうでなければ、10 通に 1 通しかトラッキングしないメールボックスは、崩壊したように見えてしまいます。
パラメーター: tracking.list
openedbool- `True` はカウント対象の開封が 1 件以上あるメッセージを、`False` は開封のないトラッキング済みメッセージを選びます。どちらも既定ではなく、`False` が未トラッキングのメールを意味することはありません。それらはこの一覧にまったく現れません。
clickedbool- カウント対象のクリックについての同じフィルターで、`opened` とは独立に適用されます。両方を指定することもでき、その場合メッセージは両方を満たす必要があります。
daysint- 今から何日前までを見るか。1 から 365 で既定は 30 です。範囲外は 422 になります。期間はトラッキング記録が作られた時点で測られ、送信が実際に出ていった記録だけが一覧されます。
limitint- 1 ページあたりのレポート数を新しい順に指定します。1 から 200 で既定は 50 です。次のページは、同じ絞り込み条件のままページの `nextCursor` を `cursor` として渡すと得られます。期間全体をたどるなら `list_all` や `iterate` に任せます。
レスポンス: TrackingResource
objectLiteral['tracking']- `tracking.get`、`tracking.list`、`emails.get_tracking` を通じて、それ自体として取得されたレポートでは常に `'tracking'` です。取得済みメッセージ上に `email['tracking']` として入れ子になった同じレポートには、このキーがありません。そこではそれは取得されたものではなく、そのオブジェクトの一部だからです。
idstr- トラッキング記録自身の id、`tmsg_…` です。ヒット単位の呼び出しである `list_opens` と `list_clicks` はこれをキーにしており、そこへ渡された `msg_…` はまずこれに解決されます。
sendIdstr | None- これに対応する `msg_…` の送信。送信レコードが書き込まれなかった場合は null。コンポーザー、MCP の `sendEmail`、アシスタントはいずれも送信レコードなしで送信する。トラッキングが対象とするのはメールボックス全体であり、API のトラフィックだけではない。
threadIdstr | None- 閲覧 UI がメッセージを再び見つけられるよう、送信後に設定される。ドライバーが何も返さなかった場合は null。必須ではなく、この値が null のレコードでも集計の対象になる。
messageIdstr | None- RFC 5322 の Message-ID であり、OpenEmail の id ではない。これも送信後に設定され、トランスポートが値を返さなかった場合は null。
subjectstr | None- 送信時点の件名。件名なしで記録されたメッセージでは null。
fromstr- 送信元アドレス。送信レコードから結合するのではなく、このレコードにコピーして保持する。レポートは事後かなり経ってから読まれるものであり、そうしなければ、その後に修正または削除されたアドレスが過去の記録を書き換えてしまう。
sourceEmailSource | str- どの経路から送信されたか: `composer`、`api`、`mcp`、`ai`、`oauth`、`form`。この SDK がまだ名前を挙げていない経路が破壊的変更にならないよう、型は開いた形で定義されています。
sentAtstr | None- メッセージが送信された時刻。ISO 8601 の時点として表される。送信が完了しなかったレコードでは null。`tracking.list` はそれらを除外するが、`get` は除外しない。
opensbool- このメッセージにピクセルが実際に適用されたかどうか。現在のアカウント設定ではなく、実行時に何が行われたかを表す。
clicksbool- このメッセージのリンクが書き換えられたかどうか。本文にリンクがなければ false です。そのときは何も変更されておらず、そうでないと主張する記録はバイト列と辻褄が合わなくなるからです。
openedbool- コピーにわたってカウント対象の開封が 1 件でも記録されたかどうか。`opens` と併せて読んでください。収集していないからデータがないことと、誰もメッセージを読まなかったことは別の事実です。
clickedbool- カウント対象のクリックが 1 件でも記録されたかどうか。開封より強い証拠です。画像がブロックされる頻度は、リンクがたどられない頻度よりはるかに高いからです。
attributablebool- ここでのすべての閲覧を、特定の受信者に結び付けられるかどうか。帰属できないコピーにカウント対象の活動が現れた瞬間に false になります。これは複数宛先の場合で、1 つの本文が 1 つのトークンでリスト全体に届くケースです。「Bob はこれを開いていない」と書く前に確認してください。
openCountint- 人によるものと考えられる開封を、コピーにわたって合計したもの。機械的なヒットは除外され、30 秒以内の繰り返しは 1 件にまとめられるので、読み手の前に出すべき数字はこれです。
clickCountint- カウント対象のクリックを、コピーにわたって合計したもの。メッセージ単位ではなくリンク単位で重複排除するので、数秒差でたどられた異なる 2 本のリンクは 2 クリックです。
openCountRawint- スキャナーとプライバシープロキシを含む、すべてのピクセル取得。`openCountRaw - openCount` は分類器が除外した件数であり、そもそもフィルタリングが行われたことを示す唯一の証拠です。
clickCountRawint- 書き換えられたリンクへのすべての訪問。機械的なヒットと繰り返しを含みます。
firstOpenAtstr | None- コピーにわたる、カウント対象の最も早い開封。なければ null です。機械的なヒットでこれが動くことはありません。
lastOpenAtstr | None- 各コピーを通じて最も新しいカウント対象の開封。存在しない間は null。
firstClickAtstr | None- 各コピーを通じて最も古いカウント対象のクリック。存在しない間は null。
lastClickAtstr | None- 各コピーを通じて最も新しいカウント対象のクリック。存在しない間は null。
recipientslist[TrackingRecipientResource]- トラッキング対象のコピーごとに 1 エントリ。トランスポートが人ごとにバイト列を変えられる場合は受信者ごとに、そうでない場合は共有エントリが 1 つだけ入る。共有エントリは実際に何らかのヒットが記録された場合にのみ残るため、何も起きていない「誰か」の行が実名の隣に並ぶことはない。
recipients[].emailstr | None- このコピーの宛先。送信時点の値を小文字化したもの。`attributed` が false のときに限り null。
recipients[].kindRecipientKind | None- そのアドレスがどのヘッダーに現れたか。レポートがメッセージと同じ形で読めるようにするためのもの。どのアドレスにも属さない共有コピーでは null。
recipients[].attributedbool- この行が個人を特定しているかどうか。`email` より先にこの値を読むこと。false は共有コピーであり、ヒットが 1 件でも記録された時点で一覧に現れる。受信者が 1 人だけのメッセージであっても、そのヒットに名前を付けることは、この仕組みが提供できない唯一の事実を捏造することになる。
recipients[].openCountint- このコピー単独でのカウント対象の開封数。除外条件はメッセージ全体の合計と同じで、マシンによるヒットは除外され、30 秒以内の繰り返しは 1 件にまとめられる。
recipients[].clickCountint- このコピー単独でのカウント対象のクリック数。重複排除はコピー単位ではなくリンク単位で行われる。
recipients[].firstOpenAtstr | None- このコピーで最も古いカウント対象の開封。存在しない間は null。
recipients[].lastOpenAtstr | None- このコピーで最も新しいカウント対象の開封。存在しない間は null。
recipients[].firstClickAtstr | None- このコピーで最も古いカウント対象のクリック。存在しない間は null。
recipients[].lastClickAtstr | None- このコピーで最も新しいカウント対象のクリック。存在しない間は null。
linkslist[TrackingLinkResource]- このメッセージ内で書き換えられたすべてのリンク。本文中の位置順に並ぶ。書き換えが行われなかった場合は空になる。`clicks` を無効にして送信したメッセージや、本文にリンクが 1 つもなかったメッセージがこれにあたる。
links[].idstr- リンク自身の id、`lnk_…`。クリック行の `linkId` が指す値であり、`list_clicks` で得たヒットをここのエントリに対応付けられる。
links[].urlstr- リンクの実際の遷移先。書き換え前のメッセージ内にあった値。リダイレクターは id をこの値に解決し、訪問者をそこへ送る。
links[].labelstr | None- メッセージに現れたとおりのアンカーテキスト。画像や裸の URL のようにアンカーテキストがなかった場合は null。レポートが 3 つものトラッキングパラメーターの付いた URL を引用する代わりに「料金ページのリンク」と書けるようにするためのもので、`url` の代わりにはならない。
links[].clickCountint- このリンクへのカウント対象の訪問数を、全コピーで合計したもの。メッセージの `clickCount` と同じ、リンク単位の 30 秒ウィンドウが適用される。
links[].clickCountRawint- このリンクへのすべての訪問。マシンによるヒットと繰り返しも含む。
リファレンス
emails.get_tracking()完全なリファレンスtracking.list()完全なリファレンスtracking.list_all()完全なリファレンスtracking.iterate()完全なリファレンスtracking.get_stats()完全なリファレンスtracking.get()完全なリファレンスtracking.list_opens()完全なリファレンスtracking.list_all_opens()完全なリファレンスtracking.iterate_opens()完全なリファレンスtracking.list_clicks()完全なリファレンスtracking.list_all_clicks()完全なリファレンスtracking.iterate_clicks()完全なリファレンス