Amazon Developer

as

Settings
Sign out
Notifications
Alexa
Amazonアプリストア
Ring
AWS
ドキュメント
Support
Contact Us
My Cases
デバイス
ビルド
テスト
公開
関連情報
ドキュメント

収益化指標APIリファレンス

収益化指標APIリファレンス

このガイドには、収益化指標APIの統合に役立つリファレンス情報が含まれています。

収益化指標APIの使用には、Program Materials License Agreementが適用されます。

前提条件

API呼び出しを行う前に、次の要件を満たしていることを確認してください。

要件 詳細
Amazon開発者アカウント 管理者レベルの認証情報が必要
セキュリティプロファイル 開発者コンソール > [設定] > [APIアクセス] で作成
APIにマッピングされたセキュリティプロファイル プロファイルをReporting APIに関連付け
クライアントIDとクライアントシークレット セキュリティプロファイルの [ウェブ設定] タブから
Login with Amazon (LWA) スコープ adx_reporting::appstore:marketer
パッケージ名 アプリのパッケージ名(例:com.example.myapp)は開発者のベンダーアカウントが所有している必要があります
Python 3.6以上とrequestsライブラリ pip install requests

ベースURL

収益化指標APIのベースURLはhttps://developer.amazon.com/api/appstoreです。

操作

収益化指標APIには、以下の操作とエンドポイントが含まれています:

操作 メソッド エンドポイント 説明
最新状況の確認 GET /v2/applications/{packageName}/monetization/{metricSetName} 最新の利用可能なデータのタイムスタンプ
指標の照会 POST /v2/applications/{packageName}/monetization/{metricSetName}:query ディメンション/フィルター付きの時系列指標

{metricSetName}パスパラメーターには、次のメトリックセットを指定できます:subsSignupMetricSet, subsRenewalMetricSet, subsReactivationMetricSet, subsCancellationMetricSet, subsActiveMetricSet, subsHealthMetricSet, subsCancellationSurveyMetricSet, and subsFulfillmentMetricSet.

リクエスト

パラメーターと検証規則の詳細については、次のセクションを参照してください。

リクエストパラメーター

すべてのクエリリクエストには、次のパラメーターを含める必要があります。

パラメーター 説明 型 必須
timelineSpec.aggregationPeriod 返されるデータの詳細度です。 DAILYまたはHOURLYを指定できます。 文字列 はい
timelineSpec.startTime クエリウィンドウの下限は%Y-%m-%dT%H:%M:%SZ形式の ISO 8601 UTC タイムスタンプ文字列です例"2026-07-01T00:00:00Z"。両方の境界値を含みます。集計期間より細かいフィールドは無視され、拒否されません。 HOURLYのクエリでは分/秒が削除され(T10:15:00Zは10時として扱われます)、DAILYのクエリでは時間以下の単位が削除されます。 文字列 はい
timelineSpec.endTime クエリウィンドウの上限は%Y-%m-%dT%H:%M:%SZ形式の ISO 8601 UTC タイムスタンプ文字列です。startTime以降である必要があります。両方の境界値を含みます。StartTimeと同じルールで、より詳細なフィールドは無視されます。T11:30:45Zの HOURLY endTimeは11時として扱われるため、11時間目も引き続き含まれます。 文字列 はい
metrics[] メトリックセットから返されるメトリック名のサブセット。省略すると、セットで定義されているすべての指標が返されます。 配列 いいえ
dimensions[] 結果をグループ化するディメンション(例:subscriptionType、marketplace)。 配列 いいえ
filter フィルター条件を表すJSONオブジェクトです。各キーはディメンションを示し、その値には許容する値のリストを指定します(フィールド内はOR、フィールド間はANDとして処理されます)。たとえば、{"marketplace": ["US"]}。 オブジェクト いいえ
pageSize 1ページあたりの最大行数。デフォルト: 1,000。最大:100,000。 整数 いいえ
pageToken 前回のレスポンスのnextPageTokenとして返された不透明なカーソルです。初回のリクエストでは省略します。 文字列 いいえ

検証ルール

APIは実行前にすべてのクエリリクエストを検証します。次のルールのいずれかに違反するリクエストは400 VALIDATION_ERRORで拒否されます。応答本文のmessageフィールドには違反が説明されています。次の例は、各ルールで返されるメッセージを示しています。

ルール 違反した場合はエラー
endTimeはstartTime以上である必要があります timelineSpec.endTimeはstartTime以降である必要があります
HOURLYタイムスタンプは過去 15 日以内のものでなければなりません timelineSpec.startTime は過去 15 日以内でなければなりません
DAILYタイムスタンプは過去 30 日以内のものでなければなりません timelineSpec.startTime は過去 30 日以内でなければなりません
指標名は指標セットに存在する必要があります メトリクスには '... metricSet' でサポートされていない'... 'が含まれています。許可済み:[...]
ディメンション名が存在する必要があります ディメンションには、既知のディメンションではない '...' が含まれています。許可されています:[...]
ディメンションは指標セットでサポートされている必要があります ディメンションには '... metricSet' でサポートされていない'... 'が含まれています。許可:[...]
subsActiveMetricSetとsubsCancellationSurveyMetricSetはDAILYのみをサポートします '..MetricSet' はHOURLYの集計をサポートしていません
marketplaceはサポートされているコードである必要があります ディメンション「marketplace」の値「UK」は無効です。有効:[CA, US, MX, JP, FR, IT, DE, BR, ES, IN, AU, GB]
metricsに重複を含めることはできません メトリックスに「fulfilled」が複数回含まれています
dimensionsに重複を含めることはできません ディメンションに「marketplace」が複数回含まれています
pageSizeは負の値にすることはできません pageSizeは0以上である必要があります。取得した値: -5
タイムスタンプは有効なISO 8601 UTCインスタントである必要があります startTimeが無効です: 「2026-02-30T00:00:00Z」は有効な日付ではありません
フィルターキーあたり最大100個の値 400 VALIDATION_ERROR
pageTokenは前のレスポンスから取得した有効なカーソルであり、同じリクエスト形式で再利用する必要があります pageToken はこのリクエストと一致しません。カーソルが発行されてから、リクエスト形式(metricSet、timelineSpec、dimensions、または filter)が変更されました。新しいクエリを開始します。(FIELD_IMMUTABLE)

レスポンス

レスポンス形式は操作によって異なります。鮮度チェック(GET)は、freshnessInfo、クエリエンドポイント(POST)は要求された期間に一致する単一のfreshnessオブジェクトを返します。

GETの最新状況レスポンスフィールド

フィールド 常に存在する 注記
name はい 指標セット名
description はい 指標セットの説明
metrics はい 使用可能なメトリック名の配列
dimensions はい 使用可能な次元名の配列
freshnessInfo[] はい このメトリックセットでサポートされている集計期間ごとに、1つのエントリがあります。subsActiveMetricSetなどのDAILYのみのメトリックセットではDAILYエントリが1つ返されます。
freshnessInfo[].aggregationPeriod はい DAILYまたはHOURLYを指定できます。
freshnessInfo[].latestDataTimestamp はい 完全に完了した最新のバケットをISO 8601 UTCインスタントとして。DAILYはT00:00:00Z(UTC の1日全体が完了)を返しHOURLYはThh:00:00Z(その hh:00–hh:59 の時間が完了)を返します。

成功時のレスポンス(200)

ヘッダー
HTTP/1.1 200 OK
Content-Type: application/json
x-amzn-RequestId: 0d4db8e3-c535-4ba8-bdce-614eb6490570
本文
{
  "name": "subsSignupMetricSet",
  "description": 「新規サブスクリプション登録とサインアップ収益 」,  
  "metrics": ["signups", "signupRevenue"],
  "dimensions": ["marketplace", "termSku", "deviceType", "deviceOs", "subscriptionType"],
  "freshnessInfo": [
    {"aggregationPeriod": "DAILY", "latestDataTimestamp": "2026-07-06T00:00:00Z"},
    {"aggregationPeriod": "HOURLY", "latestDataTimestamp": "2026-07-06T14:00:00Z"}
  ]
}

latestDataTimestampの解釈: 値は、最新の完全に完了した集計バケットを示すISO 8601 UTCインスタントです。ラベルはバケットの開始時点であり、バケット全体が完了しています。HOURLYの場合、Thh:00:00Zはhh:00–hh:59の1時間が完了したことを意味します(たとえば、2026-07-06T14:00:00Zは14:00~14:59の1時間が完了したことを意味します)。DAILYの場合、YYYY-MM-DDT00:00:00ZはUTCの1日全体が完了したことを意味します(たとえば、2026-07-06T00:00:00Zは7月6日の1日全体が完了したことを意味します)。

POSTクエリレスポンスフィールド

フィールド 常に存在する 注記
freshness はい クエリされた集計期間の最新データタイムスタンプ
resultCount はい このページの行数
rows[] はい 一致するデータがない場合は空になることがあります
nextPageToken さらにページがある場合のみ 次のページを取得するには、次のリクエストに渡します

成功時のレスポンス(200)

ヘッダー
HTTP/1.1 200 OK
Content-Length: 735
Content-Type: application/json
Date: Mon, 21 Sep 2026 13:13:56 GMT
x-amzn-RequestId: 912d79f5-e9b6-4466-b438-b41a96c30acf
本文
{
  "freshness": {
    "aggregationPeriod": "DAILY",
    "latestDataTimestamp": "2026-07-06T00:00:00Z"
  },
  "resultCount": 3,
  "rows": [
    {
      "startTime": "2026-07-01T00:00:00Z",
      "aggregationPeriod": "DAILY",
      "dimensions": [
        {"name": "subscriptionType", "value": "FREE_TRIAL"},
        {"name": "marketplace", "value": "US"}
      ],
      "metrics": [
        {"name": "signups", "value": 2341},
        {"name": "signupRevenue", "value": 12345.6}
      ]
    }
  ],
  "nextPageToken": "MjAyNi0wNy0wMXwxNA=="
}

実装例

次の例は、収益化指標APIを使用したさまざまなタスクのPythonコードを示しています。

アクセストークンの取得

クライアントIDとクライアントシークレットを使用して認可トークンを取得し、各APIリクエストのヘッダーに追加する必要があります。以下の例では、認可トークンを取得し、このトークンを利用してAuthorizationヘッダーを作成する方法を紹介します。

import requests

# 指定する必要がある値
client_id = "<クライアントID>"
client_secret = "<クライアントシークレット>"
package_name = "<アプリのパッケージ名>"

BASE_URL = "https://developer.amazon.com/api/appstore"

scope = "adx_reporting::appstore:marketer"
data = {
    "grant_type": "client_credentials",
    "client_id": client_id,
    "client_secret": client_secret,
    "scope": scope
}
auth_response = requests.post("https://api.amazon.com/auth/o2/token", data=data)
auth_token = auth_response.json()["access_token"]

headers = {
    "Authorization": f"Bearer {auth_token}",
    "Content-Type": "application/json"
}

データの最新状況の確認

次の例は、クエリを実行する前に、利用可能な最新データのタイムスタンプを確認する方法を示しています。

freshness_url = f"{BASE_URL}/v2/applications/{package_name}/monetization/subsSignupMetricSet"
freshness_response = requests.get(freshness_url, headers=headers)
freshness = freshness_response.json()

for info in freshness["freshnessInfo"]:
    print(f"{info['aggregationPeriod']}: {info['latestDataTimestamp']}")

サインアップ指標のクエリ

次の例は、毎日の登録指標をクエリする方法を示しています。

query_url = f"{BASE_URL}/v2/applications/{package_name}/monetization/subsSignupMetricSet:query"
body = {
    "timelineSpec": {
        "aggregationPeriod": "DAILY",
        "startTime": "2026-07-01T00:00:00Z",
        "endTime": "2026-07-07T00:00:00Z"
    },
    "metrics": ["signups", "signupRevenue"]
}
response = requests.post(query_url, headers=headers, json=body)
result = response.json()

ディメンションを使ったクエリ

次の例は、サブスクリプションの種類とマーケットプレイスごとに登録を分類する方法を示しています。

body = {
    "timelineSpec": {
        "aggregationPeriod": "DAILY",
        "startTime": "2026-07-01T00:00:00Z",
        "endTime": "2026-07-07T00:00:00Z"
    },
    "metrics": ["signups", "signupRevenue"],
    "dimensions": ["subscriptionType", "marketplace"]
}
response = requests.post(query_url, headers=headers, json=body)
result = response.json()

フィルターを使ったクエリ

次の例は、米国内の無料トライアルの登録のみに結果を絞り込む方法を示しています。

body = {
    "timelineSpec": {
        "aggregationPeriod": "DAILY",
        "startTime": "2026-07-01T00:00:00Z",
        "endTime": "2026-07-07T00:00:00Z"
    },
    "metrics": ["signups"],
    "filter": {"subscriptionType": ["FREE_TRIAL"], "marketplace": ["US"]}
}
response = requests.post(query_url, headers=headers, json=body)
result = response.json()

時間単位のメトリクスのクエリ

次の例は、ほぼリアルタイムのサブスクリプションモニタリングのために時間単位のデータをクエリする方法を示しています。

body = {
    "timelineSpec": {
        "aggregationPeriod": "HOURLY",
        "startTime": "2026-07-07T08:00:00Z",
        "endTime": "2026-07-07T11:00:00Z"
    },
    "metrics": ["signups"],
    "dimensions": ["subscriptionType"]
}

1日中使用できるようにするには、startTimeをT00:00:00Zに、endTimeをT23:00:00Zに設定します。1時間につき1行が返されます。いずれの境界の分と秒も無視されます(該当する時間の開始時点に切り捨てられます)。

body = {
    "timelineSpec": {
        "aggregationPeriod": "HOURLY",
        "startTime": "2026-07-07T00:00:00Z",
        "endTime": "2026-07-07T23:00:00Z"
    },
    "metrics": ["signups"],
    "dimensions": ["subscriptionType"]
}
response = requests.post(query_url, headers=headers, json=body)
result = response.json()

フルフィルメント指標のクエリ

次の例は、レシート配信パフォーマンスをクエリする方法を示しています。

fulfillment_url = f"{BASE_URL}/v2/applications/{package_name}/monetization/subsFulfillmentMetricSet:query"
body = {
    "timelineSpec": {
        "aggregationPeriod": "DAILY",
        "startTime": "2026-07-01T00:00:00Z",
        "endTime": "2026-07-07T00:00:00Z"
    },
    "metrics": [
        "totalReceipts",
        "fulfilled",
        "unavailable",
        "pending",
        "p50AcknowledgementDelay",
        "p90AcknowledgementDelay",
        "p95AcknowledgementDelay"
    ],
    "filter": {"purchaseChannel": ["QS"]}
}
response = requests.post(fulfillment_url, headers=headers, json=body)
result = response.json()

サブスクリプションヘルスのクエリ

次の例は、自動更新の変更と猶予期間イベントを追跡する方法を示しています。

health_url = f"{BASE_URL}/v2/applications/{package_name}/monetization/subsHealthMetricSet:query"
body = {
    "timelineSpec": {
        "aggregationPeriod": "DAILY",
        "startTime": "2026-07-01T00:00:00Z",
        "endTime": "2026-07-07T00:00:00Z"
    },
    "metrics": ["autoRenewalOff", "autoRenewalOn", "gracePeriodEntries", "gracePeriodRecoveries"],
    "dimensions": ["subscriptionType"]
}
response = requests.post(health_url, headers=headers, json=body)
result = response.json()

キャンセルアンケートの回答のクエリ

次の例は、キャンセルアンケートで回答されたキャンセルを、顧客が選択した理由別に分類する方法を示しています。このメトリックセットは、DAILYの粒度のみをサポートします。

survey_url = f"{BASE_URL}/v2/applications/{package_name}/monetization/subsCancellationSurveyMetricSet:query"
body = {
    "timelineSpec": {
        "aggregationPeriod": "DAILY",
        "startTime": "2026-07-01T00:00:00Z",
        "endTime": "2026-07-07T00:00:00Z"
    },
    "metrics": ["surveyedCancellations"],
    "dimensions": ["cancellationReason"]
}
response = requests.post(survey_url, headers=headers, json=body)
result = response.json()

結果のページ分割

次の例は、レスポンスにnextPageTokenが含まれている場合に、すべての結果を取得する方法を示しています。

all_rows = []
page_token = None
while True:
    body = {
        "timelineSpec": {
            "aggregationPeriod": "DAILY",
            "startTime": "2026-07-01T00:00:00Z",
            "endTime": "2026-07-07T00:00:00Z"
        },
        "metrics": ["signups"],
        "dimensions": ["subscriptionType", "marketplace"],
        "pageSize": 100
    }
    if page_token:
        body["pageToken"] = page_token
    response = requests.post(query_url, headers=headers, json=body)
    result = response.json()
    all_rows.extend(result["rows"])
    page_token = result.get("nextPageToken")
    if not page_token:
        break

エラー処理

すべてのエラーは構造化されたJSONを返します。HTTP ステータス行にはステータスクラス(4xx/5xx)、本体には機械可読コード、人間が読めるメッセージ、(検証に失敗した場合は)問題のある各フィールドを識別するフィールドレベルのerrors[]配列が含まれます。

  フィールド 常に存在する 注記
1 code はい 標準列挙型からの機械可読エラーコード(たとえば、VALIDATION_ERROR)
2 message はい 人が判読できる形で記載されたエラーの説明
3 errors[] 検証に失敗した場合のみ フィールドレベルの詳細。各エントリにはfield(問題のある要素へのドット表記のパス。該当する場合は配列インデックスを含みます。例:metrics[1]またはfilter.deviceType[0])、code(VALUE_NOT_ALLOWEDやFIELD_INVALIDなどのフィールドレベルのコード)、およびmessageが含まれます

単一エラーの例

{
  "code": "VALIDATION_ERROR",
  "message": "metricsには、'subsSignupMetricSet'でサポートされていない値'不正な値'が含まれています。許可される値: [signupRevenue, signups]",
  "errors": [
    {
      "field": "metrics[0]",
      "code": "VALUE_NOT_ALLOWED",
      "message": "metricsには、'subsSignupMetricSet'でサポートされていない値'不正な値'が含まれています。許可される値: [signupRevenue, signups]"
    }
  ]
}

マルチフィールド検証の例

{
  "code": "VALIDATION_ERROR",
  "message": "The request contains 3 invalid fields.",
  "errors": [
    {
      "field": "metrics[1]",
      "code": "VALUE_NOT_ALLOWED",
      "message": "metricsには、'subsSignupMetricSet'でサポートされていない値'不正な値'が含まれています。許可される値: [signupRevenue, signups]"
    },
    {
      "field": "dimensions[0]",
      "code": "VALUE_NOT_ALLOWED",
      "message": "dimensionsには、既知のディメンションではない 'startType' が含まれています。許可される値: [deviceOs, deviceType, marketplace, subscriptionType, termSku]"
    },
    {
      "field": "filter.deviceType[1]",
      "code": "VALUE_NOT_ALLOWED",
      "message": "ディメンション'deviceType'の値'AMAZON_FIRE_TV'は無効です。有効: [FIRE_TABLET, FIRE_TV, OTHER]" 
    }
  ]
}

エラーコード

HTTPステータス コード 原因 対処法
400 VALIDATION_ERROR リクエストパラメータが正しくありません(指標、ディメンション、フィルター値、日付範囲が無効です) リクエストを修正してください。再試行しないでください
401 AUTHENTICATION_FAILED アクセストークンが見つからない、無効、または期限切れです トークンを更新して再試行します
403 ACCESS_DENIED 認証された呼び出し元には、このアプリまたはAPIの権限がありません パッケージ名がベンダーアカウントに属し、セキュリティプロファイルがReporting APIにマップされていることを確認します
404 RESOURCE_NOT_FOUND パッケージ名が間違っているか、空です パッケージ名のスペルを確認してください
429 RATE_LIMIT_EXCEEDED 1秒あたり5リクエストを超えました 待機時間を指数的に伸ばしながら再試行します
500 INTERNAL_ERROR 予期しないサーバーエラー 待機時間を伸ばしながら再試行します(最大3回)
503 SERVICE_UNAVAILABLE サービスまたは依存関係は一時的に利用できません バックオフして再試行

よくある誤りと修正

誤り 表示されるエラー 修正
timelineSpecが見つからない "timelineSpec is required" 必要なtimelineSpecオブジェクトを追加
HOURLYでsubsActiveMetricSetを使用 "subsActiveMetricSet does not support HOURLY aggregation" DAILYに切り替え
クエリ可能なウィンドウ外のstartTimeまたはendTime "timelineSpec.startTime must be within the last 15 days" (FIELD_OUT_OF_RANGE) 問題のあるタイムスタンプをウィンドウ内に移動します: DAILYは過去 30 日間(昨日まで)HOURLYは過去 15 日間
トークンの期限切れ 401 AUTHENTICATION_FAILED LWAトークンを更新
リクエストが多すぎる 429 Too Many Requests 呼び出しの間にtime.sleep()を追加
指標セットに間違ったディメンションを使用している "dimensions contains 'renewalType' which is not supported by 'subsSignupMetricSet'; allowed: […]" その指標セットに適切なディメンションを使用します
dimensions、filter、またはtimelineSpecを変更した後にページトークンを再利用すること FIELD_IMMUTABLE: "pageToken does not match this request" 古いトークンなしで新しいクエリを開始します。ページ間で変更できるのはpageSizeだけです。
URLのmetricSetNameのスペルが間違っている 400 VALIDATION_ERROR: "Unsupported metricSetName: …; allowed: […]" エラーメッセージに記載されている指標セット名のいずれかを使用してください

再試行とベストプラクティス

再試行の戦略とベストプラクティスについては、次のセクションを参照してください。

再試行戦略の例

import time

MAX_RETRIES = 3
RETRIABLE_CODES = {429, 500, 502, 503, 504}

def query_with_retry(url, headers、 体):
    for attempt in range(MAX_RETRIES):
        resp = requests.post(url, headers=headers, json=body)
        if resp.status_code == 200:
            return resp.json()
        if resp.status_code not in RETRIABLE_CODES:
            break  # 再試行不可のエラー
        wait = (2 ** attempt) + 0.5  # 1.5秒、2.5秒、4.5秒
        print(f"Retry {attempt + 1}/{MAX_RETRIES} after {wait}s (HTTP {resp.status_code})")
        time.sleep(wait)
    # 最後の試行は失敗しました
    error = resp.json() if resp.headers.get("content-type", "").startswith("application/json") else {}
    raise RuntimeError(f"Failed after {MAX_RETRIES} retries: {resp.status_code} {error.get('message', '')}")

本番環境でのベストプラクティス

ベストプラクティス 推奨される方法
トークンのキャッシング トークンをキャッシュし、有効期限が切れる 5 分前に更新します。API呼び出しごとに新しいトークンをリクエストしないでください。
最初に最新状況を確認する 結果が空にならないように、クエリを実行する前に必ず最新状況エンドポイントを呼び出します。
ページ分割を使用する デフォルトのpageSizeは1000です。ディメンションによる内訳が多い場合は、タイムアウトを避けるためにページ分割を行います。
リクエスト頻度の制限 1秒あたり5リクエスト未満にします。連続した呼び出しの間にtime.sleep(0.2)を追加します。
再試行可能なエラーについてのみ再試行する 429、500、502、503、および504を再試行します。400は再試行しない(代わりにリクエストを修正)。
空の結果を処理する rows: []を返すクエリはエラーではありません。これは、その日付範囲のデータがないことを意味します。
オーバーフェッチを回避する 必要な指標のみをリクエストする。metrics[]を省略すると、すべてが返されますが、速度は遅くなります。

Last updated: 2026年10月13日