収益化指標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) |
termSkuはフリーテキストであり、指定されたとおりに渡されます。そのため、termSku フィルター値のスペルを間違えると、エラーではなく空の結果セットが返されます。他のすべてのディメンションは固定値のセットに対して検証され、認識されない値は400 VALIDATION_ERRORで拒否されます。レスポンス
レスポンス形式は操作によって異なります。鮮度チェック(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コードを示しています。
DAILY タイムスタンプと、過去 15 日間の HOURLY タイムスタンプを受け入れるため、そのウィンドウ内の日付に置き換えてください。データの最新状況の確認の例を使用して、利用可能な最新の日付を確認してください。アクセストークンの取得
クライアント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[]を省略すると、すべてが返されますが、速度は遅くなります。 |
関連トピック
- 収益化指標APIの概要: 使用可能な指標とディメンション
- API Explorer: 開発者ポータルのインタラクティブなAPI Explorer
- APIの確認: Developer ConsoleのAPI Explorerへのリンク
Last updated: 2026年10月13日

