2分で読了チュートリアル
コア記事

CDPなしでUTMキャンペーンをエンドツーエンドで追跡する方法

マーケター向けの実践的なプレイブック: ワークスペースのUTMテンプレート、Sheetsからの一括インポート、サーバーサイドのコンバージョン転送、そしてローンチ前にズレを検出するQAドライラン

Ana Kowalska
Marketing solutions engineering
5ステップのUTMパイプライン: ワークスペーステンプレート、キャンペーン上書き、一括インポート、サーバーサイド転送、GA4 DebugViewでの検証

私はこれまで3つの会社でUTM追跡をエンドツーエンドで構築してきました。毎回、同じ5つのことが同じ順序で壊れ、毎回、その修正方法も同じでした。テンプレート化をキャンペーンレベルまで引き上げ、コンバージョン転送をサーバー側まで押し下げ、両者の間にドライランを挟むことです。この記事の大部分はそれについてです。残りは、自分では思いつかないような壊れ方を検出するQAチェックリストです。

5つのタグそれぞれが何をするのかまだよくわかっていない場合は、UTMパラメータの解説がこのパイプラインの土台となる入門記事です。

これにはカスタマーデータプラットフォーム(CDP)は必要ありません。あなたのアトリビューションの課題が「3台のデバイスにまたがる4回の匿名タッチを1つの顧客ジャーニーに継ぎ合わせる」というものになれば、いずれ必要になるでしょう。しかし、私が最も頻繁に見る「すべての外部リンクに一貫してタグ付けし、クリックを捕捉し、コンバージョンをMetaとGA4にサーバーサイドで転送し、Safariを生き延びる」というケースでは、テンプレート機能付きのURL短縮ツールとConversions APIがあれば十分です。以下は、私が見てきた失敗パターンとともに紹介する、実際にうまくいくバージョンです。

UTM追跡でよくある失敗

私が一緒に仕事をするマーケターはUTMが苦手なわけではありません。問題は、ツールがUTMを一度だけ入力するのは簡単にする一方で、組織全体で統一するのは難しく、ローンチ後に修正するのは不可能にしがちだということです。よくある失敗パターンが4つあります。

表記のズレ。 ある人はutm_source=newsletterと入力し、別の人はutm_source=Newsletterと入力し、また別の人はutm_source=emailと入力します。半年後には、あなたの「newsletter」チャネルがGA4上で9通りの文字列バリエーションに分裂しています。後からこれをクリーンアップするのは、正規表現を書いて祈るような作業です。この慣習を持ち込んだ元祖のurchinTracker()スクリプト、つまりGoogleがAnalyticsを持つ前のUrchinというWeb解析製品で、2003年に一時オープンソース化された後に買収されたものですが、当時もテンプレート層はありませんでした。慣習は常に「一貫した表記で入力すること」であり、ツール側がそれを強制したことは一度もなかったのです。

大量発行時の手作業タグ付け。 4つの地域ストアにまたがる80本の短縮リンクを使うチラシキャンペーンは、320個のURLを手で入力し、スプレッドシートに貼り付け、短縮ツールにコピーし、祈るという作業を意味します。その半分はutm_contentを間違えます。誰も気づかないまま、キャンペーンは2週間進みます。

サーバーサイドのコンバージョン計測の抜け漏れ。 サンクスページでピクセルが発火し、GA4がそれを拾い、Metaもそれを拾い、それで仕事は終わりです。ところがSafariの新しいITPバージョンがリリースされ、広告ブロッカーの導入率が上がり、報告されるコンバージョンが3分の1減ります。AppleのITP 2.3リリースノートはまさにその仕組みを説明しています。リンク装飾はスロットリングされ、document.referrerは取り除かれ、ブラウザがサードパーティのJSを実行することに依存する分析フローは静かに劣化していきます。コンバージョン自体はサーバー上では今も発生しています。ただ、それが広告面に届いていないだけです。

ドライランがない。 新しいパイプラインを通過する最初のコンバージョンが、最初の本物の買い物客になってしまいます。何か設定を誤っていた場合、最適化アルゴリズムがすでに実際には機能していたキャンペーンから予算を引き上げてしまった3日後に、ようやくそれに気づくことになります。

この記事では、最初の3つをテンプレート、一括インポート、サーバーサイド転送で解決し、4つ目を、省略しやすく省略すると高くつく検証ステップで解決します。

ワークスペースとキャンペーンのUTMテンプレート

テンプレートは、一貫性の問題をスタックの上位に押し上げます。自社のタグ付け規約をワークスペースレベルで一度だけ定義し、必要な箇所にキャンペーンごとの上書きを重ね、あとはすべてのリンクに継承させます。これでタイプミスが入り込む余地はなくなります。

まずワークスペースのデフォルトを定義します。リテラル値は自社にとって決して変わらない変数(ニュースレターキャンペーンのutm_medium = emailなど)を固定し、プレースホルダーは作成時にリンクのペイロードから値を埋めます。

curl -X PUT \
  https://api.elido.app/v1/workspaces/1/utm-template \
  -H "Authorization: Bearer $ELIDO_TOKEN" \
  -d '{
    "utm_source":   "{{ channel }}",
    "utm_medium":   "{{ medium }}",
    "utm_campaign": "{{ campaign }}",
    "utm_content":  "{{ creative }}",
    "utm_term":     "{{ audience.segment }}"
  }'

ここで重要な点がいくつかあります。

  • プレースホルダーはクリック時ではなくリンク作成時に埋め込まれます。分析ツールに現れるのは、リンクが発行された瞬間に意図されていた内容であり、クリック時にリンクの遷移先が計算した何かではありません。これにより、半年後に何かがおかしく見えたときの監査ログの再構築がずっと楽になります。
  • 未知のプレースホルダーは即座に失敗します。一括インポートにcreative列が欠けていて、ワークスペースのテンプレートが{{ creative }}を参照している場合、APIは未解決の変数名とともに422を返します。サイレントな部分適用はありません。
  • リンクのタグ配列から読み取るlink.tag.<name>プレースホルダー(すべてのURLにクライアント識別子を埋め込む必要がある、マルチテナントの代理店に便利です)を含む、テンプレートの完全なリファレンスはドキュメントガイドにあります。

次にキャンペーンテンプレートを重ねます。キャンペーンはワークスペースから継承し、キャンペーン固有の部分だけを置き換えます。

curl -X POST \
  https://api.elido.app/v1/campaigns \
  -H "Authorization: Bearer $ELIDO_TOKEN" \
  -d '{
    "name": "Spring 2026 - DACH",
    "utm_template": {
      "utm_campaign": "spring_2026_dach",
      "utm_term":     "{{ audience.locale }}"
    }
  }'

キャンペーンで設定されていないものはすべてワークスペースのデフォルトにフォールバックします。この2段階のレイヤー構造は、実際の組織構造のほとんどをカバーします。ワークスペースレベルでの共通規約、キャンペーンレベルでのチーム固有または季節固有の上書きです。もし3段階目の継承が欲しくなったら、それは違和感のサインです。たいていの場合、2つのキャンペーンは、より賢いプレースホルダーの値を持つ1つのキャンペーンにまとめるべきだということを意味します。

ElidoダッシュボードのキャンペーンページにUTMデフォルトが設定された4つのキャンペーン: Spring 2026 launch(newsletter / email)、Newsletter weekly、Influencer DACH Q2(creator / partner)、Paid social Meta retargeting

リンクごとの上書きが手放すもの、それは上書きがテンプレートに関係なく発火するということです。保持されるもの、それは上書きが監査ログに行為者、タイムスタンプ、解決後と最終結果の差分とともに記録されるということです。半年後、200本のリンクを持つキャンペーンのうち1本だけがutm_term=manual_overrideになっている理由を誰かに聞かれても、あなたは答えられます。

Sheetsからの一括インポート、実際にマーケターが使うワークフロー

マーケターは一日中curlを叩いているわけではありません。キャンペーンブリーフは遷移先URLとキャンペーンのメタデータを載せたスプレッドシートとして届き、ローンチ期限は金曜日で、問題はそのスプレッドシートをどうやって、誰も同じUTM文字列を200回入力することなく、200本の短縮リンクに変えるかということです。

CSVの列名はテンプレートのプレースホルダー名に一致します(大文字小文字は区別しません)。Elidoが認識しない列は、警告とともに黙って破棄されるのではなく、意図的に破棄されます。サイレントなコピーは、誰かが内部メモ用に列を追加したせいでutm_brand_colorがGA4に現れてしまうような事態を招きます。

destination_url,channel,medium,creative
https://shop.example.com/de,newsletter,email,hero_a
https://shop.example.com/fr,newsletter,email,hero_a
https://shop.example.com/de,paid_social,meta,carousel_v2
https://shop.example.com/fr,paid_social,meta,carousel_v2

multipartとしてPOSTします。

curl -X POST \
  https://api.elido.app/v1/links/bulk \
  -H "Authorization: Bearer $ELIDO_TOKEN" \
  -F "csv=@launch_q2.csv" \
  -F "campaign_id=cmp_8a2f"

この検証フローが、1件ずつ操作するUIでは得られない利点を2つもたらします。

  • オールオアナッシングのコミット。 1行でも不正があればアップロード全体が中止され、該当する行番号と理由が返されます。row 47: unresolved variable {{ creative }}というエラーは、金曜午後4時に200本のリンクのうち47本がプレースホルダー文字列のまま解決されていたことに気づくよりも、はるかにましなエラーです。
  • ローンチ前プレビュー。 ダッシュボードの一括インポートプレビュー行は、コミット前に、レンダリングされたutm_*クエリ文字列を含む解決済みURLを表示します。2番目のリンクを見てテンプレートが期待どおりに動作したか確認し、最後のリンクを見てファイルの下の方の行でズレが起きていないか確認します。2回見るだけで1分です。

スプレッドシートの形が安定していない場合、つまり列の順序が入れ替わったり見出し名が変わったりする場合、一括インポートのエンドポイントは扱いにくくなります。修正すべきはツール側ではなく、キャンペーンブリーフのCSVスキーマを固定し、スキーマのズレをプロセス上のバグとして扱うことです。この広いパターンについてはマーケター向けソリューションページで議論しています。

Meta CAPIとGA4へのサーバーサイドコンバージョン転送

ピクセルのみのアトリビューションは、Safari ITP、広告ブロッカー、同意バナーによってコンバージョンの20〜40%を失います。この数字は業種によって変わり、DTCのEコマースは範囲の高い方に、B2BのSaaSは低い方に位置しますが、iOS 14以降に私が見てきたどの測定でも、ピクセルの信頼性は広告プラットフォームが前提とする95%を大きく下回っています。最適化アルゴリズムはノイズの多い入力を受け取り、CPAは実態よりも悪く見えます。

MetaのConversions APIドキュメントはこの点について明確です。サーバーイベントが本命であり、ブラウザ側のピクセルは補完にすぎません。GA4のMeasurement Protocolも同じ主張をしています。両プロトコルとも同じ形を受け付けます。コンバージョンの詳細を持つサーバーサイドイベント、重複排除用のevent_id、そして理想的にはプラットフォームが既知の訪問者にコンバージョンを結びつけられるようにするハッシュ化されたユーザー識別子です。

そのギャップを閉じる配線は機械的です。3つのステップがあります。

ステップ1: click_idを捕捉する。 すべてのElidoリダイレクトのレスポンスにはX-Elido-Click-Idヘッダーが含まれます。TS / Python / GoのSDKはそれをリダイレクトのレスポンスオブジェクト上に公開しますが、生のHTTPでも動作します。

curl -sI https://elido.me/launch | grep -i click-id
# X-Elido-Click-Id: clk_01HYZ7T8WV6KQX3M

これを遷移先ページ上のファーストパーティCookie(elido_click_id、TTL90日。典型的なSaaSの検討期間をカバーするのに十分な長さで、ePrivacyガイダンスを満たすのに十分な短さです)に保存します。チェックアウト時にそれを読み戻します。

ステップ2: 転送先を配線する。 転送したい面それぞれの認証情報をPUTします。どのサブセットでも構いません。設定されていない面は黙ってスキップされます。

curl -X PUT \
  https://api.elido.app/v1/workspaces/1/conversion-forwarding \
  -H "Authorization: Bearer $ELIDO_TOKEN" \
  -d '{
    "meta_capi": {
      "pixel_id": "1234567890",
      "access_token": "EAA…",
      "test_event_code": null
    },
    "ga4_mp": {
      "measurement_id": "G-ABC123",
      "api_secret": "abc_def_ghi"
    }
  }'

Mixpanelはコンバージョン転送先ではありません。Elidoの Mixpanel連携は、各短縮リンクのクリックをlink_clickイベントとして転送するもので、Integrations配下で別途接続します。

ステップ3: コンバージョンをPOSTする。 注文が発生したら、click_idと注文の詳細を添えてイベントを送信します。event_idが冪等性キーです。

curl -X POST \
  https://api.elido.app/v1/conversions \
  -H "Authorization: Bearer $ELIDO_TOKEN" \
  -d '{
    "click_id":   "clk_01HYZ7T8WV6KQX3M",
    "event_name": "purchase",
    "event_id":   "ord_98231",
    "value":      89.00,
    "currency":   "EUR",
    "user": {
      "email":  "[email protected]",
      "phone":  "+4915123456789",
      "external_id": "cust_5128"
    }
  }'

ユーザー識別情報のフィールドは、MetaとGA4に転送される前にSHA-256でハッシュ化されます。両プラットフォームともこれを要求しているためです。UTMのコンテキストはclick_idに一致するクリック行から取得されるため、ユーザーがチェックアウトするまでの1時間サイト内をうろついていたとしても、転送されるイベントには元のキャンペーンアトリビューションが乗ります。返金処理やマルチタッチアトリビューションモデルの切り替えを含む完全な仕組みは、コンバージョン転送ガイドにあります。

Elidoダッシュボードのコンバージョン計測ピクセル管理タブ。Meta Pixel ID、Google Ads / GA4 ID、LinkedIn Insight Tag、TikTok Pixel Codeの各フィールドがある

これでギャップの大部分が閉じます。残る穴はあります。click_idのCookieをブロックする訪問者や、Elido経由でない経路で到達する訪問者です。しかし、実際にトラフィックを流しているキャンペーンについては、「ピクセルの信頼性60〜80%」から「サーバーの信頼性95%以上」へと移行できています。

監査ログが救ってくれる3つのエッジケース

テンプレートと転送はハッピーパスを処理してくれます。以下のケースは、ある程度規模のあるキャンペーンの3週目には必ず現れ、これらすべてに対する正しい答えは、より凝ったテンプレートを設計しようとすることではなく、監査ログとコンバージョンパネルの中にあります。

このリストに含まれていない1つのケース、それはテンプレートでは解決できないものです。リファラーを一切持たず、あなたが設定した覚えのないキャンペーンパラメータを持って届くクリックです。それはAIアシスタントが送ってくるものであり、ChatGPTからのトラフィックの追跡がその対処法を扱っています。

返金。 購入コンバージョンが発火し、顧客が1週間後にその商品を返品し、報告されている売上が8%高くなってしまっている状態です。修正方法は、同じevent_idをevent_name: "refund"とともにPOSTすることです。MetaとGA4はこれを元のコンバージョンに対するマイナスのコンバージョンとして扱います。event_idがこの形になっている理由は、イベントID単位での冪等性によって返金の二重計上も防げるからです。完全なパターンはコンバージョン転送ガイドのエッジケースのセクションに記載されています。返金、一部返金、ストアクレジットはそれぞれ少しずつ形が異なります。

click_idの不一致。 既知のどのクリックにも一致しないclick_idとともにコンバージョンが発火することがあります。タイプミス、保持期間切れ、ワークスペースの取り違えなどです。コンバージョン自体はワークスペースに対して記録されますが、UTMのコンテキストは空のまま転送されます。これは意図的な挙動です。取りこぼしなくキャッチオールで帰属させる方が、コンバージョンを取り落とすよりも有用であり、監査ログのclick_id_unknownフラグによって、レポート作成時にアトリビューション不明な部分を絞り込んで確認できます。この割合がコンバージョン全体の5%を超えているなら、遷移先ページでclick_idを保持する方法に何か問題があります。たいていはCookieのSameSite属性かパスのスコープが原因です。

遅れて到着するコンバージョン。 B2BのSaaS案件が、元のクリックから47日後に成約することがあります。Elidoのデフォルトのクリック保持期間は30日なので、コンバージョンが発火する頃にはクリックはすでに期限切れになっており、上記のclick_id不一致のケースに該当してしまいます。対処法は営業サイクルに応じて2つあります。ワークスペースの保持期間を90日に延長する(Proプラン以上)か、顧客レコードの長期保存される識別子(original_click_id列)にclick_idを保存しておき、Cookieが消えていてもコンバージョン時にそれを結び直せるようにするかです。私たちは本番環境で両方のパターンを見てきました。

監査ログには、リンクごとの解決後と最終結果のUTM差分、コンバージョンごと・転送先ごとの転送レスポンスコード、そしてclick_idとコンバージョンの結合状態が表示されます。最適化アルゴリズムが不振に見えるキャンペーンから予算を引き上げようとしたとき、監査ログがあれば「いや、キャンペーン自体は問題なく、ローテーションされたGA4のapi_secretが更新されていなかったせいで3日分の転送を失っただけだ」と言えます。ぜひ見てください。

ローンチ前のQA、パイプライン全体をドライランする

このパイプラインを通過する最初のコンバージョンを、本物の買い物客にしないでください。30分のドライランのコストはすべてあなたが負担しますが、設定ミスのあるパイプラインのコストは、気づくまでの2日間、最適化アルゴリズムが最も成績の良いキャンペーンから予算を引き上げ続けるという形で負担することになります。この非対称性は良くありません。

順番に3つのステップがあります。

一括インポートのドライラン。 一括インポートのエンドポイントはクエリパラメータとしてdry_run=trueを受け付けます。検証を実行し、テンプレートを解決し、コミットすることなく作成されるはずのリンクを返します。レスポンスを任意のJSONビューアで開けば、すべての行の解決済みURLが見えます。2番目のリンク、最後のリンク、ワークスペースのデフォルトを上書きした行の3〜5行を抜き取って確認します。utm_*のクエリ文字列がキャンペーンブリーフに書かれているとおりかを検証します。

コンバージョン転送のテストモード。 Meta CAPIはtest_event_codeパラメータを受け付けており、これによりイベントは本番ではなくEvents Manager内のTest Eventsタブに送られます。ワークスペースの転送設定にそれを設定し、サンプルのコンバージョンを10〜20件送信し、届いたことを確認します。GA4も同じ考え方で、イベントにdebug_mode: trueを設定し、DebugViewで確認します。どちらもリアルタイムです。ここでの目的は単にAPIが動くことを確認することではなく、設定ミスのあるpixel_idや、ローテーションされたのに更新されていないapi_secretを検出することです。

エンドツーエンドのスモークテスト。 クリーンなブラウザセッションから、実際の短縮リンクの1つをクリックします。Elidoダッシュボードの最近のクリックパネルでそのクリックを確認します。何かを購入したふりをして、端末からそのclick_idを使ってpurchaseコンバージョンをPOSTします。そのコンバージョンが正しいUTMコンテキストとともにMetaのTest EventsとGA4のDebugViewに現れることを確認します。一度やり方を覚えれば、このループ全体は10分もかかりません。

3つすべてに合格したら、test_event_codeを外し、debug_modeをfalseに設定して、本番に出しましょう。最初の本物の買い物客を、クリーンなパイプラインが待ち構えている状態で迎えられます。

Elidoダッシュボードのコンバージョンパネル。合計コンバージョン数と売上、売上上位のリンク、過去30日間の日次売上チャート、プラットフォーム別の売上内訳を表示

実際にCDPが欲しくなるとき

テンプレートと一括インポートとサーバーサイド転送で、ほとんどのところまではたどり着けます。それでは足りない問題のクラスが存在し、そこではCDPに頼るのが正しい判断です。

クロスデバイスのアイデンティティ結合。 訪問者がモバイルでリンクをクリックし、コンバージョンには至らず、後でデスクトップに戻ってきてサインアップします。両方のタッチを同一人物に帰属させたいところです。UTM追跡とclick_idはタッチ単位のものであり、2つのタッチを1つのジャーニーにまとめるユーザーアイデンティティのレイヤーこそがCDP(Segment、mParticle、RudderStack)の設計目的です。Elidoは訪問者ごとに最大30日分のクリックを保存し、その期間内でラストタッチ、ファーストタッチ、ポジションベースのアトリビューションをサポートしますが、クロスデバイスの結合には、私たちが意図的に運用していないアイデンティティグラフが必要です。

100ミリ秒未満のパーソナライゼーション。 訪問者の過去のタッチに基づいて遷移先ページをリアルタイムでレンダリングする、たとえばフィーチャーストアからコホートを取得してヒーローの見出しを変えるといったことをしたい場合、レンダリングに近い場所でアイデンティティ解決が必要です。それはCDPの領域か、あるいはより多くの場合、PostHogやLaunchDarklyのような実験プラットフォームをその上に重ねる領域です。

大規模なマルチタッチアトリビューション。 ほとんどのキャンペーンにはラストタッチで十分です。もし営業サイクルが4か月にわたって6回のタッチを経るもので、それぞれに本気でクレジットを配分する必要があるなら、マルコフ連鎖やシャープレイ値によるアトリビューションが意味を持ち始める領域に入っています。Elidoが提供するのはラストタッチ、ファーストタッチ、ポジションベースのアトリビューションです。それ以上に高度なものが必要なら、適切なアイデンティティグラフとモデルレイヤーを備えたツールが必要です。

それ以外のすべて、つまり私がこれまで一緒に仕事をしてきたマーケティングチームの大半にとっての「それ以外のすべて」については、テンプレート、一括インポート、サーバーサイド転送のパターンで十分です。ワークスペーステンプレートを一度設定し、ローンチごとにキャンペーンテンプレートを設定し、プラットフォーム連携ごとに一度転送設定を行い、すべてのローンチの前にドライランを実行してください。この4つをすべて行えば、私が監査してきたマーケティングチームの80%よりも引き締まったUTMパイプラインを手にすることになります。

一度構築したら、ローンチのたびにドライランし、次のキャンペーンに進みましょう。

ブログの関連記事

Elidoを試す

URLを貼り付けて短縮リンクを取得

登録不要。リンクは30日間有効。永久に保存するには登録してください。

Free、登録不要 · 1日あたり2件

Elidoを試す

EUホスティングのURL短縮サービス。カスタムドメイン、詳細な分析、オープンAPI付き。無料プラン - クレジットカード不要。

タグ
utm tracking
utm template
utm builder
utm attribution
conversion forwarding
ga4
meta capi

続きを読む