1
0
mirror of synced 2025-12-25 02:09:19 -05:00

feat:Amazon Ads - Add DAILY option for Reports streams & Auto-update start_date if past lookback(retention) period (#55217)

Co-authored-by: Octavia Squidington III <octavia-squidington-iii@users.noreply.github.com>
This commit is contained in:
Alfredo Garcia
2025-04-22 09:34:12 -05:00
committed by GitHub
parent 38c86073c0
commit 3bac873393
20 changed files with 2879 additions and 310 deletions

View File

@@ -65,6 +65,32 @@ acceptance_tests:
bypass_reason: "can't populate stream because it requires real ad campaign"
- name: sponsored_product_ad_group_bid_recommendations
bypass_reason: "data is updated frequently"
- name: sponsored_display_campaigns_report_stream_daily
bypass_reason: "can't populate stream because it requires real ad campaign"
- name: sponsored_products_keywords_report_stream_daily
bypass_reason: "can't populate stream because it requires real ad campaign"
- name: sponsored_display_productads_report_stream_daily
bypass_reason: "can't populate stream because it requires real ad campaign"
- name: sponsored_products_campaigns_report_stream_daily
bypass_reason: "can't populate stream because it requires real ad campaign"
- name: sponsored_products_asins_keywords_report_stream_daily
bypass_reason: "can't populate stream because it requires real ad campaign"
- name: sponsored_display_targets_report_stream_daily
bypass_reason: "can't populate stream because it requires real ad campaign"
- name: sponsored_products_productads_report_stream_daily
bypass_reason: "can't populate stream because it requires real ad campaign"
- name: sponsored_display_asins_report_stream_daily
bypass_reason: "can't populate stream because it requires real ad campaign"
- name: sponsored_brands_v3_report_stream_daily
bypass_reason: "can't populate stream because it requires real ad campaign"
- name: sponsored_products_asins_targets_report_stream_daily
bypass_reason: "can't populate stream because it requires real ad campaign"
- name: sponsored_products_adgroups_report_stream_daily
bypass_reason: "can't populate stream because it requires real ad campaign"
- name: sponsored_display_adgroups_report_stream_daily
bypass_reason: "can't populate stream because it requires real ad campaign"
- name: sponsored_products_targets_report_stream_daily
bypass_reason: "can't populate stream because it requires real ad campaign"
timeout_seconds: 2400
expect_records:
path: integration_tests/expected_records.jsonl

View File

@@ -31,6 +31,38 @@
"cursor_field": ["reportDate"],
"sync_mode": "incremental",
"destination_sync_mode": "overwrite"
},
{
"stream": {
"name": "sponsored_products_report_stream_daily",
"json_schema": {},
"supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_primary_key": [
["profileId"],
["recordType"],
["reportDate"],
["recordId"]
]
},
"cursor_field": ["reportDate"],
"sync_mode": "incremental",
"destination_sync_mode": "overwrite"
},
{
"stream": {
"name": "sponsored_brands_v3_report_stream_daily",
"json_schema": {},
"supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_primary_key": [
["profileId"],
["recordType"],
["reportDate"],
["recordId"]
]
},
"cursor_field": ["reportDate"],
"sync_mode": "incremental",
"destination_sync_mode": "overwrite"
}
]
}

View File

@@ -13,7 +13,7 @@ data:
connectorSubtype: api
connectorType: source
definitionId: c6b0a29e-1da9-4512-9002-7bfd0cba2246
dockerImageTag: 7.1.7
dockerImageTag: 7.2.0-rc.1
dockerRepository: airbyte/source-amazon-ads
documentationUrl: https://docs.airbyte.com/integrations/sources/amazon-ads
githubIssueLabel: source-amazon-ads
@@ -34,6 +34,8 @@ data:
enabled: true
releaseStage: generally_available
releases:
rolloutConfiguration:
enableProgressiveRollout: true
breakingChanges:
7.0.0:
message:

View File

@@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",]
build-backend = "poetry.core.masonry.api"
[tool.poetry]
version = "7.1.7"
version = "7.2.0-rc.1"
name = "source-amazon-ads"
description = "Source implementation for Amazon Ads."
authors = [ "Airbyte <contact@airbyte.io>",]

View File

@@ -1235,7 +1235,6 @@ definitions:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
@@ -1248,28 +1247,67 @@ definitions:
adProduct: SPONSORED_BRANDS
groupBy: ["purchasedAsin"]
columns:
[
"campaignBudgetCurrencyCode",
"campaignName",
"adGroupName",
"attributionType",
"purchasedAsin",
"productName",
"productCategory",
"sales14d",
"orders14d",
"unitsSold14d",
"newToBrandSales14d",
"newToBrandPurchases14d",
"newToBrandUnitsSold14d",
"newToBrandSalesPercentage14d",
"newToBrandPurchasesPercentage14d",
"newToBrandUnitsSoldPercentage14d",
]
- "campaignBudgetCurrencyCode"
- "campaignName"
- "adGroupName"
- "attributionType"
- "purchasedAsin"
- "productName"
- "productCategory"
- "sales14d"
- "orders14d"
- "unitsSold14d"
- "newToBrandSales14d"
- "newToBrandPurchases14d"
- "newToBrandUnitsSold14d"
- "newToBrandSalesPercentage14d"
- "newToBrandPurchasesPercentage14d"
- "newToBrandUnitsSoldPercentage14d"
reportTypeId: sbPurchasedProduct
filters: []
timeUnit: SUMMARY
format: GZIP_JSON
sponsored_brands_v3_report_stream_daily:
type: DeclarativeStream
name: sponsored_brands_v3_report_stream_daily
primary_key: ["profileId", "reportDate", "adGroupName", "purchasedAsin"]
incremental_sync:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
$ref: "#/definitions/basic_async_retriever/creation_requester"
request_body_json:
name: "purchasedAsin report daily {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: SPONSORED_BRANDS
groupBy: ["purchasedAsin"]
columns:
- "date"
- "campaignBudgetCurrencyCode"
- "campaignName"
- "adGroupName"
- "attributionType"
- "purchasedAsin"
- "productName"
- "productCategory"
- "sales14d"
- "orders14d"
- "unitsSold14d"
- "newToBrandSales14d"
- "newToBrandPurchases14d"
- "newToBrandUnitsSold14d"
- "newToBrandSalesPercentage14d"
- "newToBrandPurchasesPercentage14d"
- "newToBrandUnitsSoldPercentage14d"
reportTypeId: sbPurchasedProduct
filters: []
timeUnit: DAILY
format: GZIP_JSON
sponsored_display_campaigns_report_stream:
type: DeclarativeStream
@@ -1361,6 +1399,93 @@ definitions:
filters: []
timeUnit: SUMMARY
format: GZIP_JSON
sponsored_display_campaigns_report_stream_daily:
type: DeclarativeStream
name: sponsored_display_campaigns_report_stream_daily
primary_key: ["profileId", "reportDate", "campaignId"]
incremental_sync:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
$ref: "#/definitions/basic_async_retriever/creation_requester"
request_body_json:
name: "campaigns report daily {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: SPONSORED_DISPLAY
groupBy: ["campaign"]
columns:
- "date"
- "addToCart"
- "addToCartClicks"
- "addToCartRate"
- "addToCartViews"
- "addToList"
- "addToListFromClicks"
- "addToListFromViews"
- "qualifiedBorrows"
- "qualifiedBorrowsFromClicks"
- "qualifiedBorrowsFromViews"
- "royaltyQualifiedBorrows"
- "royaltyQualifiedBorrowsFromClicks"
- "royaltyQualifiedBorrowsFromViews"
- "brandedSearches"
- "brandedSearchesClicks"
- "brandedSearchesViews"
- "brandedSearchRate"
- "campaignBudgetCurrencyCode"
- "campaignId"
- "campaignName"
- "clicks"
- "cost"
- "detailPageViews"
- "detailPageViewsClicks"
- "eCPAddToCart"
- "eCPBrandSearch"
- "impressions"
- "impressionsViews"
- "leadFormOpens"
- "leads"
- "linkOuts"
- "newToBrandPurchases"
- "newToBrandPurchasesClicks"
- "newToBrandSalesClicks"
- "newToBrandUnitsSold"
- "newToBrandUnitsSoldClicks"
- "purchases"
- "purchasesClicks"
- "purchasesPromotedClicks"
- "sales"
- "salesClicks"
- "salesPromotedClicks"
- "unitsSold"
- "unitsSoldClicks"
- "videoCompleteViews"
- "videoFirstQuartileViews"
- "videoMidpointViews"
- "videoThirdQuartileViews"
- "videoUnmutes"
- "viewabilityRate"
- "viewClickThroughRate"
- "campaignBudgetAmount"
- "campaignStatus"
- "costType"
- "cumulativeReach"
- "impressionsFrequencyAverage"
- "newToBrandDetailPageViewClicks"
- "newToBrandDetailPageViewRate"
- "newToBrandDetailPageViews"
- "newToBrandDetailPageViewViews"
- "newToBrandECPDetailPageView"
- "newToBrandSales"
reportTypeId: sdCampaigns
filters: []
timeUnit: DAILY
format: GZIP_JSON
sponsored_display_adgroups_report_stream:
type: DeclarativeStream
name: sponsored_display_adgroups_report_stream
@@ -1451,6 +1576,93 @@ definitions:
filters: []
timeUnit: SUMMARY
format: GZIP_JSON
sponsored_display_adgroups_report_stream_daily:
type: DeclarativeStream
name: sponsored_display_adgroups_report_stream_daily
primary_key: ["profileId", "reportDate", "adGroupName", "adGroupId"]
incremental_sync:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
$ref: "#/definitions/basic_async_retriever/creation_requester"
request_body_json:
name: "adGroups report daily {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: SPONSORED_DISPLAY
groupBy: ["adGroup"]
columns:
- "date"
- "addToCart"
- "addToCartClicks"
- "addToCartRate"
- "addToCartViews"
- "adGroupId"
- "adGroupName"
- "addToList"
- "addToListFromClicks"
- "addToListFromViews"
- "qualifiedBorrows"
- "qualifiedBorrowsFromClicks"
- "qualifiedBorrowsFromViews"
- "royaltyQualifiedBorrows"
- "royaltyQualifiedBorrowsFromClicks"
- "royaltyQualifiedBorrowsFromViews"
- "bidOptimization"
- "brandedSearches"
- "brandedSearchesClicks"
- "brandedSearchesViews"
- "brandedSearchRate"
- "campaignBudgetCurrencyCode"
- "campaignId"
- "campaignName"
- "clicks"
- "cost"
- "detailPageViews"
- "detailPageViewsClicks"
- "eCPAddToCart"
- "eCPBrandSearch"
- "impressions"
- "impressionsViews"
- "leadFormOpens"
- "leads"
- "linkOuts"
- "newToBrandPurchases"
- "newToBrandPurchasesClicks"
- "newToBrandSales"
- "newToBrandSalesClicks"
- "newToBrandUnitsSold"
- "newToBrandUnitsSoldClicks"
- "purchases"
- "purchasesClicks"
- "purchasesPromotedClicks"
- "sales"
- "salesClicks"
- "salesPromotedClicks"
- "unitsSold"
- "unitsSoldClicks"
- "videoCompleteViews"
- "videoFirstQuartileViews"
- "videoMidpointViews"
- "videoThirdQuartileViews"
- "videoUnmutes"
- "viewabilityRate"
- "viewClickThroughRate"
- "cumulativeReach"
- "impressionsFrequencyAverage"
- "newToBrandDetailPageViewClicks"
- "newToBrandDetailPageViewRate"
- "newToBrandDetailPageViews"
- "newToBrandDetailPageViewViews"
- "newToBrandECPDetailPageView"
reportTypeId: sdAdGroup
filters: []
timeUnit: DAILY
format: GZIP_JSON
sponsored_display_productads_report_stream:
type: DeclarativeStream
name: sponsored_display_productads_report_stream
@@ -1544,6 +1756,96 @@ definitions:
filters: []
timeUnit: SUMMARY
format: GZIP_JSON
sponsored_display_productads_report_stream_daily:
type: DeclarativeStream
name: sponsored_display_productads_report_stream_daily
primary_key: ["profileId", "reportDate", "adGroupName", "adId"]
incremental_sync:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
$ref: "#/definitions/basic_async_retriever/creation_requester"
request_body_json:
name: "productAds report daily {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: SPONSORED_DISPLAY
groupBy: ["advertiser"]
columns:
- "date"
- "addToCart"
- "addToCartRate"
- "addToCartViews"
- "addToCartClicks"
- "adGroupId"
- "adGroupName"
- "adId"
- "addToList"
- "addToListFromClicks"
- "qualifiedBorrows"
- "royaltyQualifiedBorrows"
- "addToListFromViews"
- "qualifiedBorrowsFromClicks"
- "qualifiedBorrowsFromViews"
- "royaltyQualifiedBorrowsFromClicks"
- "royaltyQualifiedBorrowsFromViews"
- "bidOptimization"
- "brandedSearches"
- "brandedSearchesClicks"
- "brandedSearchesViews"
- "brandedSearchRate"
- "campaignBudgetCurrencyCode"
- "campaignId"
- "campaignName"
- "clicks"
- "cost"
- "cumulativeReach"
- "detailPageViews"
- "detailPageViewsClicks"
- "eCPAddToCart"
- "eCPBrandSearch"
- "impressions"
- "impressionsFrequencyAverage"
- "impressionsViews"
- "leadFormOpens"
- "leads"
- "linkOuts"
- "newToBrandDetailPageViewClicks"
- "newToBrandDetailPageViewRate"
- "newToBrandDetailPageViews"
- "newToBrandDetailPageViewViews"
- "newToBrandECPDetailPageView"
- "newToBrandPurchases"
- "newToBrandPurchasesClicks"
- "newToBrandSales"
- "newToBrandSalesClicks"
- "newToBrandUnitsSold"
- "newToBrandUnitsSoldClicks"
- "promotedAsin"
- "promotedSku"
- "purchases"
- "purchasesClicks"
- "purchasesPromotedClicks"
- "sales"
- "salesClicks"
- "salesPromotedClicks"
- "unitsSold"
- "unitsSoldClicks"
- "videoCompleteViews"
- "videoFirstQuartileViews"
- "videoMidpointViews"
- "videoThirdQuartileViews"
- "videoUnmutes"
- "viewabilityRate"
- "viewClickThroughRate"
reportTypeId: sdAdvertisedProduct
filters: []
timeUnit: DAILY
format: GZIP_JSON
sponsored_display_targets_report_stream:
type: DeclarativeStream
name: sponsored_display_targets_report_stream
@@ -1629,6 +1931,88 @@ definitions:
filters: []
timeUnit: SUMMARY
format: GZIP_JSON
sponsored_display_targets_report_stream_daily:
type: DeclarativeStream
name: sponsored_display_targets_report_stream_daily
primary_key: ["profileId", "reportDate", "adGroupName", "targetingId"]
incremental_sync:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
$ref: "#/definitions/basic_async_retriever/creation_requester"
request_body_json:
name: "targets report daily {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: SPONSORED_DISPLAY
groupBy: ["targeting"]
columns:
- "date"
- "addToCart"
- "addToCartClicks"
- "addToCartRate"
- "addToCartViews"
- "adGroupId"
- "adGroupName"
- "addToList"
- "addToListFromClicks"
- "addToListFromViews"
- "qualifiedBorrows"
- "qualifiedBorrowsFromClicks"
- "qualifiedBorrowsFromViews"
- "royaltyQualifiedBorrows"
- "royaltyQualifiedBorrowsFromClicks"
- "royaltyQualifiedBorrowsFromViews"
- "brandedSearches"
- "brandedSearchesClicks"
- "brandedSearchesViews"
- "brandedSearchRate"
- "campaignBudgetCurrencyCode"
- "campaignId"
- "campaignName"
- "clicks"
- "cost"
- "detailPageViews"
- "detailPageViewsClicks"
- "eCPAddToCart"
- "eCPBrandSearch"
- "impressions"
- "impressionsViews"
- "leadFormOpens"
- "leads"
- "linkOuts"
- "newToBrandPurchases"
- "newToBrandPurchasesClicks"
- "newToBrandSales"
- "newToBrandSalesClicks"
- "newToBrandUnitsSold"
- "newToBrandUnitsSoldClicks"
- "purchases"
- "purchasesClicks"
- "purchasesPromotedClicks"
- "sales"
- "salesClicks"
- "salesPromotedClicks"
- "targetingExpression"
- "targetingId"
- "targetingText"
- "unitsSold"
- "unitsSoldClicks"
- "videoCompleteViews"
- "videoFirstQuartileViews"
- "videoMidpointViews"
- "videoThirdQuartileViews"
- "videoUnmutes"
- "viewabilityRate"
- "viewClickThroughRate"
reportTypeId: sdTargeting
filters: []
timeUnit: DAILY
format: GZIP_JSON
sponsored_display_asins_report_stream:
type: DeclarativeStream
name: sponsored_display_asins_report_stream
@@ -1680,6 +2064,54 @@ definitions:
filters: []
timeUnit: SUMMARY
format: GZIP_JSON
sponsored_display_asins_report_stream_daily:
type: DeclarativeStream
name: sponsored_display_asins_report_stream_daily
primary_key: ["profileId", "reportDate", "adGroupName", "promotedAsin"]
incremental_sync:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
$ref: "#/definitions/basic_async_retriever/creation_requester"
request_body_json:
name: "asins report daily {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: SPONSORED_DISPLAY
groupBy: ["asin"]
columns:
- "date"
- "adGroupId"
- "adGroupName"
- "asinBrandHalo"
- "addToList"
- "addToListFromClicks"
- "qualifiedBorrowsFromClicks"
- "royaltyQualifiedBorrowsFromClicks"
- "addToListFromViews"
- "qualifiedBorrows"
- "qualifiedBorrowsFromViews"
- "royaltyQualifiedBorrows"
- "royaltyQualifiedBorrowsFromViews"
- "campaignBudgetCurrencyCode"
- "campaignId"
- "campaignName"
- "conversionsBrandHalo"
- "conversionsBrandHaloClicks"
- "promotedAsin"
- "promotedSku"
- "salesBrandHalo"
- "salesBrandHaloClicks"
- "unitsSoldBrandHalo"
- "unitsSoldBrandHaloClicks"
reportTypeId: sdPurchasedProduct
filters: []
timeUnit: DAILY
format: GZIP_JSON
sponsored_products_campaigns_report_stream:
type: DeclarativeStream
@@ -1741,6 +2173,65 @@ definitions:
filters: []
timeUnit: SUMMARY
format: GZIP_JSON
sponsored_products_campaigns_report_stream_daily:
type: DeclarativeStream
name: sponsored_products_campaigns_report_stream_daily
primary_key: ["profileId", "reportDate", "campaignId"]
incremental_sync:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
$ref: "#/definitions/basic_async_retriever/creation_requester"
request_body_json:
name: "campaigns report daily {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: SPONSORED_PRODUCTS
groupBy: ["campaign"]
columns:
- "date"
- "campaignName"
- "campaignId"
- "campaignStatus"
- "campaignBudgetAmount"
- "campaignRuleBasedBudgetAmount"
- "campaignApplicableBudgetRuleId"
- "campaignApplicableBudgetRuleName"
- "impressions"
- "clicks"
- "cost"
- "purchases1d"
- "purchases7d"
- "purchases14d"
- "purchases30d"
- "purchasesSameSku1d"
- "purchasesSameSku7d"
- "purchasesSameSku14d"
- "purchasesSameSku30d"
- "unitsSoldClicks1d"
- "unitsSoldClicks7d"
- "unitsSoldClicks14d"
- "unitsSoldClicks30d"
- "sales1d"
- "sales7d"
- "sales14d"
- "sales30d"
- "attributedSalesSameSku1d"
- "attributedSalesSameSku7d"
- "attributedSalesSameSku14d"
- "attributedSalesSameSku30d"
- "unitsSoldSameSku1d"
- "unitsSoldSameSku7d"
- "unitsSoldSameSku14d"
- "unitsSoldSameSku30d"
reportTypeId: spCampaigns
filters: []
timeUnit: DAILY
format: GZIP_JSON
sponsored_products_adgroups_report_stream:
type: DeclarativeStream
name: sponsored_products_adgroups_report_stream
@@ -1798,6 +2289,62 @@ definitions:
filters: []
timeUnit: SUMMARY
format: GZIP_JSON
sponsored_products_adgroups_report_stream_daily:
type: DeclarativeStream
name: sponsored_products_adgroups_report_stream_daily
primary_key: ["profileId", "reportDate", "adGroupName", "adGroupId"]
incremental_sync:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
$ref: "#/definitions/basic_async_retriever/creation_requester"
request_body_json:
name: "adGroups report daily {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: SPONSORED_PRODUCTS
groupBy: ["campaign", "adGroup"]
columns:
- "date"
- "campaignName"
- "campaignId"
- "adGroupName"
- "adGroupId"
- "impressions"
- "clicks"
- "cost"
- "purchases1d"
- "purchases7d"
- "purchases14d"
- "purchases30d"
- "purchasesSameSku1d"
- "purchasesSameSku7d"
- "purchasesSameSku14d"
- "purchasesSameSku30d"
- "unitsSoldClicks1d"
- "unitsSoldClicks7d"
- "unitsSoldClicks14d"
- "unitsSoldClicks30d"
- "sales1d"
- "sales7d"
- "sales14d"
- "sales30d"
- "attributedSalesSameSku1d"
- "attributedSalesSameSku7d"
- "attributedSalesSameSku14d"
- "attributedSalesSameSku30d"
- "unitsSoldSameSku1d"
- "unitsSoldSameSku7d"
- "unitsSoldSameSku14d"
- "unitsSoldSameSku30d"
reportTypeId: spCampaigns
filters: []
timeUnit: DAILY
format: GZIP_JSON
sponsored_products_keywords_report_stream:
type: DeclarativeStream
name: sponsored_products_keywords_report_stream
@@ -1864,6 +2411,67 @@ definitions:
]
timeUnit: SUMMARY
format: GZIP_JSON
sponsored_products_keywords_report_stream_daily:
type: DeclarativeStream
name: sponsored_products_keywords_report_stream_daily
primary_key: ["profileId", "reportDate", "adGroupName", "keywordId"]
incremental_sync:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
$ref: "#/definitions/basic_async_retriever/creation_requester"
request_body_json:
name: "keywords report daily {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: SPONSORED_PRODUCTS
groupBy: ["targeting"]
columns:
- "date"
- "campaignName"
- "campaignId"
- "adGroupName"
- "adGroupId"
- "keywordId"
- "keyword"
- "matchType"
- "impressions"
- "clicks"
- "cost"
- "purchases1d"
- "purchases7d"
- "purchases14d"
- "purchases30d"
- "purchasesSameSku1d"
- "purchasesSameSku7d"
- "purchasesSameSku14d"
- "purchasesSameSku30d"
- "unitsSoldClicks1d"
- "unitsSoldClicks7d"
- "unitsSoldClicks14d"
- "unitsSoldClicks30d"
- "sales1d"
- "sales7d"
- "sales14d"
- "sales30d"
- "attributedSalesSameSku1d"
- "attributedSalesSameSku7d"
- "attributedSalesSameSku14d"
- "attributedSalesSameSku30d"
- "unitsSoldSameSku1d"
- "unitsSoldSameSku7d"
- "unitsSoldSameSku14d"
- "unitsSoldSameSku30d"
reportTypeId: spTargeting
filters:
- field: "keywordType"
values: ["BROAD", "PHRASE", "EXACT"]
timeUnit: DAILY
format: GZIP_JSON
sponsored_products_targets_report_stream:
type: DeclarativeStream
name: sponsored_products_targets_report_stream
@@ -1935,6 +2543,70 @@ definitions:
]
timeUnit: SUMMARY
format: GZIP_JSON
sponsored_products_targets_report_stream_daily:
type: DeclarativeStream
name: sponsored_products_targets_report_stream_daily
primary_key: ["profileId", "reportDate", "adGroupName", "keywordId"]
incremental_sync:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
$ref: "#/definitions/basic_async_retriever/creation_requester"
request_body_json:
name: "targets report daily {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: SPONSORED_PRODUCTS
groupBy: ["targeting"]
columns:
- "date"
- "campaignName"
- "campaignId"
- "adGroupName"
- "adGroupId"
- "keywordId"
- "keyword"
- "targeting"
- "keywordType"
- "impressions"
- "clicks"
- "cost"
- "purchases1d"
- "purchases7d"
- "purchases14d"
- "purchases30d"
- "purchasesSameSku1d"
- "purchasesSameSku7d"
- "purchasesSameSku14d"
- "purchasesSameSku30d"
- "unitsSoldClicks1d"
- "unitsSoldClicks7d"
- "unitsSoldClicks14d"
- "unitsSoldClicks30d"
- "sales1d"
- "sales7d"
- "sales14d"
- "sales30d"
- "attributedSalesSameSku1d"
- "attributedSalesSameSku7d"
- "attributedSalesSameSku14d"
- "attributedSalesSameSku30d"
- "unitsSoldSameSku1d"
- "unitsSoldSameSku7d"
- "unitsSoldSameSku14d"
- "unitsSoldSameSku30d"
reportTypeId: spTargeting
filters:
- field: "keywordType"
values:
- "TARGETING_EXPRESSION"
- "TARGETING_EXPRESSION_PREDEFINED"
timeUnit: DAILY
format: GZIP_JSON
sponsored_products_productads_report_stream:
type: DeclarativeStream
name: sponsored_products_productads_report_stream
@@ -1995,6 +2667,65 @@ definitions:
filters: []
timeUnit: SUMMARY
format: GZIP_JSON
sponsored_products_productads_report_stream_daily:
type: DeclarativeStream
name: sponsored_products_productads_report_stream_daily
primary_key: ["profileId", "reportDate", "adGroupName", "adId"]
incremental_sync:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
$ref: "#/definitions/basic_async_retriever/creation_requester"
request_body_json:
name: "productAds report daily {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: SPONSORED_PRODUCTS
groupBy: ["advertiser"]
columns:
- "date"
- "campaignName"
- "campaignId"
- "adGroupName"
- "adGroupId"
- "adId"
- "impressions"
- "clicks"
- "cost"
- "campaignBudgetCurrencyCode"
- "advertisedAsin"
- "purchases1d"
- "purchases7d"
- "purchases14d"
- "purchases30d"
- "purchasesSameSku1d"
- "purchasesSameSku7d"
- "purchasesSameSku14d"
- "purchasesSameSku30d"
- "unitsSoldClicks1d"
- "unitsSoldClicks7d"
- "unitsSoldClicks14d"
- "unitsSoldClicks30d"
- "sales1d"
- "sales7d"
- "sales14d"
- "sales30d"
- "attributedSalesSameSku1d"
- "attributedSalesSameSku7d"
- "attributedSalesSameSku14d"
- "attributedSalesSameSku30d"
- "unitsSoldSameSku1d"
- "unitsSoldSameSku7d"
- "unitsSoldSameSku14d"
- "unitsSoldSameSku30d"
reportTypeId: spAdvertisedProduct
filters: []
timeUnit: DAILY
format: GZIP_JSON
sponsored_products_asins_keywords_report_stream:
type: DeclarativeStream
name: sponsored_products_asins_keywords_report_stream
@@ -2044,6 +2775,54 @@ definitions:
filters: []
timeUnit: SUMMARY
format: GZIP_JSON
sponsored_products_asins_keywords_report_stream_daily:
type: DeclarativeStream
name: sponsored_products_asins_keywords_report_stream_daily
primary_key: ["profileId", "reportDate", "adGroupName", "advertisedAsin"]
incremental_sync:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
$ref: "#/definitions/basic_async_retriever/creation_requester"
request_body_json:
name: "asins_keywords report daily {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: SPONSORED_PRODUCTS
groupBy: ["asin"]
columns:
- "date"
- "campaignName"
- "campaignId"
- "adGroupName"
- "adGroupId"
- "keywordId"
- "keyword"
- "advertisedAsin"
- "purchasedAsin"
- "advertisedSku"
- "campaignBudgetCurrencyCode"
- "matchType"
- "unitsSoldClicks1d"
- "unitsSoldClicks7d"
- "unitsSoldClicks14d"
- "unitsSoldClicks30d"
- "unitsSoldOtherSku1d"
- "unitsSoldOtherSku7d"
- "unitsSoldOtherSku14d"
- "unitsSoldOtherSku30d"
- "salesOtherSku1d"
- "salesOtherSku7d"
- "salesOtherSku14d"
- "salesOtherSku30d"
reportTypeId: spPurchasedProduct
filters: []
timeUnit: DAILY
format: GZIP_JSON
sponsored_products_asins_targets_report_stream:
type: DeclarativeStream
name: sponsored_products_asins_targets_report_stream
@@ -2094,6 +2873,55 @@ definitions:
filters: []
timeUnit: SUMMARY
format: GZIP_JSON
sponsored_products_asins_targets_report_stream_daily:
type: DeclarativeStream
name: sponsored_products_asins_targets_report_stream_daily
primary_key: ["profileId", "reportDate", "adGroupName", "advertisedAsin"]
incremental_sync:
$ref: "#/definitions/incremental_sync_report_datetime_cursor"
transformations:
$ref: "#/definitions/transformation_report_add_fields"
retriever:
$ref: "#/definitions/basic_async_retriever"
creation_requester:
$ref: "#/definitions/basic_async_retriever/creation_requester"
request_body_json:
name: "asins_targets report daily {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: SPONSORED_PRODUCTS
groupBy: ["asin"]
columns:
- "date"
- "campaignName"
- "campaignId"
- "adGroupName"
- "adGroupId"
- "advertisedAsin"
- "purchasedAsin"
- "advertisedSku"
- "campaignBudgetCurrencyCode"
- "matchType"
- "unitsSoldClicks1d"
- "unitsSoldClicks7d"
- "unitsSoldClicks14d"
- "unitsSoldClicks30d"
- "unitsSoldOtherSku1d"
- "unitsSoldOtherSku7d"
- "unitsSoldOtherSku14d"
- "unitsSoldOtherSku30d"
- "salesOtherSku1d"
- "salesOtherSku7d"
- "salesOtherSku14d"
- "salesOtherSku30d"
- "keywordId"
- "targeting"
- "keywordType"
reportTypeId: spPurchasedProduct
filters: []
timeUnit: DAILY
format: GZIP_JSON
incremental_sync_report_datetime_cursor:
type: DatetimeBasedCursor
@@ -2104,7 +2932,11 @@ definitions:
lookback_window: P{{ config.get('look_back_window', 3) }}D
start_datetime:
type: MinMaxDatetime
datetime: "{{ config.get('start_date', today_utc().strftime('%Y-%m-%d') ) }}"
datetime: >-
{%- set today = today_utc() - duration('P1D') -%}
{%- set user_start_date = config.get('start_date', today.strftime('%Y-%m-%d')) -%}
{%- set ninety_days_ago = today - duration('P90D') -%}
"{{ max(user_start_date, ninety_days_ago.strftime('%Y-%m-%d')) }}"
datetime_format: "%Y-%m-%d"
end_datetime:
datetime: "{{ today_utc() }}"
@@ -2178,7 +3010,12 @@ definitions:
Amazon-Advertising-API-ClientId: '{{ config["client_id"] }}'
request_body_json:
name: "purchasedAsin report {{ stream_interval.start_time }}"
startDate: "{{ stream_interval.start_time }}"
startDate: >
{% if stream_interval.start_time < config['start_date'] %}
{{ config['start_date'] }}
{% else %}
{{ stream_interval.start_time }}
{% endif %}
endDate: "{{ stream_interval.end_time }}"
configuration:
adProduct: OVERRIDDEN_REPORT_TYPE # Placeholder value. Each report stream overrides the adProduct value to the respective report name
@@ -2271,6 +3108,20 @@ streams:
- $ref: "#/definitions/streams/sponsored_products_asins_keywords_report_stream"
- $ref: "#/definitions/streams/sponsored_products_asins_targets_report_stream"
- $ref: "#/definitions/streams/sponsored_brands_v3_report_stream_daily"
- $ref: "#/definitions/streams/sponsored_display_campaigns_report_stream_daily"
- $ref: "#/definitions/streams/sponsored_display_adgroups_report_stream_daily"
- $ref: "#/definitions/streams/sponsored_display_productads_report_stream_daily"
- $ref: "#/definitions/streams/sponsored_display_targets_report_stream_daily"
- $ref: "#/definitions/streams/sponsored_display_asins_report_stream_daily"
- $ref: "#/definitions/streams/sponsored_products_campaigns_report_stream_daily"
- $ref: "#/definitions/streams/sponsored_products_adgroups_report_stream_daily"
- $ref: "#/definitions/streams/sponsored_products_keywords_report_stream_daily"
- $ref: "#/definitions/streams/sponsored_products_targets_report_stream_daily"
- $ref: "#/definitions/streams/sponsored_products_productads_report_stream_daily"
- $ref: "#/definitions/streams/sponsored_products_asins_keywords_report_stream_daily"
- $ref: "#/definitions/streams/sponsored_products_asins_targets_report_stream_daily"
concurrency_level:
type: ConcurrencyLevel
default_concurrency: 10

View File

@@ -0,0 +1,26 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"date": { "type": ["null", "string"] },
"profileId": { "type": ["null", "integer"] },
"reportDate": { "type": ["null", "string"] },
"attributionType": { "type": ["null", "string"] },
"campaignName": { "type": ["null", "string"] },
"newToBrandSales14d": { "type": ["null", "number"] },
"orders14d": { "type": ["null", "integer"] },
"productName": { "type": ["null", "string"] },
"sales14d": { "type": ["null", "number"] },
"newToBrandPurchasesPercentage14d": { "type": ["null", "number"] },
"purchasedAsin": { "type": ["null", "string"] },
"newToBrandSalesPercentage14d": { "type": ["null", "number"] },
"productCategory": { "type": ["null", "string"] },
"newToBrandPurchases14d": { "type": ["null", "integer"] },
"newToBrandUnitsSoldPercentage14d": { "type": ["null", "number"] },
"unitsSold14d": { "type": ["null", "integer"] },
"adGroupName": { "type": ["null", "string"] },
"newToBrandUnitsSold14d": { "type": ["null", "integer"] },
"campaignBudgetCurrencyCode": { "type": ["null", "string"] }
},
"title": "sponsored_brands_v3_report_stream_daily",
"type": ["null", "object"]
}

View File

@@ -0,0 +1,202 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"date": {
"type": ["null", "string"]
},
"profileId": {
"type": ["null", "integer"]
},
"reportDate": {
"type": ["null", "string"]
},
"adGroupId": {
"type": ["null", "integer"]
},
"addToCart": {
"type": ["null", "integer"]
},
"addToCartClicks": {
"type": ["null", "integer"]
},
"addToCartRate": {
"type": ["null", "number"]
},
"addToCartViews": {
"type": ["null", "integer"]
},
"adGroupName": {
"type": ["null", "string"]
},
"addToList": {
"type": ["null", "integer"]
},
"addToListFromClicks": {
"type": ["null", "integer"]
},
"addToListFromViews": {
"type": ["null", "integer"]
},
"qualifiedBorrows": {
"type": ["null", "integer"]
},
"qualifiedBorrowsFromClicks": {
"type": ["null", "integer"]
},
"qualifiedBorrowsFromViews": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrows": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrowsFromClicks": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrowsFromViews": {
"type": ["null", "integer"]
},
"bidOptimization": {
"type": ["null", "string"]
},
"brandedSearches": {
"type": ["null", "integer"]
},
"brandedSearchesClicks": {
"type": ["null", "integer"]
},
"brandedSearchesViews": {
"type": ["null", "integer"]
},
"brandedSearchRate": {
"type": ["null", "number"]
},
"campaignBudgetCurrencyCode": {
"type": ["null", "string"]
},
"campaignId": {
"type": ["null", "integer"]
},
"campaignName": {
"type": ["null", "string"]
},
"clicks": {
"type": ["null", "integer"]
},
"cost": {
"type": ["null", "number"]
},
"detailPageViews": {
"type": ["null", "integer"]
},
"detailPageViewsClicks": {
"type": ["null", "integer"]
},
"eCPAddToCart": {
"type": ["null", "number"]
},
"eCPBrandSearch": {
"type": ["null", "number"]
},
"impressions": {
"type": ["null", "integer"]
},
"impressionsViews": {
"type": ["null", "integer"]
},
"leadFormOpens": {
"type": ["null", "integer"]
},
"leads": {
"type": ["null", "integer"]
},
"linkOuts": {
"type": ["null", "integer"]
},
"newToBrandPurchases": {
"type": ["null", "integer"]
},
"newToBrandPurchasesClicks": {
"type": ["null", "integer"]
},
"newToBrandSales": {
"type": ["null", "number"]
},
"newToBrandSalesClicks": {
"type": ["null", "number"]
},
"newToBrandUnitsSold": {
"type": ["null", "integer"]
},
"newToBrandUnitsSoldClicks": {
"type": ["null", "integer"]
},
"purchases": {
"type": ["null", "integer"]
},
"purchasesClicks": {
"type": ["null", "integer"]
},
"purchasesPromotedClicks": {
"type": ["null", "integer"]
},
"sales": {
"type": ["null", "number"]
},
"salesClicks": {
"type": ["null", "number"]
},
"salesPromotedClicks": {
"type": ["null", "number"]
},
"unitsSold": {
"type": ["null", "integer"]
},
"unitsSoldClicks": {
"type": ["null", "integer"]
},
"videoCompleteViews": {
"type": ["null", "integer"]
},
"videoFirstQuartileViews": {
"type": ["null", "integer"]
},
"videoMidpointViews": {
"type": ["null", "integer"]
},
"videoThirdQuartileViews": {
"type": ["null", "integer"]
},
"videoUnmutes": {
"type": ["null", "integer"]
},
"viewabilityRate": {
"type": ["null", "number"]
},
"viewClickThroughRate": {
"type": ["null", "number"]
},
"cumulativeReach": {
"type": ["null", "string"]
},
"impressionsFrequencyAverage": {
"type": ["null", "number"]
},
"newToBrandDetailPageViewClicks": {
"type": ["null", "integer"]
},
"newToBrandDetailPageViewRate": {
"type": ["null", "number"]
},
"newToBrandDetailPageViews": {
"type": ["null", "integer"]
},
"newToBrandDetailPageViewViews": {
"type": ["null", "integer"]
},
"newToBrandECPDetailPageView": {
"type": ["null", "number"]
}
},
"title": "sponsored_display_adgroups_report_stream_daily",
"type": ["null", "object"]
}

View File

@@ -0,0 +1,86 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"date": {
"type": ["null", "string"]
},
"profileId": {
"type": ["null", "integer"]
},
"reportDate": {
"type": ["null", "string"]
},
"promotedAsin": {
"type": ["null", "string"]
},
"adGroupId": {
"type": ["null", "integer"]
},
"adGroupName": {
"type": ["null", "string"]
},
"asinBrandHalo": {
"type": ["null", "string"]
},
"addToList": {
"type": ["null", "integer"]
},
"addToListFromClicks": {
"type": ["null", "integer"]
},
"qualifiedBorrowsFromClicks": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrowsFromClicks": {
"type": ["null", "integer"]
},
"addToListFromViews": {
"type": ["null", "integer"]
},
"qualifiedBorrows": {
"type": ["null", "integer"]
},
"qualifiedBorrowsFromViews": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrows": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrowsFromViews": {
"type": ["null", "integer"]
},
"campaignBudgetCurrencyCode": {
"type": ["null", "string"]
},
"campaignId": {
"type": ["null", "integer"]
},
"campaignName": {
"type": ["null", "string"]
},
"conversionsBrandHalo": {
"type": ["null", "integer"]
},
"conversionsBrandHaloClicks": {
"type": ["null", "integer"]
},
"promotedSku": {
"type": ["null", "string"]
},
"salesBrandHalo": {
"type": ["null", "integer"]
},
"salesBrandHaloClicks": {
"type": ["null", "integer"]
},
"unitsSoldBrandHalo": {
"type": ["null", "integer"]
},
"unitsSoldBrandHaloClicks": {
"type": ["null", "integer"]
}
},
"title": "sponsored_display_asins_report_stream_daily",
"type": ["null", "object"]
}

View File

@@ -0,0 +1,202 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"date": {
"type": ["null", "string"]
},
"profileId": {
"type": ["null", "integer"]
},
"reportDate": {
"type": ["null", "string"]
},
"campaignId": {
"type": ["null", "integer"]
},
"addToCart": {
"type": ["null", "integer"]
},
"addToCartClicks": {
"type": ["null", "integer"]
},
"addToCartRate": {
"type": ["null", "number"]
},
"addToCartViews": {
"type": ["null", "integer"]
},
"addToList": {
"type": ["null", "integer"]
},
"addToListFromClicks": {
"type": ["null", "integer"]
},
"addToListFromViews": {
"type": ["null", "integer"]
},
"qualifiedBorrows": {
"type": ["null", "integer"]
},
"qualifiedBorrowsFromClicks": {
"type": ["null", "integer"]
},
"qualifiedBorrowsFromViews": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrows": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrowsFromClicks": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrowsFromViews": {
"type": ["null", "integer"]
},
"brandedSearches": {
"type": ["null", "integer"]
},
"brandedSearchesClicks": {
"type": ["null", "integer"]
},
"brandedSearchesViews": {
"type": ["null", "integer"]
},
"brandedSearchRate": {
"type": ["null", "number"]
},
"campaignBudgetCurrencyCode": {
"type": ["null", "string"]
},
"campaignName": {
"type": ["null", "string"]
},
"clicks": {
"type": ["null", "integer"]
},
"cost": {
"type": ["null", "number"]
},
"detailPageViews": {
"type": ["null", "integer"]
},
"detailPageViewsClicks": {
"type": ["null", "integer"]
},
"eCPAddToCart": {
"type": ["null", "number"]
},
"eCPBrandSearch": {
"type": ["null", "number"]
},
"impressions": {
"type": ["null", "integer"]
},
"impressionsViews": {
"type": ["null", "integer"]
},
"leadFormOpens": {
"type": ["null", "integer"]
},
"leads": {
"type": ["null", "integer"]
},
"linkOuts": {
"type": ["null", "integer"]
},
"newToBrandPurchases": {
"type": ["null", "integer"]
},
"newToBrandPurchasesClicks": {
"type": ["null", "integer"]
},
"newToBrandSalesClicks": {
"type": ["null", "number"]
},
"newToBrandUnitsSold": {
"type": ["null", "integer"]
},
"newToBrandUnitsSoldClicks": {
"type": ["null", "integer"]
},
"purchases": {
"type": ["null", "integer"]
},
"purchasesClicks": {
"type": ["null", "integer"]
},
"purchasesPromotedClicks": {
"type": ["null", "integer"]
},
"sales": {
"type": ["null", "number"]
},
"salesClicks": {
"type": ["null", "number"]
},
"salesPromotedClicks": {
"type": ["null", "number"]
},
"unitsSold": {
"type": ["null", "integer"]
},
"unitsSoldClicks": {
"type": ["null", "integer"]
},
"videoCompleteViews": {
"type": ["null", "integer"]
},
"videoFirstQuartileViews": {
"type": ["null", "integer"]
},
"videoMidpointViews": {
"type": ["null", "integer"]
},
"videoThirdQuartileViews": {
"type": ["null", "integer"]
},
"videoUnmutes": {
"type": ["null", "integer"]
},
"viewabilityRate": {
"type": ["null", "number"]
},
"viewClickThroughRate": {
"type": ["null", "number"]
},
"campaignBudgetAmount": {
"type": ["null", "number"]
},
"campaignStatus": {
"type": ["null", "string"]
},
"costType": {
"type": ["null", "string"]
},
"cumulativeReach": {
"type": ["null", "string"]
},
"impressionsFrequencyAverage": {
"type": ["null", "number"]
},
"newToBrandDetailPageViewClicks": {
"type": ["null", "integer"]
},
"newToBrandDetailPageViewRate": {
"type": ["null", "number"]
},
"newToBrandDetailPageViews": {
"type": ["null", "integer"]
},
"newToBrandDetailPageViewViews": {
"type": ["null", "integer"]
},
"newToBrandECPDetailPageView": {
"type": ["null", "number"]
},
"newToBrandSales": {
"type": ["null", "number"]
}
},
"title": "sponsored_display_campaigns_report_stream_daily",
"type": ["null", "object"]
}

View File

@@ -0,0 +1,212 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"date": {
"type": ["null", "string"]
},
"profileId": {
"type": ["null", "integer"]
},
"reportDate": {
"type": ["null", "string"]
},
"adId": {
"type": ["null", "integer"]
},
"addToCart": {
"type": ["null", "integer"]
},
"addToCartRate": {
"type": ["null", "number"]
},
"addToCartViews": {
"type": ["null", "integer"]
},
"addToCartClicks": {
"type": ["null", "integer"]
},
"adGroupId": {
"type": ["null", "integer"]
},
"adGroupName": {
"type": ["null", "string"]
},
"addToList": {
"type": ["null", "integer"]
},
"addToListFromClicks": {
"type": ["null", "integer"]
},
"qualifiedBorrows": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrows": {
"type": ["null", "integer"]
},
"addToListFromViews": {
"type": ["null", "integer"]
},
"qualifiedBorrowsFromClicks": {
"type": ["null", "integer"]
},
"qualifiedBorrowsFromViews": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrowsFromClicks": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrowsFromViews": {
"type": ["null", "integer"]
},
"bidOptimization": {
"type": ["null", "string"]
},
"brandedSearches": {
"type": ["null", "integer"]
},
"brandedSearchesClicks": {
"type": ["null", "integer"]
},
"brandedSearchesViews": {
"type": ["null", "integer"]
},
"brandedSearchRate": {
"type": ["null", "number"]
},
"campaignBudgetCurrencyCode": {
"type": ["null", "string"]
},
"campaignId": {
"type": ["null", "integer"]
},
"campaignName": {
"type": ["null", "string"]
},
"clicks": {
"type": ["null", "integer"]
},
"cost": {
"type": ["null", "number"]
},
"cumulativeReach": {
"type": ["null", "string"]
},
"detailPageViews": {
"type": ["null", "integer"]
},
"detailPageViewsClicks": {
"type": ["null", "integer"]
},
"eCPAddToCart": {
"type": ["null", "number"]
},
"eCPBrandSearch": {
"type": ["null", "number"]
},
"impressions": {
"type": ["null", "integer"]
},
"impressionsFrequencyAverage": {
"type": ["null", "number"]
},
"impressionsViews": {
"type": ["null", "integer"]
},
"leadFormOpens": {
"type": ["null", "integer"]
},
"leads": {
"type": ["null", "integer"]
},
"linkOuts": {
"type": ["null", "integer"]
},
"newToBrandDetailPageViewClicks": {
"type": ["null", "integer"]
},
"newToBrandDetailPageViewRate": {
"type": ["null", "number"]
},
"newToBrandDetailPageViews": {
"type": ["null", "integer"]
},
"newToBrandDetailPageViewViews": {
"type": ["null", "integer"]
},
"newToBrandECPDetailPageView": {
"type": ["null", "number"]
},
"newToBrandPurchases": {
"type": ["null", "integer"]
},
"newToBrandPurchasesClicks": {
"type": ["null", "integer"]
},
"newToBrandSales": {
"type": ["null", "number"]
},
"newToBrandSalesClicks": {
"type": ["null", "number"]
},
"newToBrandUnitsSold": {
"type": ["null", "integer"]
},
"newToBrandUnitsSoldClicks": {
"type": ["null", "integer"]
},
"promotedAsin": {
"type": ["null", "string"]
},
"promotedSku": {
"type": ["null", "string"]
},
"purchases": {
"type": ["null", "integer"]
},
"purchasesClicks": {
"type": ["null", "integer"]
},
"purchasesPromotedClicks": {
"type": ["null", "integer"]
},
"sales": {
"type": ["null", "number"]
},
"salesClicks": {
"type": ["null", "number"]
},
"salesPromotedClicks": {
"type": ["null", "number"]
},
"unitsSold": {
"type": ["null", "integer"]
},
"unitsSoldClicks": {
"type": ["null", "integer"]
},
"videoCompleteViews": {
"type": ["null", "integer"]
},
"videoFirstQuartileViews": {
"type": ["null", "integer"]
},
"videoMidpointViews": {
"type": ["null", "integer"]
},
"videoThirdQuartileViews": {
"type": ["null", "integer"]
},
"videoUnmutes": {
"type": ["null", "integer"]
},
"viewabilityRate": {
"type": ["null", "number"]
},
"viewClickThroughRate": {
"type": ["null", "number"]
}
},
"title": "sponsored_display_productads_report_stream_daily",
"type": ["null", "object"]
}

View File

@@ -0,0 +1,187 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"date": {
"type": ["null", "string"]
},
"properties": {
"profileId": {
"type": ["null", "integer"]
},
"reportDate": {
"type": ["null", "string"]
},
"targetingId": {
"type": ["null", "integer"]
},
"addToCart": {
"type": ["null", "integer"]
},
"addToCartClicks": {
"type": ["null", "integer"]
},
"addToCartRate": {
"type": ["null", "number"]
},
"addToCartViews": {
"type": ["null", "integer"]
},
"adGroupId": {
"type": ["null", "integer"]
},
"adGroupName": {
"type": ["null", "string"]
},
"addToList": {
"type": ["null", "integer"]
},
"addToListFromClicks": {
"type": ["null", "integer"]
},
"addToListFromViews": {
"type": ["null", "integer"]
},
"qualifiedBorrows": {
"type": ["null", "integer"]
},
"qualifiedBorrowsFromClicks": {
"type": ["null", "integer"]
},
"qualifiedBorrowsFromViews": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrows": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrowsFromClicks": {
"type": ["null", "integer"]
},
"royaltyQualifiedBorrowsFromViews": {
"type": ["null", "integer"]
},
"brandedSearches": {
"type": ["null", "integer"]
},
"brandedSearchesClicks": {
"type": ["null", "integer"]
},
"brandedSearchesViews": {
"type": ["null", "integer"]
},
"brandedSearchRate": {
"type": ["null", "number"]
},
"campaignBudgetCurrencyCode": {
"type": ["null", "string"]
},
"campaignId": {
"type": ["null", "integer"]
},
"campaignName": {
"type": ["null", "string"]
},
"clicks": {
"type": ["null", "integer"]
},
"cost": {
"type": ["null", "number"]
},
"detailPageViews": {
"type": ["null", "integer"]
},
"detailPageViewsClicks": {
"type": ["null", "integer"]
},
"eCPAddToCart": {
"type": ["null", "number"]
},
"eCPBrandSearch": {
"type": ["null", "number"]
},
"impressions": {
"type": ["null", "integer"]
},
"impressionsViews": {
"type": ["null", "integer"]
},
"leadFormOpens": {
"type": ["null", "integer"]
},
"leads": {
"type": ["null", "integer"]
},
"linkOuts": {
"type": ["null", "integer"]
},
"newToBrandPurchases": {
"type": ["null", "integer"]
},
"newToBrandPurchasesClicks": {
"type": ["null", "integer"]
},
"newToBrandSales": {
"type": ["null", "number"]
},
"newToBrandSalesClicks": {
"type": ["null", "number"]
},
"newToBrandUnitsSold": {
"type": ["null", "integer"]
},
"newToBrandUnitsSoldClicks": {
"type": ["null", "integer"]
},
"purchases": {
"type": ["null", "integer"]
},
"purchasesClicks": {
"type": ["null", "integer"]
},
"purchasesPromotedClicks": {
"type": ["null", "integer"]
},
"sales": {
"type": ["null", "number"]
},
"salesClicks": {
"type": ["null", "number"]
},
"salesPromotedClicks": {
"type": ["null", "number"]
},
"targetingExpression": {
"type": ["null", "string"]
},
"targetingText": {
"type": ["null", "string"]
},
"unitsSold": {
"type": ["null", "integer"]
},
"unitsSoldClicks": {
"type": ["null", "integer"]
},
"videoCompleteViews": {
"type": ["null", "integer"]
},
"videoFirstQuartileViews": {
"type": ["null", "integer"]
},
"videoMidpointViews": {
"type": ["null", "integer"]
},
"videoThirdQuartileViews": {
"type": ["null", "integer"]
},
"videoUnmutes": {
"type": ["null", "integer"]
},
"viewabilityRate": {
"type": ["null", "number"]
},
"viewClickThroughRate": {
"type": ["null", "number"]
}
},
"title": "sponsored_display_targets_report_stream_daily",
"type": ["null", "object"]
}

View File

@@ -0,0 +1,107 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"date": { "type": ["null", "string"] },
"profileId": {
"type": ["null", "integer"]
},
"reportDate": {
"type": ["null", "string"]
},
"adGroupId": {
"type": ["null", "integer"]
},
"campaignName": {
"type": ["null", "string"]
},
"campaignId": {
"type": ["null", "integer"]
},
"adGroupName": {
"type": ["null", "string"]
},
"impressions": {
"type": ["null", "integer"]
},
"clicks": {
"type": ["null", "integer"]
},
"cost": {
"type": ["null", "number"]
},
"purchases1d": {
"type": ["null", "integer"]
},
"purchases7d": {
"type": ["null", "integer"]
},
"purchases14d": {
"type": ["null", "integer"]
},
"purchases30d": {
"type": ["null", "integer"]
},
"purchasesSameSku1d": {
"type": ["null", "integer"]
},
"purchasesSameSku7d": {
"type": ["null", "integer"]
},
"purchasesSameSku14d": {
"type": ["null", "integer"]
},
"purchasesSameSku30d": {
"type": ["null", "integer"]
},
"unitsSoldClicks1d": {
"type": ["null", "integer"]
},
"unitsSoldClicks7d": {
"type": ["null", "integer"]
},
"unitsSoldClicks14d": {
"type": ["null", "integer"]
},
"unitsSoldClicks30d": {
"type": ["null", "integer"]
},
"sales1d": {
"type": ["null", "number"]
},
"sales7d": {
"type": ["null", "number"]
},
"sales14d": {
"type": ["null", "number"]
},
"sales30d": {
"type": ["null", "number"]
},
"attributedSalesSameSku1d": {
"type": ["null", "number"]
},
"attributedSalesSameSku7d": {
"type": ["null", "number"]
},
"attributedSalesSameSku14d": {
"type": ["null", "number"]
},
"attributedSalesSameSku30d": {
"type": ["null", "number"]
},
"unitsSoldSameSku1d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku7d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku14d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku30d": {
"type": ["null", "integer"]
}
},
"title": "sponsored_products_adgroups_report_stream_daily",
"type": ["null", "object"]
}

View File

@@ -0,0 +1,83 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"date": { "type": ["null", "string"] },
"profileId": {
"type": ["null", "integer"]
},
"reportDate": {
"type": ["null", "string"]
},
"advertisedAsin": {
"type": ["null", "string"]
},
"campaignName": {
"type": ["null", "string"]
},
"campaignId": {
"type": ["null", "integer"]
},
"adGroupName": {
"type": ["null", "string"]
},
"adGroupId": {
"type": ["null", "integer"]
},
"keywordId": {
"type": ["null", "integer"]
},
"keyword": {
"type": ["null", "string"]
},
"purchasedAsin": {
"type": ["null", "string"]
},
"advertisedSku": {
"type": ["null", "string"]
},
"campaignBudgetCurrencyCode": {
"type": ["null", "string"]
},
"matchType": {
"type": ["null", "string"]
},
"unitsSoldClicks1d": {
"type": ["null", "integer"]
},
"unitsSoldClicks7d": {
"type": ["null", "integer"]
},
"unitsSoldClicks14d": {
"type": ["null", "integer"]
},
"unitsSoldClicks30d": {
"type": ["null", "integer"]
},
"unitsSoldOtherSku1d": {
"type": ["null", "integer"]
},
"unitsSoldOtherSku7d": {
"type": ["null", "integer"]
},
"unitsSoldOtherSku14d": {
"type": ["null", "integer"]
},
"unitsSoldOtherSku30d": {
"type": ["null", "integer"]
},
"salesOtherSku1d": {
"type": ["null", "number"]
},
"salesOtherSku7d": {
"type": ["null", "number"]
},
"salesOtherSku14d": {
"type": ["null", "number"]
},
"salesOtherSku30d": {
"type": ["null", "number"]
}
},
"title": "sponsored_products_asins_keywords_report_stream_daily",
"type": ["null", "object"]
}

View File

@@ -0,0 +1,87 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"date": { "type": ["null", "string"] },
"profileId": {
"type": ["null", "integer"]
},
"reportDate": {
"type": ["null", "string"]
},
"advertisedAsin": {
"type": ["null", "string"]
},
"campaignName": {
"type": ["null", "string"]
},
"campaignId": {
"type": ["null", "integer"]
},
"adGroupName": {
"type": ["null", "string"]
},
"adGroupId": {
"type": ["null", "integer"]
},
"purchasedAsin": {
"type": ["null", "string"]
},
"advertisedSku": {
"type": ["null", "string"]
},
"campaignBudgetCurrencyCode": {
"type": ["null", "string"]
},
"matchType": {
"type": ["null", "string"]
},
"unitsSoldClicks1d": {
"type": ["null", "integer"]
},
"unitsSoldClicks7d": {
"type": ["null", "integer"]
},
"unitsSoldClicks14d": {
"type": ["null", "integer"]
},
"unitsSoldClicks30d": {
"type": ["null", "integer"]
},
"unitsSoldOtherSku1d": {
"type": ["null", "integer"]
},
"unitsSoldOtherSku7d": {
"type": ["null", "integer"]
},
"unitsSoldOtherSku14d": {
"type": ["null", "integer"]
},
"unitsSoldOtherSku30d": {
"type": ["null", "integer"]
},
"salesOtherSku1d": {
"type": ["null", "number"]
},
"salesOtherSku7d": {
"type": ["null", "number"]
},
"salesOtherSku14d": {
"type": ["null", "number"]
},
"salesOtherSku30d": {
"type": ["null", "number"]
},
"keywordId": {
"type": ["null", "integer"]
},
"targeting": {
"type": ["null", "string"]
},
"keywordType": {
"type": ["null", "string"]
}
},
"title": "sponsored_products_asins_targets_report_stream_daily",
"type": ["null", "object"]
}

View File

@@ -0,0 +1,116 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"date": { "type": ["null", "string"] },
"profileId": {
"type": ["null", "integer"]
},
"reportDate": {
"type": ["null", "string"]
},
"campaignId": {
"type": ["null", "integer"]
},
"campaignName": {
"type": ["null", "string"]
},
"campaignStatus": {
"type": ["null", "string"]
},
"campaignBudgetAmount": {
"type": ["null", "number"]
},
"campaignRuleBasedBudgetAmount": {
"type": ["null", "number"]
},
"campaignApplicableBudgetRuleId": {
"type": ["null", "string"]
},
"campaignApplicableBudgetRuleName": {
"type": ["null", "string"]
},
"impressions": {
"type": ["null", "integer"]
},
"clicks": {
"type": ["null", "integer"]
},
"cost": {
"type": ["null", "number"]
},
"purchases1d": {
"type": ["null", "integer"]
},
"purchases7d": {
"type": ["null", "integer"]
},
"purchases14d": {
"type": ["null", "integer"]
},
"purchases30d": {
"type": ["null", "integer"]
},
"purchasesSameSku1d": {
"type": ["null", "integer"]
},
"purchasesSameSku7d": {
"type": ["null", "integer"]
},
"purchasesSameSku14d": {
"type": ["null", "integer"]
},
"purchasesSameSku30d": {
"type": ["null", "integer"]
},
"unitsSoldClicks1d": {
"type": ["null", "integer"]
},
"unitsSoldClicks7d": {
"type": ["null", "integer"]
},
"unitsSoldClicks14d": {
"type": ["null", "integer"]
},
"unitsSoldClicks30d": {
"type": ["null", "integer"]
},
"sales1d": {
"type": ["null", "number"]
},
"sales7d": {
"type": ["null", "number"]
},
"sales14d": {
"type": ["null", "number"]
},
"sales30d": {
"type": ["null", "number"]
},
"attributedSalesSameSku1d": {
"type": ["null", "number"]
},
"attributedSalesSameSku7d": {
"type": ["null", "number"]
},
"attributedSalesSameSku14d": {
"type": ["null", "number"]
},
"attributedSalesSameSku30d": {
"type": ["null", "number"]
},
"unitsSoldSameSku1d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku7d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku14d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku30d": {
"type": ["null", "integer"]
}
},
"title": "sponsored_products_campaigns_report_stream_daily",
"type": ["null", "object"]
}

View File

@@ -0,0 +1,116 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"date": { "type": ["null", "string"] },
"profileId": {
"type": ["null", "integer"]
},
"reportDate": {
"type": ["null", "string"]
},
"keywordId": {
"type": ["null", "integer"]
},
"campaignName": {
"type": ["null", "string"]
},
"campaignId": {
"type": ["null", "integer"]
},
"adGroupName": {
"type": ["null", "string"]
},
"adGroupId": {
"type": ["null", "integer"]
},
"keyword": {
"type": ["null", "string"]
},
"matchType": {
"type": ["null", "string"]
},
"impressions": {
"type": ["null", "integer"]
},
"clicks": {
"type": ["null", "integer"]
},
"cost": {
"type": ["null", "number"]
},
"purchases1d": {
"type": ["null", "integer"]
},
"purchases7d": {
"type": ["null", "integer"]
},
"purchases14d": {
"type": ["null", "integer"]
},
"purchases30d": {
"type": ["null", "integer"]
},
"purchasesSameSku1d": {
"type": ["null", "integer"]
},
"purchasesSameSku7d": {
"type": ["null", "integer"]
},
"purchasesSameSku14d": {
"type": ["null", "integer"]
},
"purchasesSameSku30d": {
"type": ["null", "integer"]
},
"unitsSoldClicks1d": {
"type": ["null", "integer"]
},
"unitsSoldClicks7d": {
"type": ["null", "integer"]
},
"unitsSoldClicks14d": {
"type": ["null", "integer"]
},
"unitsSoldClicks30d": {
"type": ["null", "integer"]
},
"sales1d": {
"type": ["null", "number"]
},
"sales7d": {
"type": ["null", "number"]
},
"sales14d": {
"type": ["null", "number"]
},
"sales30d": {
"type": ["null", "number"]
},
"attributedSalesSameSku1d": {
"type": ["null", "number"]
},
"attributedSalesSameSku7d": {
"type": ["null", "number"]
},
"attributedSalesSameSku14d": {
"type": ["null", "number"]
},
"attributedSalesSameSku30d": {
"type": ["null", "number"]
},
"unitsSoldSameSku1d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku7d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku14d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku30d": {
"type": ["null", "integer"]
}
},
"title": "sponsored_products_keywords_report_stream_daily",
"type": ["null", "object"]
}

View File

@@ -0,0 +1,117 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"date": { "type": ["null", "string"] },
"profileId": {
"type": ["null", "integer"]
},
"reportDate": {
"type": ["null", "string"]
},
"adId": {
"type": ["null", "integer"]
},
"campaignName": {
"type": ["null", "string"]
},
"campaignId": {
"type": ["null", "integer"]
},
"adGroupName": {
"type": ["null", "string"]
},
"adGroupId": {
"type": ["null", "integer"]
},
"impressions": {
"type": ["null", "integer"]
},
"clicks": {
"type": ["null", "integer"]
},
"cost": {
"type": ["null", "number"]
},
"campaignBudgetCurrencyCode": {
"type": ["null", "string"]
},
"advertisedAsin": {
"type": ["null", "string"]
},
"purchases1d": {
"type": ["null", "integer"]
},
"purchases7d": {
"type": ["null", "integer"]
},
"purchases14d": {
"type": ["null", "integer"]
},
"purchases30d": {
"type": ["null", "integer"]
},
"purchasesSameSku1d": {
"type": ["null", "integer"]
},
"purchasesSameSku7d": {
"type": ["null", "integer"]
},
"purchasesSameSku14d": {
"type": ["null", "integer"]
},
"purchasesSameSku30d": {
"type": ["null", "integer"]
},
"unitsSoldClicks1d": {
"type": ["null", "integer"]
},
"unitsSoldClicks7d": {
"type": ["null", "integer"]
},
"unitsSoldClicks14d": {
"type": ["null", "integer"]
},
"unitsSoldClicks30d": {
"type": ["null", "integer"]
},
"sales1d": {
"type": ["null", "number"]
},
"sales7d": {
"type": ["null", "number"]
},
"sales14d": {
"type": ["null", "number"]
},
"sales30d": {
"type": ["null", "number"]
},
"attributedSalesSameSku1d": {
"type": ["null", "number"]
},
"attributedSalesSameSku7d": {
"type": ["null", "number"]
},
"attributedSalesSameSku14d": {
"type": ["null", "number"]
},
"attributedSalesSameSku30d": {
"type": ["null", "number"]
},
"unitsSoldSameSku1d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku7d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku14d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku30d": {
"type": ["null", "integer"]
}
},
"title": "sponsored_products_productads_report_stream_daily",
"type": ["null", "object"]
}

View File

@@ -0,0 +1,120 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"date": { "type": ["null", "string"] },
"profileId": {
"type": ["null", "integer"]
},
"reportDate": {
"type": ["null", "string"]
},
"keywordId": {
"type": ["null", "integer"]
},
"campaignName": {
"type": ["null", "string"]
},
"campaignId": {
"type": ["null", "integer"]
},
"adGroupName": {
"type": ["null", "string"]
},
"adGroupId": {
"type": ["null", "integer"]
},
"keyword": {
"type": ["null", "string"]
},
"targeting": {
"type": ["null", "string"]
},
"keywordType": {
"type": ["null", "string"]
},
"impressions": {
"type": ["null", "integer"]
},
"clicks": {
"type": ["null", "integer"]
},
"cost": {
"type": ["null", "number"]
},
"purchases1d": {
"type": ["null", "integer"]
},
"purchases7d": {
"type": ["null", "integer"]
},
"purchases14d": {
"type": ["null", "integer"]
},
"purchases30d": {
"type": ["null", "integer"]
},
"purchasesSameSku1d": {
"type": ["null", "integer"]
},
"purchasesSameSku7d": {
"type": ["null", "integer"]
},
"purchasesSameSku14d": {
"type": ["null", "integer"]
},
"purchasesSameSku30d": {
"type": ["null", "integer"]
},
"unitsSoldClicks1d": {
"type": ["null", "integer"]
},
"unitsSoldClicks7d": {
"type": ["null", "integer"]
},
"unitsSoldClicks14d": {
"type": ["null", "integer"]
},
"unitsSoldClicks30d": {
"type": ["null", "integer"]
},
"sales1d": {
"type": ["null", "number"]
},
"sales7d": {
"type": ["null", "number"]
},
"sales14d": {
"type": ["null", "number"]
},
"sales30d": {
"type": ["null", "number"]
},
"attributedSalesSameSku1d": {
"type": ["null", "number"]
},
"attributedSalesSameSku7d": {
"type": ["null", "number"]
},
"attributedSalesSameSku14d": {
"type": ["null", "number"]
},
"attributedSalesSameSku30d": {
"type": ["null", "number"]
},
"unitsSoldSameSku1d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku7d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku14d": {
"type": ["null", "integer"]
},
"unitsSoldSameSku30d": {
"type": ["null", "integer"]
}
},
"title": "sponsored_products_targets_report_stream_daily",
"type": ["null", "object"]
}

View File

@@ -1,114 +1,117 @@
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
# Copyright (c) 2025 Airbyte, Inc., all rights reserved.
import uuid
from unittest import TestCase
import gzip
from typing import Any, Mapping
import pendulum
import pytest
import requests_mock
from source_amazon_ads import SourceAmazonAds
from airbyte_cdk.models import Level as LogLevel
from airbyte_cdk.models import SyncMode
from airbyte_cdk.test.mock_http import HttpMocker, HttpRequestMatcher
from .ad_requests import (
OAuthRequestBuilder,
ProfilesRequestBuilder,
ReportCheckStatusRequestBuilder,
ReportDownloadRequestBuilder,
SponsoredBrandsV3ReportRequestBuilder,
SponsoredDisplayReportRequestBuilder,
SponsoredProductsReportRequestBuilder,
)
from .ad_responses import (
ErrorResponseBuilder,
OAuthResponseBuilder,
ProfilesResponseBuilder,
ReportCheckStatusResponseBuilder,
ReportDownloadResponseBuilder,
ReportInitResponseBuilder,
)
from .ad_responses.records import (
ErrorRecordBuilder,
ProfilesRecordBuilder,
ReportCheckStatusRecordBuilder,
ReportFileRecordBuilder,
ReportInitResponseRecordBuilder,
)
from .config import ConfigBuilder
from .metrics_map import BRANDS_METRICS_MAP_V3, DISPLAY_REPORT_METRICS_MAP, PRODUCTS_REPORT_METRICS_MAP
from .utils import get_log_messages_by_log_level, read_stream
from airbyte_cdk.test.catalog_builder import CatalogBuilder
from airbyte_cdk.test.entrypoint_wrapper import EntrypointOutput, read
from airbyte_cdk.test.state_builder import StateBuilder
class TestDisplayReportStreams(TestCase):
@property
def _config(self):
return ConfigBuilder().build()
# Fixture for the configuration with a valid region value
@pytest.fixture(name="config")
def config_fixture() -> Mapping[str, Any]:
return {
"client_id": "amzn.app-oa2-client.test",
"client_secret": "test-secret",
"refresh_token": "test-refresh-token",
"region": "NA",
"report_wait_timeout": 3600,
"report_generation_max_retry": 5,
}
def _given_oauth_and_profiles(self, http_mocker: HttpMocker, config: dict) -> None:
# Fixture to mock OAuth token endpoint
@pytest.fixture(name="mock_oauth")
def mock_oauth_fixture(requests_mock: requests_mock.Mocker) -> None:
requests_mock.post(
"https://api.amazon.com/auth/o2/token",
json={"access_token": "test-access-token", "token_type": "bearer", "expires_in": 3600},
status_code=200,
)
# Fixture to mock profiles endpoint
@pytest.fixture(name="mock_profiles")
def mock_profiles_fixture(requests_mock: requests_mock.Mocker) -> None:
requests_mock.get(
"https://advertising-api.amazon.com/v2/profiles?profileTypeFilter=seller,vendor",
json=[{"profileId": 1, "timezone": "UTC"}],
status_code=200,
request_headers={"Authorization": "Bearer test-access-token"},
)
def get_log_messages_by_log_level(logs, level: LogLevel) -> list:
"""Utility to extract log messages by log level."""
return [log.log.message for log in logs if log.type == "LOG" and log.log.level == level]
class TestDisplayReportStreams:
@staticmethod
def _read(config: Mapping[str, Any], stream_name: str, sync_mode: SyncMode = SyncMode.full_refresh) -> EntrypointOutput:
catalog = CatalogBuilder().with_stream(stream_name, sync_mode).build()
state = StateBuilder().build()
source = SourceAmazonAds(catalog, config, state)
return read(source, config, catalog, state)
def test_given_file_when_read_brands_v3_report_then_return_records(
self, requests_mock: requests_mock.Mocker, config: Mapping[str, Any], mock_oauth, mock_profiles
):
"""
Authenticate and get profiles
"""
http_mocker.post(
OAuthRequestBuilder.oauth_endpoint(
client_id=config["client_id"], client_secred=config["client_secret"], refresh_token=config["refresh_token"]
).build(),
OAuthResponseBuilder.token_response().build(),
)
http_mocker.get(
ProfilesRequestBuilder.profiles_endpoint(client_id=config["client_id"], client_access_token=config["access_token"]).build(),
ProfilesResponseBuilder.profiles_response().with_record(ProfilesRecordBuilder.profiles_record()).build(),
)
@HttpMocker()
def test_given_file_when_read_display_report_then_return_records(self, http_mocker):
"""
Check display report stream: normal stream read flow
In this test we prepare http mocker to handle all report types and tactics as well as workaround to handle gzipped file content
Check Sponsored Brands V3 report stream: normal stream read flow
In this test, we prepare HTTP mocks to handle report initiation, status checks, and file downloads.
Request structure:
1. Request report for start processing
2. Check status and get a download link
3. Download report file using the link
1. POST request to initiate report processing.
2. GET request to check report status and retrieve the download URL.
3. GET request to download the gzipped report file.
"""
self._given_oauth_and_profiles(http_mocker, self._config)
profile_timezone = ProfilesRecordBuilder.profiles_record().build().get("timezone")
start_date = pendulum.today(tz=profile_timezone).date()
for report_type, metrics in DISPLAY_REPORT_METRICS_MAP.items():
report_id = str(uuid.uuid4())
http_mocker.post(
SponsoredDisplayReportRequestBuilder._init_report_endpoint(
self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_type, metrics, start_date
).build(),
ReportInitResponseBuilder.report_init_response()
.with_record(ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id))
.with_status_code(200)
.build(),
)
download_request_builder = ReportDownloadRequestBuilder.download_endpoint(report_id)
http_mocker.get(
ReportCheckStatusRequestBuilder.check_sponsored_display_report_status_endpoint(
self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_id
).build(),
ReportCheckStatusResponseBuilder.check_status_response()
.with_record(ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url))
.build(),
)
# a workaround to pass compressed document to the mocked response
gzip_file_report_response = (
ReportDownloadResponseBuilder.download_report().with_record(ReportFileRecordBuilder.report_file_record()).build()
)
request_matcher = HttpRequestMatcher(download_request_builder.build(), minimum_number_of_expected_match=1)
http_mocker._matchers.append(request_matcher)
http_mocker._mocker.get(
requests_mock.ANY,
additional_matcher=http_mocker._matches_wrapper(request_matcher),
response_list=[{"content": gzip_file_report_response.body, "status_code": gzip_file_report_response.status_code}],
)
report_id = "report-id-brands-v3"
download_url = f"https://advertising-api.amazon.com/reporting/reports/{report_id}/download"
requests_mock.post(
"https://advertising-api.amazon.com/reporting/reports",
json={"reportId": report_id, "status": "PENDING"},
status_code=202,
request_headers={"Authorization": "Bearer test-access-token"},
)
requests_mock.get(
f"https://advertising-api.amazon.com/reporting/reports/{report_id}",
json={"status": "COMPLETED", "url": download_url},
status_code=200,
request_headers={"Authorization": "Bearer test-access-token"},
)
report_data = gzip.compress(b'[{"record": "data"}]')
requests_mock.get(
download_url,
content=report_data,
status_code=200,
)
output = self._read(config, "sponsored_brands_v3_report_stream", SyncMode.incremental)
start_date = pendulum.today(tz="UTC").date()
assert output.most_recent_state.stream_state.states == [
{"cursor": {"reportDate": start_date.format("YYYY-MM-DD")}, "partition": {"parent_slice": {}, "profileId": 1}}
]
assert len(output.records) == 1
def test_given_file_when_read_display_report_then_return_records(
self, requests_mock: requests_mock.Mocker, config: Mapping[str, Any], mock_oauth, mock_profiles
):
"""
Check display report streams: normal stream read flow for multiple streams
This test iterates over several Sponsored Display report streams, mocking the API responses for each.
It ensures that each stream can successfully initiate, check status, and download a report.
Request structure:
1. POST request to initiate report processing for each stream.
2. GET request to check report status and retrieve the download URL for each stream.
3. GET request to download the gzipped report file for each stream.
"""
number_of_records = 0
for stream_name in (
"sponsored_display_campaigns_report_stream",
@@ -117,59 +120,42 @@ class TestDisplayReportStreams(TestCase):
"sponsored_display_targets_report_stream",
"sponsored_display_asins_report_stream",
):
output = read_stream(stream_name, SyncMode.full_refresh, self._config)
report_id = f"report-id-display-{stream_name}"
download_url = f"https://advertising-api.amazon.com/reporting/reports/{report_id}/download"
requests_mock.post(
"https://advertising-api.amazon.com/reporting/reports",
json={"reportId": report_id, "status": "PENDING"},
status_code=202,
request_headers={"Authorization": "Bearer test-access-token"},
)
requests_mock.get(
f"https://advertising-api.amazon.com/reporting/reports/{report_id}",
json={"status": "COMPLETED", "url": download_url},
status_code=200,
request_headers={"Authorization": "Bearer test-access-token"},
)
report_data = gzip.compress(b'[{"record": "data"}]')
requests_mock.get(
download_url,
content=report_data,
status_code=200,
)
output = self._read(config, stream_name)
number_of_records += len(output.records)
assert number_of_records == 5
@HttpMocker()
def test_given_file_when_read_products_report_then_return_records(self, http_mocker):
def test_given_file_when_read_products_report_then_return_records(
self, requests_mock: requests_mock.Mocker, config: Mapping[str, Any], mock_oauth, mock_profiles
):
"""
Check products report stream: normal stream read flow.
In this test we prepare http mocker to handle all report types based on metrics defined for the report stream
as well as workaround to handle gzipped file content.
Check Sponsored Products report streams: normal stream read flow for multiple streams
This test iterates over several Sponsored Products report streams, mocking the API responses for each.
It ensures that each stream can successfully initiate, check status, and download a report.
Request structure:
1. Request report for start processing
2. Check status and get a download link
3. Download report file using the link
1. POST request to initiate report processing for each stream.
2. GET request to check report status and retrieve the download URL for each stream.
3. GET request to download the gzipped report file for each stream.
"""
self._given_oauth_and_profiles(http_mocker, self._config)
profile_timezone = ProfilesRecordBuilder.profiles_record().build().get("timezone")
start_date = pendulum.today(tz=profile_timezone).date()
for report_type, metrics in PRODUCTS_REPORT_METRICS_MAP.items():
report_id = str(uuid.uuid4())
http_mocker.post(
SponsoredProductsReportRequestBuilder._init_report_endpoint(
self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_type, metrics, start_date
).build(),
ReportInitResponseBuilder.report_init_response()
.with_record(ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id))
.with_status_code(200)
.build(),
)
download_request_builder = ReportDownloadRequestBuilder.download_endpoint(report_id)
http_mocker.get(
ReportCheckStatusRequestBuilder.check_sponsored_products_report_status_endpoint(
self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_id
).build(),
ReportCheckStatusResponseBuilder.check_status_response()
.with_record(ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url))
.build(),
)
# a workaround to pass compressed document to the mocked response
gzip_file_report_response = (
ReportDownloadResponseBuilder.download_report().with_record(ReportFileRecordBuilder.report_file_record()).build()
)
request_matcher = HttpRequestMatcher(download_request_builder.build(), minimum_number_of_expected_match=1)
http_mocker._matchers.append(request_matcher)
http_mocker._mocker.get(
requests_mock.ANY,
additional_matcher=http_mocker._matches_wrapper(request_matcher),
response_list=[{"content": gzip_file_report_response.body, "status_code": gzip_file_report_response.status_code}],
)
number_of_records = 0
for stream_name in (
"sponsored_products_campaigns_report_stream",
@@ -180,165 +166,171 @@ class TestDisplayReportStreams(TestCase):
"sponsored_products_asins_keywords_report_stream",
"sponsored_products_asins_targets_report_stream",
):
output = read_stream(stream_name, SyncMode.full_refresh, self._config)
report_id = f"report-id-products-{stream_name}"
download_url = f"https://advertising-api.amazon.com/reporting/reports/{report_id}/download"
requests_mock.post(
"https://advertising-api.amazon.com/reporting/reports",
json={"reportId": report_id, "status": "PENDING"},
status_code=202,
request_headers={"Authorization": "Bearer test-access-token"},
)
requests_mock.get(
f"https://advertising-api.amazon.com/reporting/reports/{report_id}",
json={"status": "COMPLETED", "url": download_url},
status_code=200,
request_headers={"Authorization": "Bearer test-access-token"},
)
report_data = gzip.compress(b'[{"record": "data"}]')
requests_mock.get(
download_url,
content=report_data,
status_code=200,
)
output = self._read(config, stream_name)
number_of_records += len(output.records)
assert number_of_records == 7
@HttpMocker()
def test_given_file_when_read_brands_v3_report_then_return_records(self, http_mocker):
def test_given_known_error_when_read_brands_v3_report_then_skip_report(
self, requests_mock: requests_mock.Mocker, config: Mapping[str, Any], mock_oauth, mock_profiles
):
"""
Check brands v3 report stream: normal stream read flow.
In this test we prepare http mocker to handle all report types based on metrics defined for the report stream
as well as workaround to handle gzipped file content.
Check error handling for Sponsored Brands V3 report stream
This test simulates known errors (400, 401, 406) by mocking API responses to return empty reports.
It verifies that the stream skips the report gracefully without logging warnings.
Request structure:
1. Request report for start processing
2. Check status and get a download link
3. Download report file using the link
1. POST request to initiate report processing.
2. GET request to check report status and retrieve the download URL.
3. GET request to download the gzipped empty report file.
"""
self._given_oauth_and_profiles(http_mocker, self._config)
profile_timezone = ProfilesRecordBuilder.profiles_record().build().get("timezone")
start_date = pendulum.today(tz=profile_timezone).date()
for report_type, metrics in BRANDS_METRICS_MAP_V3.items():
report_id = str(uuid.uuid4())
http_mocker.post(
SponsoredBrandsV3ReportRequestBuilder._init_report_endpoint(
self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_type, metrics, start_date
).build(),
ReportInitResponseBuilder.report_init_response()
.with_record(ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id))
.with_status_code(200)
.build(),
)
download_request_builder = ReportDownloadRequestBuilder.download_endpoint(report_id)
http_mocker.get(
ReportCheckStatusRequestBuilder.check_sponsored_brands_v3_report_status_endpoint(
self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_id
).build(),
ReportCheckStatusResponseBuilder.check_status_response()
.with_record(ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url))
.build(),
)
# a workaround to pass compressed document to the mocked response
gzip_file_report_response = (
ReportDownloadResponseBuilder.download_report().with_record(ReportFileRecordBuilder.report_file_record()).build()
)
request_matcher = HttpRequestMatcher(download_request_builder.build(), minimum_number_of_expected_match=1)
http_mocker._matchers.append(request_matcher)
http_mocker._mocker.get(
requests_mock.ANY,
additional_matcher=http_mocker._matches_wrapper(request_matcher),
response_list=[{"content": gzip_file_report_response.body, "status_code": gzip_file_report_response.status_code}],
)
output = read_stream("sponsored_brands_v3_report_stream", SyncMode.incremental, self._config)
# OLd format
# assert output.most_recent_state.stream_state == AirbyteStateBlob({"1": {"reportDate": start_date.format("YYYY-MM-DD")}})
assert output.most_recent_state.stream_state.states == [
{"cursor": {"reportDate": start_date.format("YYYY-MM-DD")}, "partition": {"parent_slice": {}, "profileId": 1}}
]
assert len(output.records) == 1
@HttpMocker()
def test_given_known_error_when_read_brands_v3_report_then_skip_report(self, http_mocker):
"""
Check brands v3 stream: non-breaking errors are ignored.
When error of this kind happen, we warn and then keep syncing another reports if possible.
In this test all report init requests are failed with known error and skipped
"""
ERRORS = [
(400, "KDP authors do not have access to Sponsored Brands functionality"),
(401, "Not authorized to access scope 0001"),
(406, "Report date is too far in the past."),
]
for status_code, msg in ERRORS:
self._given_oauth_and_profiles(http_mocker, self._config)
profile_timezone = ProfilesRecordBuilder.profiles_record().build().get("timezone")
start_date = pendulum.today(tz=profile_timezone).date()
non_breaking_error = ErrorRecordBuilder.non_breaking_error().with_error_message(msg)
for report_type, metrics in BRANDS_METRICS_MAP_V3.items():
http_mocker.post(
SponsoredBrandsV3ReportRequestBuilder._init_report_endpoint(
self._config["client_id"],
self._config["access_token"],
self._config["profiles"][0],
report_type,
metrics,
start_date,
).build(),
ErrorResponseBuilder.non_breaking_error_response()
.with_record(non_breaking_error)
.with_status_code(status_code)
.build(),
)
output = read_stream("sponsored_brands_v3_report_stream", SyncMode.full_refresh, self._config)
report_id = f"report-id-brands-v3-{status_code}"
download_url = f"https://advertising-api.amazon.com/reporting/reports/{report_id}/download"
requests_mock.post(
"https://advertising-api.amazon.com/reporting/reports",
json={"reportId": report_id, "status": "PENDING"},
status_code=202,
request_headers={"Authorization": "Bearer test-access-token"},
)
requests_mock.get(
f"https://advertising-api.amazon.com/reporting/reports/{report_id}",
json={"status": "COMPLETED", "url": download_url},
status_code=200,
request_headers={"Authorization": "Bearer test-access-token"},
)
report_data = gzip.compress(b"[]")
requests_mock.get(
download_url,
content=report_data,
status_code=200,
)
output = self._read(config, "sponsored_brands_v3_report_stream")
assert len(output.records) == 0
warning_logs = get_log_messages_by_log_level(output.logs, LogLevel.WARN)
expected_warning_log = f"Exception has occurred during job creation: {msg}"
assert any([expected_warning_log in warn for warn in warning_logs])
http_mocker.clear_all_matchers()
assert len(warning_logs) == 0
requests_mock.reset()
@HttpMocker()
def test_given_known_error_when_read_display_report_then_partially_skip_records(self, http_mocker):
def test_given_known_error_when_read_display_report_then_partially_skip_records(
self, requests_mock: requests_mock.Mocker, config: Mapping[str, Any], mock_oauth, mock_profiles
):
"""
Check display v3 stream: non-breaking errors are ignored.
When error of this kind happen, we warn and then keep syncing another reports if possible.
In this test half of report init requests are failed with known error and skipped while another half of reports successfully processed
Check partial error handling for Sponsored Display report streams
This test simulates errors for some streams by mocking empty reports for odd-indexed streams.
It ensures that the source skips failed streams gracefully while processing successful ones.
Request structure:
1. POST request to initiate report processing for each stream.
2. GET request to check report status and retrieve the download URL for each stream.
3. GET request to download the gzipped report file (data for even-indexed, empty for odd-indexed).
"""
self._given_oauth_and_profiles(http_mocker, self._config)
profile_timezone = ProfilesRecordBuilder.profiles_record().build().get("timezone")
start_date = pendulum.today(tz=profile_timezone).date()
for report_type, metrics in DISPLAY_REPORT_METRICS_MAP.items():
report_id = str(uuid.uuid4())
http_mocker.post(
SponsoredDisplayReportRequestBuilder._init_report_endpoint(
self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_type, metrics, start_date
).build(),
ReportInitResponseBuilder.report_init_response()
.with_record(ReportInitResponseRecordBuilder.init_response_record().with_status("PENDING").with_id(report_id))
.with_status_code(200)
.build(),
)
download_request_builder = ReportDownloadRequestBuilder.download_endpoint(report_id)
http_mocker.get(
ReportCheckStatusRequestBuilder.check_sponsored_display_report_status_endpoint(
self._config["client_id"], self._config["access_token"], self._config["profiles"][0], report_id
).build(),
ReportCheckStatusResponseBuilder.check_status_response()
.with_record(ReportCheckStatusRecordBuilder.status_record().with_status("COMPLETED").with_url(download_request_builder.url))
.build(),
)
# a workaround to pass compressed document to the mocked response
gzip_file_report_response = (
ReportDownloadResponseBuilder.download_report().with_record(ReportFileRecordBuilder.report_file_record()).build()
)
request_matcher = HttpRequestMatcher(download_request_builder.build(), minimum_number_of_expected_match=1)
http_mocker._matchers.append(request_matcher)
http_mocker._mocker.get(
requests_mock.ANY,
additional_matcher=http_mocker._matches_wrapper(request_matcher),
response_list=[{"content": gzip_file_report_response.body, "status_code": gzip_file_report_response.status_code}],
)
number_of_records = 0
for stream_name in (
streams = (
"sponsored_display_campaigns_report_stream",
"sponsored_display_adgroups_report_stream",
"sponsored_display_productads_report_stream",
"sponsored_display_targets_report_stream",
"sponsored_display_asins_report_stream",
):
output = read_stream(stream_name, SyncMode.full_refresh, self._config)
)
number_of_records = 0
for i, stream_name in enumerate(streams):
report_id = f"report-id-display-{stream_name}"
download_url = f"https://advertising-api.amazon.com/reporting/reports/{report_id}/download"
requests_mock.post(
"https://advertising-api.amazon.com/reporting/reports",
json={"reportId": report_id, "status": "PENDING"},
status_code=202,
request_headers={"Authorization": "Bearer test-access-token"},
)
requests_mock.get(
f"https://advertising-api.amazon.com/reporting/reports/{report_id}",
json={"status": "COMPLETED", "url": download_url},
status_code=200,
request_headers={"Authorization": "Bearer test-access-token"},
)
report_data = gzip.compress(b'[{"record": "data"}]') if i % 2 == 0 else gzip.compress(b"[]")
requests_mock.get(
download_url,
content=report_data,
status_code=200,
)
output = self._read(config, stream_name)
number_of_records += len(output.records)
assert number_of_records == 5
if i % 2 == 1:
warning_logs = get_log_messages_by_log_level(output.logs, LogLevel.WARN)
assert len(warning_logs) == 0
assert number_of_records == 3
@pytest.mark.parametrize(
"stream_name",
[
"sponsored_brands_v3_report_stream_daily",
"sponsored_display_campaigns_report_stream_daily",
"sponsored_display_adgroups_report_stream_daily",
"sponsored_display_productads_report_stream_daily",
"sponsored_display_targets_report_stream_daily",
"sponsored_display_asins_report_stream_daily",
"sponsored_products_campaigns_report_stream_daily",
"sponsored_products_adgroups_report_stream_daily",
"sponsored_products_keywords_report_stream_daily",
"sponsored_products_targets_report_stream_daily",
"sponsored_products_productads_report_stream_daily",
"sponsored_products_asins_keywords_report_stream_daily",
"sponsored_products_asins_targets_report_stream_daily",
],
)
def test_daily_stream(self, requests_mock, config, mock_oauth, mock_profiles, stream_name):
"""
Check daily report streams: parameterized test for all daily streams
This test verifies that each daily stream can fetch and process records with the 'date' field.
It uses HTTP mocks to simulate report initiation, status checks, and downloading gzipped daily data.
Request structure:
1. POST request to initiate report processing for the specified stream.
2. GET request to check report status and retrieve the download URL.
3. GET request to download the gzipped report file containing daily data.
"""
report_id = f"report-id-{stream_name}"
download_url = f"https://advertising-api.amazon.com/reporting/reports/{report_id}/download"
requests_mock.post(
"https://advertising-api.amazon.com/reporting/reports",
json={"reportId": report_id, "status": "PENDING"},
status_code=202,
request_headers={"Authorization": "Bearer test-access-token"},
)
requests_mock.get(
f"https://advertising-api.amazon.com/reporting/reports/{report_id}",
json={"status": "COMPLETED", "url": download_url},
status_code=200,
request_headers={"Authorization": "Bearer test-access-token"},
)
report_data = gzip.compress(b'[{"date": "2023-01-01", "record": "data1"}, {"date": "2023-01-02", "record": "data2"}]')
requests_mock.get(
download_url,
content=report_data,
status_code=200,
)
output = self._read(config, stream_name)
assert len(output.records) == 2
assert all("date" in record.record.data for record in output.records)
assert [record.record.data["date"] for record in output.records] == ["2023-01-01", "2023-01-02"]

View File

@@ -42,7 +42,7 @@ To use the [Amazon Ads API](https://advertising.amazon.com/API/docs/en-us), you
5. Click **Authenticate your Amazon Ads account**.
6. Log in and Authorize to the Amazon account.
7. Select **Region** to pull data from **North America (NA)**, **Europe (EU)**, **Far East (FE)**. See [docs](https://advertising.amazon.com/API/docs/en-us/info/api-overview#api-endpoints) for more details.
8. **Start Date (Optional)** is used for generating reports starting from the specified start date. This should be in YYYY-MM-DD format and not more than 60 days in the past. If a date is not specified, today's date is used. The date is treated in the timezone of the processed profile.
8. **Start Date (Optional)** is used for generating reports starting from the specified start date. This should be in YYYY-MM-DD format and not more than 90 days in the past. If a date is not specified, today's date is used. The date is treated in the timezone of the processed profile.
9. **Profile IDs (Optional)** you want to fetch data for. The Amazon Ads source connector supports only profiles with seller and vendor type, profiles with agency type will be ignored. See [docs](https://advertising.amazon.com/API/docs/en-us/concepts/authorization/profiles) for more details.
10. **Marketplace IDs (Optional)** you want to fetch data for. _Note: If Profile IDs are also selected, profiles will be selected if they match the Profile ID **OR** the Marketplace ID._
11. Click **Set up source**.
@@ -58,7 +58,7 @@ To use the [Amazon Ads API](https://advertising.amazon.com/API/docs/en-us), you
4. **Client Secret** of your Amazon Ads developer application. See [onboarding process](https://advertising.amazon.com/API/docs/en-us/setting-up/overview) for more details.
5. **Refresh Token**. See [onboarding process](https://advertising.amazon.com/API/docs/en-us/setting-up/overview) for more details.
6. Select **Region** to pull data from **North America (NA)**, **Europe (EU)**, **Far East (FE)**. See [docs](https://advertising.amazon.com/API/docs/en-us/info/api-overview#api-endpoints) for more details.
7. **Start Date (Optional)** is used for generating reports starting from the specified start date. This should be in YYYY-MM-DD format and not more than 60 days in the past. If a date is not specified, today's date is used. The date is treated in the timezone of the processed profile.
7. **Start Date (Optional)** is used for generating reports starting from the specified start date. This should be in YYYY-MM-DD format and not more than 90 days in the past. If a date is not specified, yesterday's date is used. The date is treated in the timezone of the processed profile.
8. **Profile IDs (Optional)** you want to fetch data for. The Amazon Ads source connector supports only profiles with seller and vendor type, profiles with agency type will be ignored. See [docs](https://advertising.amazon.com/API/docs/en-us/concepts/authorization/profiles) for more details.
9. **Marketplace IDs (Optional)** you want to fetch data for. _Note: If Profile IDs are also selected, profiles will be selected if they match the Profile ID **OR** the Marketplace ID._
10. Click **Set up source**.
@@ -72,7 +72,7 @@ To use the [Amazon Ads API](https://advertising.amazon.com/API/docs/en-us), you
2. **Client Secret** of your Amazon Ads developer application. See [onboarding process](https://advertising.amazon.com/API/docs/en-us/setting-up/overview) for more details.
3. **Refresh Token**. See [onboarding process](https://advertising.amazon.com/API/docs/en-us/setting-up/overview) for more details.
4. Select **Region** to pull data from **North America (NA)**, **Europe (EU)**, **Far East (FE)**. See [docs](https://advertising.amazon.com/API/docs/en-us/info/api-overview#api-endpoints) for more details.
5. **Start Date (Optional)** is used for generating reports starting from the specified start date. This should be in YYYY-MM-DD format and not more than 60 days in the past. If a date is not specified, today's date is used. The date is treated in the timezone of the processed profile.
5. **Start Date (Optional)** is used for generating reports starting from the specified start date. This should be in YYYY-MM-DD format and not more than 90 days in the past. If a date is not specified, today's date is used. The date is treated in the timezone of the processed profile.
6. **Profile IDs (Optional)** you want to fetch data for. The Amazon Ads source connector supports only profiles with seller and vendor type, profiles with agency type will be ignored. See [docs](https://advertising.amazon.com/API/docs/en-us/concepts/authorization/profiles) for more details.
7. **Marketplace IDs (Optional)** you want to fetch data for. _Note: If Profile IDs are also selected, profiles will be selected if they match the Profile ID **OR** the Marketplace ID._
<!-- /env:oss -->
@@ -129,8 +129,12 @@ All the reports are generated relative to the target profile's timezone.
Campaign reports may sometimes have no data or may not be presenting in records. This can occur when there are no clicks or views associated with the campaigns on the requested day - [details](https://advertising.amazon.com/API/docs/en-us/guides/reporting/v2/faq#why-is-my-report-empty).
Report data synchronization only covers the last 60 days - [details](https://advertising.amazon.com/API/docs/en-us/reference/1/reports#parameters).
Report data synchronization only covers the last 90 days - [details](https://advertising.amazon.com/API/docs/en-us/reference/1/reports#parameters).
:::note
The 'Reports' stream(s) by default will have `timeUnit` set to `SUMMARY`. If you would like more granularity, use the `_daily` versions of the report streams, which have
`timeUnit` set to `DAILY`. More info about this can be found [here](https://advertising.amazon.com/API/docs/en-us/guides/reporting/v3/get-started#timeunit-and-supported-columns).
:::
## Performance considerations
Information about expected report generation waiting time can be found [here](https://advertising.amazon.com/API/docs/en-us/get-started/developer-notes).
@@ -153,6 +157,7 @@ Information about expected report generation waiting time can be found [here](ht
| Version | Date | Pull Request | Subject |
|:--------|:-----------|:---------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 7.2.0-rc.1 | 2025-04-22 | [55217](https://github.com/airbytehq/airbyte/pull/55217) | Add `daily` versions of `reports` streams & Auto-update start_date if past lookback window|
| 7.1.7 | 2025-04-12 | [57591](https://github.com/airbytehq/airbyte/pull/57591) | Update dependencies |
| 7.1.6 | 2025-04-05 | [57138](https://github.com/airbytehq/airbyte/pull/57138) | Update dependencies |
| 7.1.5 | 2025-03-29 | [56554](https://github.com/airbytehq/airbyte/pull/56554) | Update dependencies |