Microsoft広告(Bing)のレポート自動化|Reporting APIの使い方

広告分析
読了時間 約19分
Microsoft広告(Bing)にはGoogleやMetaのような無料の公式コネクタ・転送サービスが無く、日本語の情報もほとんどありません。管理画面でのレポート出力やETLツール経由の方法に加え、本命のReporting API直連携について、開発者トークンの取得からAzure Portalでのアプリ登録、OAuth認証、非同期レポート取得のPython実装までを2026年8月時点の公式ドキュメントに基づいて解説します。ダウンロードURLの5分間有効期限など、つまずきやすい落とし穴も押さえます。

Microsoft広告(Bing)のレポート自動化を調べようとすると、まず日本語の情報がほとんど出てこないことに気づきます。Google広告やMeta広告なら手順を解説する記事がいくらでも見つかるのに、Bing広告は公式ドキュメント(英語)を自分で読み解くしかない。しかも仕組みを見ると、GoogleやMetaにあった「無料の公式コネクタ」や「無料の公式データ転送」がMicrosoft広告には存在せず、自動化しようとするといきなりAPI連携の話になります。

そこで、公式ドキュメント(learn.microsoft.com/en-us/advertising/配下)を実際に確認しながら、管理画面での手動出力からReporting API直連携までを順に見ていきます。


どのやり方で自動化するか

先に結論です。Microsoft広告のレポート取得手段は大きく3つあります。

管理画面のレポート出力
  • 難易度: ★☆☆(画面操作のみ)
  • 出力先: ダウンロードファイル
  • 費用: 無料
  • 弱点: 加工・蓄積ができない
ETLツール/コネクタ
  • 難易度: ★★☆(設定のみ・実装不要)
  • 出力先: BigQuery / BI
  • 費用: ツール利用料が発生
  • 弱点: 月額コスト
Reporting API 直連携
  • 難易度: ★★★(開発者トークン+Azure登録+実装)
  • 出力先: 自由(DB/BI/BigQuery)
  • 費用: API自体は無料
  • 弱点: SOAP・非同期ポーリングの実装が要る
Microsoft広告(Bing)レポート自動化の3つのやり方。GoogleやMetaと違い無料の公式コネクタ・転送は無く、実装するならReporting API直連携が本命
  • 手作業でたまにダウンロードできれば十分 → やり方1(管理画面のレポート出力)
  • 実装せずBigQueryやBIに流したい → やり方2(ETLツール/コネクタ)
  • 自社システムへの組み込み、他媒体との統合、無料での完結を狙う → やり方3(Reporting API直連携)

GoogleにあったBigQuery Data Transferのような無料の公式転送や、Google Adsスクリプトのようなコード不要の中間手段はMicrosoft広告には無いため、蓄積・分析まで見据えるなら実質的にやり方3一択になります。以下、やり方3を中心に手順を追っていきます。

やり方1: 管理画面からレポートをダウンロードする

Microsoft Advertisingの管理画面(ads.microsoft.com)には「レポート」機能があり、キャンペーン別・日別といった粒度でレポートを作成し、CSVやExcel形式でダウンロードできます。特別な申請も実装も不要で、今すぐ使えるのがメリットです。

弱点は、これが基本的に手作業だという点です。毎回画面を開いてレポートを作成しダウンロードする必要があり、他システムへの自動連携や、スプレッドシート・BigQueryへの自動蓄積はできません。「月に一度、数字を確認できればいい」程度の用途に留まります。

やり方2: ETLツール・コネクタでBigQueryやBIに流す

実装せずにBigQueryやBIツールにデータを流したい場合は、ETLツールやパートナーコネクタを使う選択肢があります。FivetranやAirbyteといったETLツールにはMicrosoft Advertising(旧Bing Ads)向けのコネクタが用意されており、認証情報を設定するだけでBigQueryなどへの定期取り込みが組めます。

自前でAzure ADのアプリ登録やOAuthの実装をせずに済むのが最大のメリットですが、ツール側の月額利用料がかかります。複数の自動化ツールの料金や対応媒体の比較は広告レポート自動化ツール比較|主要9ツールの料金・対応媒体・選び方にまとめています。

やり方3: Reporting APIで自由に取得する

無料で完結し、自由度も最大のやり方です。ただし、GoogleのAds APIやMetaのMarketing APIと比べても段取りが多く、Azure AD(Entra ID)へのアプリ登録という他媒体には無いステップが挟まります。順を追って説明します。

前提条件として、手順3以降で使うAzure Portalへのサインインには**職場または学校のアカウント(Microsoft Entra IDテナントのアカウント)**が必要です。個人のMicrosoftアカウント(outlook.com等)だけでMicrosoft広告を運用している場合は、先にAzureの無料アカウントを作成してください。作成すると自分用のEntra IDテナントが自動的に用意され、そのアカウントで後述のApp registrations(アプリ登録)が使えるようになります。

手順1: 広告アカウントを用意する

まだ広告アカウントを持っていない場合は、ads.microsoft.com(Microsoft Advertising管理画面)でアカウントを作成します。検証用にはSandbox環境(sandbox.bingads.microsoft.com)も用意されていますが、本番用とSandbox用はアカウント・クレデンシャルとも完全に別物です。開発中はSandboxで動作確認し、本番移行時に改めて本番用のトークン・認証情報を用意する前提で進めてください。

手順2: 開発者トークンを取得する

APIを呼び出すには、OAuthのアクセストークンとは別に「開発者トークン(Developer Token)」が必要です。以下の手順で取得します。

  1. ブラウザで https://ads.microsoft.com/cc/Settings/DevSettings を開きます(2025年5月31日以降、旧Developer Portalの https://developers.ads.microsoft.com/Account は廃止され、このURLに統合されています)。
  2. Super Admin(スーパー管理者)権限を持つユーザーでサインインします。自分の権限が分からない場合は、Microsoft Advertising管理画面のユーザー管理(アカウントアクセス)画面で、自分のユーザーの役割が「スーパー管理者(Super Admin)」になっているかを確認してください(※画面の表記・導線はバージョンによって異なる場合があります)。Super Adminでない場合は、社内のSuper Admin権限保持者にトークン発行を依頼する必要があります。
  3. 開発者トークンを関連付けたいユーザーを一覧から選択します。現在のデフォルトは1つのトークンで全ユーザーの認証に使えるUniversal Developer Tokenなので、アプリを複数人で使う場合でもトークンは1つで足ります。
  4. Request Token」ボタンをクリックします。
  5. 画面にトークン文字列が表示されたら発行完了です。この値をコピーして控えます(後述のPythonコードで DEVELOPER_TOKEN に入れる値です)。公式ドキュメント上、発行は即時で、審査待ちがあるという記載はありません。

なお、既存ユーザーに旧式のSingle Userトークンが割り当てられていた場合は、「Upgrade to Universal」を選択してUniversalトークンに切り替えられます。

Sandbox環境用には誰でも使える共通のトークン(BBD37VB98)が用意されており、本番トークンを取得する前の動作確認に使えます。

手順3: Azure Portalでアプリを登録する

OAuth認証にはAzure AD(Microsoft Entra ID)へのアプリ登録が必要です。ここで発行される「クライアントID」が、認可URLやトークン取得リクエストで使う client_id になります。

  1. ブラウザで https://go.microsoft.com/fwlink/?linkid=2083908 を開きます。Azure Portalの「App registrations(アプリの登録)」ページに直接遷移します。https://portal.azure.com を開き、画面上部の検索バーに「App registrations」と入力して開いても同じ場所に着きます。
  2. Work/School Account(職場または学校のアカウント)でサインインします。個人のMicrosoftアカウント(outlook.com等)ではこのポータルにログインできません(公式ドキュメントに「You can no longer log in using a personal Microsoft account」と明記されています)。職場/学校アカウントを持っていない場合は、本節冒頭の前提条件の通り、先にAzure無料アカウントを作成してください。
  3. ページ左上の「+ New registration(新規登録)」をクリックします。
  4. 「Register an application(アプリケーションの登録)」画面で、次の通り入力します。
    • Name(名前)」: 任意のアプリ名を入力します。例: evast-msads-report のように「社名-msads-report」形式にしておくと後から判別しやすいです。
    • Supported account types(サポートされているアカウントの種類)」: 選択肢のうち「Any Entra ID Tenant + Personal Microsoft accounts」(日本語UIでは「任意の組織ディレクトリ内のアカウント(任意のMicrosoft Entra IDテナント - マルチテナント)と個人のMicrosoftアカウント(Skype、Xboxなど)」)を選択します。Microsoft広告に個人アカウント(MSA)でログインしているユーザーも認証できるようにするため、ここは必ずこの選択肢にしてください。
    • 「Redirect URI」欄はこの時点では空欄のままで構いません(次の手順4で設定します)。
  5. 画面下部の「Register(登録)」ボタンをクリックします。
  6. 登録したアプリの「Overview(概要)」ページが自動で表示されたら登録完了です。

手順4: クライアントIDとリダイレクトURI、シークレットを設定する

続けて、同じアプリの画面で3つの設定を行います。サーバー上で定期実行するバッチを想定し、本記事ではWebアプリ+クライアントシークレットの構成で統一します(この構成なら、取得したリフレッシュトークンを取得時と別のマシンでも使い回せます)。

(1) クライアントIDを控える

  1. アプリの「Overview(概要)」ページ上部の「Essentials」欄にある「Application (client) ID(アプリケーション(クライアント)ID)」の値(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 形式のGUID)をコピーして控えます。これが client_id です。すぐ下の「Directory (tenant) ID」とは別物なので注意してください。

(2) リダイレクトURIを設定する

  1. 同じ「Overview」ページのEssentials欄にある「Add a Redirect URI(リダイレクトURIの追加)」リンクをクリックします(左メニュー「Manage(管理)」配下の「Authentication(認証)」を開いても同じ画面です)。
  2. + Add a platform(プラットフォームを追加)」をクリックし、右側に出るパネルで「Web」を選択します。
  3. 「Redirect URIs」の入力欄に http://localhost/myapp/ と入力し、パネル下部の「Configure(構成)」をクリックします。ローカルにWebサーバーを立てる必要はありません。認可後にこのURLへリダイレクトされ、ページ自体はエラー表示になりますが、アドレスバーのURLに認可コードが付くのでそれをコピーして使います(手順5で後述)。
  4. 「Web」プラットフォームの「Redirect URIs」一覧に http://localhost/myapp/ が表示されていれば設定完了です。

(3) クライアントシークレットを作成する

  1. 左メニュー「Manage(管理)」配下の「Certificates & secrets(証明書とシークレット)」をクリックします。
  2. Client secrets(クライアントシークレット)」タブが選ばれた状態で、「+ New client secret(新しいクライアントシークレット)」ボタンをクリックします。
  3. 右側に出るパネルで「Description(説明)」に用途が分かる名前(例: msads-report-secret)を入力し、「Expires(有効期限)」を選択して(最長でも2年程度までしか選べないため、期限切れ前の再作成をカレンダーに登録しておくのがおすすめです)、「Add(追加)」をクリックします。
  4. 一覧に追加された行の「Value(値)」列の文字列を、この画面にいるうちに必ずコピーして保存します。ページを離れると二度と表示されず、再作成が必要になります。これが client_secret です。隣の「Secret ID」列はシークレットの管理用IDであって client_secret ではないので、取り違えないよう注意してください。

なお、パブリック(ネイティブ)クライアントとして使う場合はシークレット作成は不要で、(2)のプラットフォーム選択で「Mobile and desktop applications」を選び、「Suggested Redirect URIs for public clients (mobile, desktop)」内の https://login.microsoftonline.com/common/oauth2/nativeclient にチェックを入れます。ただしこの構成ではリフレッシュトークンが取得したデバイスに紐づき、別マシンで使い回せません。また、nativeclientのリダイレクトURIと client_secret を併用すると「Public clients can’t send a client secret.」といった趣旨のエラーになります。

手順5: OAuth認可コードを取得し、トークンに交換する

(1) 認可URLをブラウザで開く

以下のURLの YOUR_CLIENT_ID の部分だけを手順4-(1)で控えたクライアントIDに置き換え、ブラウザのアドレスバーに貼り付けて開きます(1行のままコピーしてください。%3A などはURLエンコード済みの値なのでそのまま使います)。

https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&response_mode=query&scope=openid%20offline_access%20https%3A%2F%2Fads.microsoft.com%2Fmsads.manage&state=12345

パラメータの意味: scopeの https://ads.microsoft.com/msads.manage がMicrosoft Advertisingの操作権限、offline_access がリフレッシュトークンの取得に必須です。redirect_uri は手順4-(2)で登録した値とURLエンコード済みで完全一致している必要があります(登録URIを変えた場合はここも変えます)。

(2) サインインして同意する

  1. 広告アカウントの管理者権限を持つユーザーでサインインします。同じメールアドレスでMSA(個人)とAzure AD(職場)双方の資格情報を持つ場合、「職場または学校アカウント」か「個人のアカウント」かを選択する画面が出ることがあります。Microsoft広告にログインしている方を選んでください。
  2. 「(アプリ名)がお客様のMicrosoft Advertisingアカウントの管理を求めています」といった同意画面が表示されたら、「承諾(Accept)」をクリックします。なお、組織のテナント設定でユーザーによる同意が無効化されている場合、同意画面の代わりに「管理者の承認が必要です(Need admin approval)」と表示されて先に進めないことがあります。その場合はテナント管理者(Entra ID管理者)に同意の付与を依頼してください。
  3. ブラウザが http://localhost/myapp/?code=M.C105_BAY...&state=12345 のようなURLにリダイレクトされます。ページ自体は「このサイトにアクセスできません」等のエラー表示になりますが、それで正常です。アドレスバーのURLのうち、code= の後ろから &state の手前までの文字列(認可コード)をコピーします。
  4. 認可コードの有効期限は約5分です。すぐに次のトークン交換へ進んでください。もしURLに error=access_denied が付いて戻ってきた場合は、同意画面で拒否したか権限が不足しています。

(3) 認可コードをトークンに交換する

ターミナルで以下のcurlコマンドを実行します(YOUR_CLIENT_IDYOUR_CLIENT_SECRET・認可コードの3か所を自分の値に置き換えてください)。なお、バックスラッシュ(\)による行継続はmacOS/Linux(またはWSL・Git Bash)のシェル前提の書き方です。PowerShellやコマンドプロンプトで実行する場合は、\を外して1行にまとめて実行してください。

curl -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "client_id=YOUR_CLIENT_ID" \
  --data-urlencode "client_secret=YOUR_CLIENT_SECRET" \
  --data-urlencode "code=ここに(2)でコピーした認可コードを貼り付け" \
  --data-urlencode "redirect_uri=http://localhost/myapp/" \
  --data-urlencode "scope=https://ads.microsoft.com/msads.manage offline_access"

成功すると、次のようなJSONが返ります。

{
  "token_type": "Bearer",
  "scope": "https://ads.microsoft.com/msads.manage",
  "expires_in": 3599,
  "access_token": "EwB4A8l6BAAU...",
  "refresh_token": "M.C105_BAY.-CS..."
}

この refresh_token の値を環境変数やシークレット管理サービスなど安全な場所に保存してください。以降の自動実行では、このリフレッシュトークンさえあればユーザーの再ログインなしでアクセストークンを取得し続けられます。invalid_grant エラーが返る場合は認可コードの期限切れ(約5分)が典型なので、(1)からやり直してください。

(4) アクセストークンの更新

アクセストークンは約1時間(expires_in=3599秒)で失効します。失効後は以下のように grant_type=refresh_token で更新します(後述のPython SDKを使う場合、この更新はSDKが自動で行うため手作業は不要です)。

curl -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=refresh_token" \
  --data-urlencode "client_id=YOUR_CLIENT_ID" \
  --data-urlencode "client_secret=YOUR_CLIENT_SECRET" \
  --data-urlencode "refresh_token=保存したリフレッシュトークン" \
  --data-urlencode "scope=https://ads.microsoft.com/msads.manage offline_access"

リフレッシュトークン自体の失効タイミングは保証されていません(公式ドキュメントに「いつでも無効化されうる」と明記。Microsoft identity platform共通の仕様としてはパブリッククライアントで概ね90日が目安とされ、パスワード変更やアプリ権限の削除でも失効します)。失効すると {"error":"invalid_grant", ...} が返るため、その場合は(1)からやり直して新しいリフレッシュトークンを取得するエラーハンドリングを組み込んでおいてください。

手順6: CustomerIdとCustomerAccountIdを取得する

API呼び出し時のSOAPヘッダに指定するCustomerId(顧客ID)とCustomerAccountId(アカウントID)を調べます。管理画面のURLから読み取るのが最も簡単です。

  1. ブラウザで https://ads.microsoft.com を開き、サインインします。
  2. 左サイドバーの「キャンペーン(Campaigns)」をクリックします。
  3. ブラウザのアドレスバーのURLを確認します。https://ui.ads.microsoft.com/campaign/Campaigns.m?cid=123456789&aid=987654321#/... のような形式になっており、cid= の後ろの数字がCustomerIdaid= の後ろの数字が**AccountId(=CustomerAccountId)**です。両方をコピーして控えます。

注意: 管理画面のアカウント名の近くに表示される「アカウント番号」(X1234567 のような8桁の英数字)は、APIで使うAccountIdとは別物です。APIリクエストには必ずURLの aid= で確認した数値のAccountIdを使ってください。

プログラムから取得したい場合は、Customer Management ServiceのGetUser操作(リクエストのUserIdをnilにして呼ぶと自分のUserIdが返る)→SearchAccounts操作(そのUserIdを条件に検索)の順に呼び出すと、アクセス可能な全アカウントのAccountId・CustomerIdの一覧が取得できます。

手順7: Reporting APIでレポートをリクエストする

ここまでで、以下の6つの値が揃っているはずです。1つでも欠けていたら該当の手順に戻ってください。

取得した手順
開発者トークン手順2
クライアントID手順4-(1)
クライアントシークレット手順4-(3)
リフレッシュトークン手順5-(3)
CustomerId手順6(URLのcid=)
AccountId手順6(URLのaid=)

これらを使ってレポートを取得します。Reporting Service(SOAPベース)は非同期のリクエスト/ポーリング方式で、生のSOAPを叩く場合の流れは次の通りです。

  1. SubmitGenerateReport操作を呼び出し、CampaignPerformanceReportRequestなどのレポートリクエストを送信すると、ReportRequestIdが返る
  2. PollGenerateReport操作を、レスポンスのstatusPendingの間ループで呼び出す。多くのレポートは数分で完了するため、2〜15分間隔でのポーリングが目安(ポーリングの総時間が60分を超える場合は、ReportRequestIdを保存していったん処理を抜け、後で再開するのが推奨されている)
  3. statusSuccessになったら、レスポンスのReportDownloadUrlからファイルを取得する
  4. ファイルはZIP圧縮されているため解凍する。フォーマットはCsv(デフォルト)/Tsv/Xmlから選べる

.NET/Java/PythonのSDKを使うと、この一連の流れ(Submit→Poll→ダウンロード→解凍)をReportingServiceManagerが抽象化してくれます。ここではPython SDK(bingadsパッケージ)で、コピペでそのまま動く形まで作ります。

(1) Python環境を準備する

ターミナルで以下を順に実行します(Python 3がインストール済みである前提です)。

# 作業用ディレクトリを作成して移動
mkdir msads-report && cd msads-report

# 仮想環境を作成して有効化(Windowsの場合は .venv\Scripts\activate)
python3 -m venv .venv
source .venv/bin/activate

# Microsoft Advertising公式のPython SDKをインストール(本記事はv13系で検証)
pip install "bingads>=13.0,<14"

pip show bingads を実行してバージョン情報が表示されればインストール成功です。

(2) スクリプトを作成する

以下の内容を msads_report.py という名前で保存します。冒頭の「ここから自分の値に書き換える」ブロックの7つの定数を、ここまでの手順で控えた値に書き換えれば、それ以外の変更は不要です。

"""Microsoft広告のキャンペーン日次レポート(直近30日)をCSVでダウンロードするスクリプト。

実行方法:
    python msads_report.py

成功すると、カレントディレクトリに campaign_report.csv が生成されます。
"""

import sys

from bingads.authorization import AuthorizationData, OAuthWebAuthCodeGrant
from bingads.service_client import ServiceClient
from bingads.v13.reporting import ReportingDownloadParameters, ReportingServiceManager

# ==== ここから自分の値に書き換える ====
CLIENT_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"  # 手順4-(1) Application (client) ID
CLIENT_SECRET = "xxxxxxxxxxxxxxxxxxxx"              # 手順4-(3) クライアントシークレットの「Value」
REDIRECT_URI = "http://localhost/myapp/"            # 手順4-(2) で登録したリダイレクトURI
REFRESH_TOKEN = "M.C105_BAY.-CS..."                 # 手順5-(3) で保存したリフレッシュトークン
DEVELOPER_TOKEN = "xxxxxxxxx"                       # 手順2 の開発者トークン
CUSTOMER_ID = 123456789                             # 手順6 のURLの cid= の値(数値のみ・クォート不要)
ACCOUNT_ID = 987654321                              # 手順6 のURLの aid= の値(数値のみ・クォート不要)
# ==== ここまで ====

# Sandbox環境で試す場合は "sandbox" に変更(トークン類もSandbox用が必要)
ENVIRONMENT = "production"


def save_refresh_token(oauth_tokens):
    """トークン更新時にSDKから呼ばれる。新しいリフレッシュトークンを保存する。"""
    # 実運用ではファイルやシークレット管理サービスに上書き保存し、次回実行時はそちらを使う
    print("新しいリフレッシュトークン(次回はこちらを使用):", oauth_tokens.refresh_token)


def build_authorization_data():
    """OAuth認証を行い、SOAPヘッダ相当の認証情報一式を組み立てる。"""
    authentication = OAuthWebAuthCodeGrant(
        client_id=CLIENT_ID,
        client_secret=CLIENT_SECRET,
        redirection_uri=REDIRECT_URI,
        env=ENVIRONMENT,
    )
    authentication.token_refreshed_callback = save_refresh_token

    # リフレッシュトークンからアクセストークンを取得する。
    # 以降のAPI呼び出し中の期限切れ(約1時間)はSDKが自動で更新してくれる。
    authentication.request_oauth_tokens_by_refresh_token(REFRESH_TOKEN)

    return AuthorizationData(
        account_id=ACCOUNT_ID,
        customer_id=CUSTOMER_ID,
        developer_token=DEVELOPER_TOKEN,
        authentication=authentication,
    )


def build_report_request(reporting_service):
    """キャンペーン別・日別のパフォーマンスレポート定義を組み立てる。"""
    report_request = reporting_service.factory.create("CampaignPerformanceReportRequest")
    report_request.Format = "Csv"          # Csv / Tsv / Xml から選択
    report_request.FormatVersion = "2.0"   # 公式推奨のフォーマットバージョン(未指定だと旧1.0になる)
    report_request.ReportName = "daily campaign report"
    report_request.ReturnOnlyCompleteData = False  # 確定済みデータのみ必要なら True
    report_request.Aggregation = "Daily"   # 日別集計
    report_request.ExcludeReportHeader = True   # CSV冒頭のメタ情報行を除外(後続処理しやすくする)
    report_request.ExcludeReportFooter = True   # 末尾の著作権行を除外
    report_request.ExcludeColumnHeaders = False # 列名行は残す

    # 対象アカウント
    scope = reporting_service.factory.create("AccountThroughCampaignReportScope")
    scope.AccountIds = {"long": [ACCOUNT_ID]}
    scope.Campaigns = None
    report_request.Scope = scope

    # 対象期間。日付を指定したい場合はPredefinedTimeの代わりに
    # CustomDateRangeStart/CustomDateRangeEnd を設定する
    report_time = reporting_service.factory.create("ReportTime")
    report_time.PredefinedTime = "Last30Days"
    # 未指定だと米国太平洋時間で集計されるため、日本時間を明示する
    report_time.ReportTimeZone = "OsakaSapporoTokyo"
    report_request.Time = report_time

    # 取得する列
    columns = reporting_service.factory.create("ArrayOfCampaignPerformanceReportColumn")
    columns.CampaignPerformanceReportColumn.append(
        ["TimePeriod", "CampaignName", "Impressions", "Clicks", "Spend", "Conversions"]
    )
    report_request.Columns = columns

    return report_request


def main():
    authorization_data = build_authorization_data()

    # SubmitGenerateReport→PollGenerateReport→ダウンロード→解凍を肩代わりするマネージャ
    reporting_service_manager = ReportingServiceManager(
        authorization_data=authorization_data,
        poll_interval_in_milliseconds=5000,  # 5秒間隔でPollGenerateReportを呼ぶ
        environment=ENVIRONMENT,
    )

    # レポート定義オブジェクトを生成するためのSOAPクライアント
    reporting_service = ServiceClient(
        service="ReportingService",
        version=13,
        authorization_data=authorization_data,
        environment=ENVIRONMENT,
    )

    report_request = build_report_request(reporting_service)

    download_parameters = ReportingDownloadParameters(
        report_request=report_request,
        result_file_directory=".",               # 保存先ディレクトリ
        result_file_name="campaign_report.csv",  # 保存ファイル名
        overwrite_result_file=True,              # 既存ファイルを上書き
        timeout_in_milliseconds=3_600_000,       # 60分でタイムアウト
    )

    result_file_path = reporting_service_manager.download_file(download_parameters)

    if result_file_path is None:
        # 指定期間にデータが1行も無い場合などはNoneが返る
        print("レポートデータがありませんでした。期間・アカウントIDを確認してください。")
        return

    print(f"ダウンロード完了: {result_file_path}")


if __name__ == "__main__":
    try:
        main()
    except Exception as ex:
        # invalid_grant(リフレッシュトークン失効)→ 手順5-(1)からやり直し
        # Invalid client data(105)→ 開発者トークン・アクセストークンの環境不一致を確認
        # Customer/Account系エラー → 手順6のcid/aidの値を確認
        print(f"エラーが発生しました: {ex}", file=sys.stderr)
        sys.exit(1)

(3) 実行して結果を確認する

python msads_report.py

「ダウンロード完了: ./campaign_report.csv」と表示され、カレントディレクトリに campaign_report.csv が生成されていれば成功です。中身は1行目が列名(TimePeriod,CampaignName,Impressions,Clicks,Spend,Conversions)、2行目以降が日別×キャンペーン別の実績になっています。

ReportingServiceManagerがSubmitGenerateReport/PollGenerateReportのポーリングとZIP解凍を内部で肩代わりしてくれるため、自前でポーリングループを書く必要はありません。あとはこのスクリプトをcron等で毎朝実行し、取得したCSVをBigQueryやスプレッドシートに読み込ませれば、日次のレポートパイプラインが完成します。

ただし定期実行に載せる前に1点だけ改修が必要です。リフレッシュトークンはSDKによる更新時にローテーション(新しい値への差し替え)されることがあるため、定数REFRESH_TOKENのままだとローテーション後の実行でinvalid_grantになり得ます。実運用ではsave_refresh_token内でファイルやシークレット管理サービスに新しいトークンを上書き保存し、次回実行時はそこから読み込む実装に差し替えてください。

料金・制限まとめ

項目内容
開発者トークン取得費用公式ドキュメント上、課金の記載なし
API利用料公式ドキュメント上、課金の記載なし(広告費以外の追加コスト明記なし)
ReportRequestIdの有効期限公式内で記載が分かれる(ガイド: 2日間 / APIリファレンス: 最大1日)。安全側の1日を目安に
ReportDownloadUrlの有効期限PollGenerateReport応答取得後5分間
SubmitGenerateReportの呼び出し上限非公開(具体的な数値の記載なし・随時変更されうる)
レポート形式Csv(デフォルト)/Tsv/Xml

料金・レート制限とも専用の公開ページが見当たらず、「明記が無い=無料/無制限」と決めつけるのは早計です。本番運用では上限に達した場合のエラーハンドリング(リトライ・間隔調整)を必ず組み込んでください。

実務でハマる落とし穴5つ

Reporting APIを実際に触ると、公式ドキュメントを読んだだけでは気づきにくいポイントがいくつかあります。

1. ダウンロードURLが5分しか有効でないReportRequestId自体の有効期限は公式ドキュメント内でも記載が分かれています(ガイドでは2日間、APIリファレンスでは最大1日。安全側の1日を目安にしてください)が、ダウンロード用のReportDownloadUrlはPollGenerateReportの応答を受け取ってからわずか5分で失効します。バッチ処理を設計する際は、URL取得後すぐにダウンロードする、あるいは失効時は再Pollしてやり直す前提で組む必要があります。

2. MFA対応で認証方式が変わっている。2022年6月以降、多要素認証(MFA)対応のためmsads.manageスコープ+Microsoft identity platform(v2.0)エンドポイントの利用が必須になりました。旧形式(16進数のClient ID)で登録した古いアプリはそのままでは動かず、AADSTS700016(アプリケーションがディレクトリに見つからない)エラーになるため、Azure Portalで新規登録し直す必要があります。数年前の情報を参考にしていると、この点でつまずきやすいです。

3. データが確定するまでタイムラグがある(Books Closed)。クリック発生から最大2時間、コンバージョンは最大3時間はレポートにデータが反映されません。さらに不正クリックの調整などで、1週間以上経ってから数値が変わることもあります。直近データを確定値として扱いたい場合は、レポートリクエストのReturnOnlyCompleteDatatrueに設定します(falseのままだと未確定データが混じります)。

4. 本番とSandboxは別世界。開発・検証はSandbox環境(共通の開発者トークンBBD37VB98が使えます)で進められますが、アカウントもクレデンシャルも本番とは別物です。Sandboxで動いたコードをそのまま本番URLに向けるだけでは動かず、本番用のアカウント・トークン・認証情報を別途揃える必要があります。

5. レート制限が非公開。SubmitGenerateReportの呼び出し回数には上限がありますが、具体的な数値は公開されておらず、Microsoft側の都合で変わる可能性があります。上限に達すると「You have already reached the maximum number of concurrent report requests.」というエラーになるため、同時に大量のレポートをリクエストしない設計にしておくのが無難です。

どこまで自分でやるか:内製の限界ライン

Microsoft広告1媒体だけの自動化であれば、やり方3までの内製は十分可能です。ただし、Azure ADへのアプリ登録・OAuthのv2.0対応・SOAPの非同期ポーリングと、1媒体でもGoogle広告やMeta広告より実装量は明らかに多くなります。

内製が重くなるのは、Google・Meta・Microsoftと媒体が増えたときです。媒体ごとに認証方式もAPIの形式(GAQL/REST/SOAP)もバラバラで、仕様変更のたびに個別対応が必要になります。Google広告の自動化手順はGoogle広告レポート自動化のやり方|API・BigQuery連携からAI分析まで、Meta広告はMeta広告(Facebook)レポート自動化のやり方|APIからAI分析までで解説しています。外注した場合の費用相場は広告レポート自動化の費用は?ツール・代行の料金相場と選び方、蓄積先となるBigQueryのコスト最適化はBigQueryの料金体系とコスト削減|課金トラップと対策にまとめています。

私たちが提供しているアドヨミAIは、こうした媒体ごとのAPI連携をまとめて肩代わりするサービスです。Google・Meta・Microsoft広告などのデータをAPIで自動連携して自社所有のBigQueryに集め、前処理からAI分析・異常検知まで載せて、初期5万円・月1.5万円〜(媒体数に応じた累進料金)で運用できます。この記事のやり方3を、複数媒体分まとめて外注すると考えていただくと位置づけが近いです。

まとめ:情報が少ないぶん、公式ドキュメントを一次情報にする

  • Microsoft広告には無料の公式コネクタや転送サービスが無く、蓄積・分析まで見据えるなら実質Reporting API直連携が本命
  • 開発者トークンはDeveloper Portalの「Request Token」で発行。加えてAzure Portalでのアプリ登録という他媒体には無いステップが必要
  • 2022年6月以降のMFA対応で、msads.manageスコープ+v2.0エンドポイントの利用が必須。旧形式のアプリは再登録が要る
  • レポート取得はSubmitGenerateReport→PollGenerateReportの非同期方式。ダウンロードURLは5分しか有効でない
  • 料金・レート制限とも公式には数値の記載が無く、「明記が無い=保証されている」わけではない点に注意
  • 日本語の一次情報が少ない領域だからこそ、公式ドキュメント(learn.microsoft.com)を直接確認する姿勢が重要

Sandbox環境の共通開発者トークンを使えば、今日のうちに動作確認まで進められます。まずはSubmitGenerateReportを1回呼んでみてください。


複数媒体の広告レポート自動化はEvastへ

株式会社EvastのアドヨミAIは、Google・Meta・Microsoft広告など主要媒体の広告データをAPIで自動連携し、自社所有のBigQueryに集約する半スクラッチ型の広告レポート自動化・AI分析サービスです。

  • 「Microsoft広告(Bing)のAPI連携だけ手が付けられずにいる」
  • 「媒体ごとに違う認証方式・仕様変更への対応を社内で持ち続けたくない」
  • 「レポートだけでなく、AIでの分析や異常検知まで載せたい」

現状の運用の棚卸しからで構いません。1媒体・最短2週間から始められます。

アドヨミAIの詳細・料金を見る無料相談を申し込む

よくある質問

Microsoft広告(Bing)のレポート自動化に費用はかかりますか?
Reporting APIの利用や開発者トークンの取得そのものに課金があるという記載は、公式ドキュメント上には見当たりません。広告アカウント運用にかかる広告費以外の追加コストは明記されていない、というのが2026年8月時点の状況です。ただし専用の価格ページは確認できておらず、契約形態によって扱いが異なる可能性は残ります。ETLツールやコネクタ経由でBigQueryなどに流す場合は、ツール側の月額利用料が別途かかります。
開発者トークンはどうやって取得しますか?
Microsoft Advertising Developer PortalのAccountタブ(2025年5月31日以降はads.microsoft.com/cc/Settings/DevSettingsに統合)で、Super Admin権限を持つユーザーが対象ユーザーを選び「Request Token」ボタンを押すと発行されます。現在は1つのトークンで全ユーザーに対応するUniversal Developer Tokenがデフォルトです。公式ドキュメントには即時発行としか書かれておらず、審査に数日かかるという情報は非公式の二次情報源によるもので、公式には明記されていません。
OAuth認証で特に気をつけることはありますか?
2022年6月以降、多要素認証(MFA)対応のためmsads.manageスコープとMicrosoft identity platform (v2.0)エンドポイントの利用が必須になりました。旧形式(16進数のClient ID)で登録した古いアプリはそのままでは使えず、AADSTS700016(アプリケーションがディレクトリに見つからない)というエラーになるため、Azure Portalの「App registrations」で再登録が必要です。認可URLのscopeにはhttps://ads.microsoft.com/msads.manageとoffline_accessを指定してください。
レポートのダウンロードURLはどれくらいの期間有効ですか?
SubmitGenerateReportで発行されるReportRequestIdの有効期限は、公式ドキュメント内でも記載が分かれており、ガイドでは2日間、APIリファレンスでは最大1日とされています。安全側を取って1日以内に処理する設計にしてください。一方、PollGenerateReportで取得できるReportDownloadUrlは、Poll応答を受け取ってからわずか5分しか有効ではありません。失効した場合は再度PollGenerateReportを呼んでURLを取り直す必要があり、バッチ処理を組む際はこの短い有効期限を前提にリトライ処理を入れておく必要があります。
Reporting APIのレート制限はどれくらいですか?
SubmitGenerateReportRequestの呼び出し回数には上限がありますが、公式ドキュメント上、具体的な数値は公開されておらず、Microsoft側の都合で随時変更されうるものと考えられます。上限を超えると「You have already reached the maximum number of concurrent report requests.」というエラーになります。他のサービスには1ユーザーあたり1分間のコール数制限があるとの記載がありますが、Reporting Service固有の数値は公式には不明です。
Back to Blog

Related Posts

View All Posts

Amazon広告のレポート自動化|Amazon Ads APIの使い方

Amazon広告のレポート自動化は、まず「Amazon Ads API」と出品者業務向けの「SP-API」を混同しないことが出発点です。LWA(Login with Amazon)でのOAuth認証、API利用申請、Profile ID取得の手順から、reporting/reportsへのレポートリクエスト→ステータスのポーリング→ダウンロードという非同期取得の3ステップ、Pythonの実コードまでを、2026年8月時点で確認できる公式情報に沿って整理します。

X広告(旧Twitter)のレポート自動化|Ads APIの使い方

X広告(旧Twitter)のレポート自動化|Ads APIの使い方

X広告(旧Twitter広告)には無料の公式コネクタが無く、レポート自動化の本命はX Ads APIの直連携になります。ただし認証は一般のX API v2と異なるOAuth 1.0aで、利用にはApp IDごとの申請・審査が必要です。デベロッパー登録からKeys and tokensの発行、Ads API Access Formでの申請、広告主アカウントへの権限付与、非同期ジョブで日次CSVを自動取得するPython実装まで、実際のメニュー名とコピペで動くコードで一つずつ追います。

Google広告レポート自動化のやり方|API・BigQuery連携からAI分析まで

Google広告レポート自動化のやり方|API・BigQuery連携からAI分析まで

Google広告の日次レポートは、無料の公式手段だけで自動化できます。Looker Studio・Google Adsスクリプト・BigQuery Data Transfer・Ads API直連携それぞれの設定のやり方、開発者トークン申請とGAQL・Pythonの実コード、そして集めたデータをChatGPTやGeminiにつないで考察・日次サマリまで自動化する方法、リフレッシュトークン失効などの落とし穴を、2026年7月時点の公式情報で整理します。

LINE広告レポート自動化の現在地|API終了とLINEヤフー広告への移行

LINE広告レポート自動化の現在地|API終了とLINEヤフー広告への移行

LINE広告のレポート自動化は、2026年に前提が大きく変わりました。LINE広告APIは新規申請の受付を終了し、2027年3月に提供終了。広告自体も2026年4月からLINEヤフー広告ディスプレイ広告への統合が進んでいます。この記事では、終了までのタイムライン、既存API利用者・これから自動化したい人それぞれの選択肢、移行前に必ずやるべき過去データのエクスポート、移行後のLINEヤフー広告APIでの自動化までを、2026年7月時点の公式情報で整理します。