diff --git a/airbyte-integrations/connectors/source-apple-search-ads-custom/README.md b/airbyte-integrations/connectors/source-apple-search-ads-custom/README.md
new file mode 100644
index 000000000000..5c65293a158e
--- /dev/null
+++ b/airbyte-integrations/connectors/source-apple-search-ads-custom/README.md
@@ -0,0 +1,33 @@
+# Apple Search Ads Custom
+This directory contains the manifest-only connector for `source-apple-search-ads-custom`.
+
+Update api to v5
+
+## Usage
+There are multiple ways to use this connector:
+- You can use this connector as any other connector in Airbyte Marketplace.
+- You can load this connector in `pyairbyte` using `get_source`!
+- You can open this connector in Connector Builder, edit it, and publish to your workspaces.
+
+Please refer to the manifest-only connector documentation for more details.
+
+## Local Development
+We recommend you use the Connector Builder to edit this connector.
+
+But, if you want to develop this connector locally, you can use the following steps.
+
+### Environment Setup
+You will need `airbyte-ci` installed. You can find the documentation [here](airbyte-ci).
+
+### Build
+This will create a dev image (`source-apple-search-ads-custom:dev`) that you can use to test the connector locally.
+```bash
+airbyte-ci connectors --name=source-apple-search-ads-custom build
+```
+
+### Test
+This will run the acceptance tests for the connector.
+```bash
+airbyte-ci connectors --name=source-apple-search-ads-custom test
+```
+
diff --git a/airbyte-integrations/connectors/source-apple-search-ads-custom/acceptance-test-config.yml b/airbyte-integrations/connectors/source-apple-search-ads-custom/acceptance-test-config.yml
new file mode 100644
index 000000000000..6e1e11841c09
--- /dev/null
+++ b/airbyte-integrations/connectors/source-apple-search-ads-custom/acceptance-test-config.yml
@@ -0,0 +1,17 @@
+# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference)
+# for more information about how to configure these tests
+connector_image: airbyte/source-apple-search-ads-custom:dev
+acceptance_tests:
+ spec:
+ tests:
+ - spec_path: "manifest.yaml"
+ connection:
+ bypass_reason: "This is a builder contribution, and we do not have secrets at this time"
+ discovery:
+ bypass_reason: "This is a builder contribution, and we do not have secrets at this time"
+ basic_read:
+ bypass_reason: "This is a builder contribution, and we do not have secrets at this time"
+ incremental:
+ bypass_reason: "This is a builder contribution, and we do not have secrets at this time"
+ full_refresh:
+ bypass_reason: "This is a builder contribution, and we do not have secrets at this time"
diff --git a/airbyte-integrations/connectors/source-apple-search-ads-custom/icon.svg b/airbyte-integrations/connectors/source-apple-search-ads-custom/icon.svg
new file mode 100644
index 000000000000..cf5618012c9a
--- /dev/null
+++ b/airbyte-integrations/connectors/source-apple-search-ads-custom/icon.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/airbyte-integrations/connectors/source-apple-search-ads-custom/manifest.yaml b/airbyte-integrations/connectors/source-apple-search-ads-custom/manifest.yaml
new file mode 100644
index 000000000000..dbe9e6291d28
--- /dev/null
+++ b/airbyte-integrations/connectors/source-apple-search-ads-custom/manifest.yaml
@@ -0,0 +1,1645 @@
+version: 6.1.0
+
+type: DeclarativeSource
+
+description: Update api to v5
+
+check:
+ type: CheckStream
+ stream_names:
+ - campaigns
+
+definitions:
+ streams:
+ adgroups:
+ type: DeclarativeStream
+ name: adgroups
+ selector:
+ extractor:
+ field_path:
+ - data
+ retriever:
+ type: SimpleRetriever
+ paginator:
+ type: DefaultPaginator
+ page_size_option:
+ type: RequestOption
+ field_name: limit
+ inject_into: request_parameter
+ page_token_option:
+ type: RequestOption
+ field_name: offset
+ inject_into: request_parameter
+ pagination_strategy:
+ type: OffsetIncrement
+ page_size: 1000
+ requester:
+ $ref: "#/definitions/base_requester"
+ path: /campaigns/{{ stream_slice.campaign_id }}/adgroups
+ http_method: GET
+ error_handler:
+ type: CompositeErrorHandler
+ error_handlers:
+ - type: DefaultErrorHandler
+ response_filters:
+ - type: HttpResponseFilter
+ action: RETRY
+ http_codes:
+ - 500
+ - 429
+ backoff_strategies:
+ - type: ExponentialBackoffStrategy
+ factor: 2
+ request_headers:
+ X-AP-Context: orgId={{ config.org_id }}
+ record_selector:
+ type: RecordSelector
+ extractor:
+ type: DpathExtractor
+ field_path:
+ - data
+ partition_router:
+ type: SubstreamPartitionRouter
+ parent_stream_configs:
+ - type: ParentStreamConfig
+ stream:
+ $ref: "#/definitions/streams/campaigns"
+ parent_key: id
+ partition_field: campaign_id
+ primary_key:
+ - id
+ schema_loader:
+ type: InlineSchemaLoader
+ schema:
+ $ref: "#/schemas/adgroups"
+ keywords:
+ type: DeclarativeStream
+ name: keywords
+ selector:
+ extractor:
+ field_path:
+ - data
+ retriever:
+ type: SimpleRetriever
+ paginator:
+ type: DefaultPaginator
+ page_size_option:
+ type: RequestOption
+ field_name: limit
+ inject_into: request_parameter
+ page_token_option:
+ type: RequestOption
+ field_name: offset
+ inject_into: request_parameter
+ pagination_strategy:
+ type: OffsetIncrement
+ page_size: 1000
+ requester:
+ $ref: "#/definitions/base_requester"
+ path: >-
+ /campaigns/{{ stream_slice.parent_slice.campaign_id }}/adgroups/{{
+ stream_slice.adgroup_id }}/targetingkeywords
+ http_method: GET
+ error_handler:
+ type: CompositeErrorHandler
+ error_handlers:
+ - type: DefaultErrorHandler
+ response_filters:
+ - type: HttpResponseFilter
+ action: RETRY
+ http_codes:
+ - 500
+ - 429
+ backoff_strategies:
+ - type: ExponentialBackoffStrategy
+ factor: 2
+ request_headers:
+ X-AP-Context: orgId={{ config.org_id }}
+ record_selector:
+ type: RecordSelector
+ extractor:
+ type: DpathExtractor
+ field_path:
+ - data
+ partition_router:
+ type: SubstreamPartitionRouter
+ parent_stream_configs:
+ - type: ParentStreamConfig
+ stream:
+ $ref: "#/definitions/streams/adgroups"
+ parent_key: id
+ partition_field: adgroup_id
+ primary_key:
+ - id
+ schema_loader:
+ type: InlineSchemaLoader
+ schema:
+ $ref: "#/schemas/keywords"
+ campaigns:
+ type: DeclarativeStream
+ name: campaigns
+ selector:
+ extractor:
+ field_path:
+ - data
+ retriever:
+ type: SimpleRetriever
+ paginator:
+ type: DefaultPaginator
+ page_size_option:
+ type: RequestOption
+ field_name: limit
+ inject_into: request_parameter
+ page_token_option:
+ type: RequestOption
+ field_name: offset
+ inject_into: request_parameter
+ pagination_strategy:
+ type: OffsetIncrement
+ page_size: 1000
+ requester:
+ $ref: "#/definitions/base_requester"
+ path: /campaigns
+ http_method: GET
+ error_handler:
+ type: CompositeErrorHandler
+ error_handlers:
+ - type: DefaultErrorHandler
+ response_filters:
+ - type: HttpResponseFilter
+ action: RETRY
+ http_codes:
+ - 500
+ - 429
+ backoff_strategies:
+ - type: ExponentialBackoffStrategy
+ factor: 2
+ request_headers:
+ X-AP-Context: orgId={{ config.org_id }}
+ record_selector:
+ type: RecordSelector
+ extractor:
+ type: DpathExtractor
+ field_path:
+ - data
+ primary_key:
+ - id
+ schema_loader:
+ type: InlineSchemaLoader
+ schema:
+ $ref: "#/schemas/campaigns"
+ adgroups_report_daily:
+ type: DeclarativeStream
+ name: adgroups_report_daily
+ selector:
+ extractor:
+ field_path:
+ - data
+ - reportingDataResponse
+ - row
+ retriever:
+ type: SimpleRetriever
+ paginator:
+ type: DefaultPaginator
+ page_size_option:
+ type: RequestOption
+ field_name: limit
+ inject_into: request_parameter
+ page_token_option:
+ type: RequestOption
+ field_name: offset
+ inject_into: request_parameter
+ pagination_strategy:
+ type: OffsetIncrement
+ page_size: 1000
+ requester:
+ $ref: "#/definitions/base_requester"
+ path: /reports/campaigns/{{ stream_slice.campaign_id }}/adgroups
+ http_method: POST
+ error_handler:
+ type: CompositeErrorHandler
+ error_handlers:
+ - type: DefaultErrorHandler
+ response_filters:
+ - type: HttpResponseFilter
+ action: RETRY
+ http_codes:
+ - 500
+ - 429
+ backoff_strategies:
+ - type: ExponentialBackoffStrategy
+ factor: 2
+ request_headers:
+ X-AP-Context: orgId={{ config.org_id }}
+ request_body_json:
+ endTime: "{{ stream_slice.end_time }}"
+ groupBy: "[ 'countryOrRegion' ]"
+ selector: >-
+ { "orderBy": [ { "field": "countryOrRegion", "sortOrder":
+ "ASCENDING" } ] }
+ timeZone: UTC
+ startTime: "{{ stream_slice.start_time }}"
+ granularity: "{{ parameters.granularity }}"
+ returnRowTotals: "true"
+ returnGrandTotals: "true"
+ record_selector:
+ type: RecordSelector
+ extractor:
+ type: DpathExtractor
+ field_path:
+ - data
+ - reportingDataResponse
+ - row
+ partition_router:
+ type: SubstreamPartitionRouter
+ parent_stream_configs:
+ - type: ParentStreamConfig
+ stream:
+ $ref: "#/definitions/streams/campaigns"
+ parent_key: id
+ partition_field: campaign_id
+ primary_key:
+ - date
+ - adGroupId
+ schema_loader:
+ type: InlineSchemaLoader
+ schema:
+ $ref: "#/schemas/adgroups_report_daily"
+ transformations:
+ - type: AddFields
+ fields:
+ - path:
+ - adGroupId
+ value: "{{ record.metadata.adGroupId }}"
+ - type: AddFields
+ fields:
+ - path:
+ - date
+ value: "{{ stream_slice.start_time }}"
+ incremental_sync:
+ type: DatetimeBasedCursor
+ step: P1D
+ cursor_field: date
+ end_datetime:
+ type: MinMaxDatetime
+ datetime: "{{ config.end_date or today_utc() }}"
+ datetime_format: "%Y-%m-%d"
+ start_datetime:
+ type: MinMaxDatetime
+ datetime: "{{ config.start_date }}"
+ datetime_format: "%Y-%m-%d"
+ datetime_format: "%Y-%m-%d"
+ lookback_window: P30D
+ cursor_granularity: P1D
+ cursor_datetime_formats:
+ - "%Y-%m-%d"
+ keywords_report_daily:
+ type: DeclarativeStream
+ name: keywords_report_daily
+ selector:
+ extractor:
+ field_path:
+ - data
+ - reportingDataResponse
+ - row
+ retriever:
+ type: SimpleRetriever
+ paginator:
+ type: DefaultPaginator
+ page_size_option:
+ type: RequestOption
+ field_name: limit
+ inject_into: request_parameter
+ page_token_option:
+ type: RequestOption
+ field_name: offset
+ inject_into: request_parameter
+ pagination_strategy:
+ type: OffsetIncrement
+ page_size: 1000
+ requester:
+ $ref: "#/definitions/base_requester"
+ path: /reports/campaigns/{{ stream_slice.campaign_id }}/keywords
+ http_method: POST
+ error_handler:
+ type: CompositeErrorHandler
+ error_handlers:
+ - type: DefaultErrorHandler
+ response_filters:
+ - type: HttpResponseFilter
+ action: RETRY
+ http_codes:
+ - 500
+ - 429
+ backoff_strategies:
+ - type: ExponentialBackoffStrategy
+ factor: 2
+ request_headers:
+ X-AP-Context: orgId={{ config.org_id }}
+ request_body_json:
+ endTime: "{{ stream_slice.end_time }}"
+ groupBy: "[ 'countryOrRegion' ]"
+ selector: >-
+ { "orderBy": [ { "field": "countryOrRegion", "sortOrder":
+ "ASCENDING" } ] }
+ timeZone: UTC
+ startTime: "{{ stream_slice.start_time }}"
+ granularity: "{{ parameters.granularity }}"
+ returnRowTotals: "true"
+ returnGrandTotals: "true"
+ record_selector:
+ type: RecordSelector
+ extractor:
+ type: DpathExtractor
+ field_path:
+ - data
+ - reportingDataResponse
+ - row
+ partition_router:
+ type: SubstreamPartitionRouter
+ parent_stream_configs:
+ - type: ParentStreamConfig
+ stream:
+ $ref: "#/definitions/streams/campaigns"
+ parent_key: id
+ partition_field: campaign_id
+ primary_key:
+ - date
+ - keywordId
+ schema_loader:
+ type: InlineSchemaLoader
+ schema:
+ $ref: "#/schemas/keywords_report_daily"
+ transformations:
+ - type: AddFields
+ fields:
+ - path:
+ - keywordId
+ value: "{{ record.metadata.keywordId }}"
+ - type: AddFields
+ fields:
+ - path:
+ - date
+ value: "{{ stream_slice.start_time }}"
+ incremental_sync:
+ type: DatetimeBasedCursor
+ step: P1D
+ cursor_field: date
+ end_datetime:
+ type: MinMaxDatetime
+ datetime: "{{ config.end_date or today_utc() }}"
+ datetime_format: "%Y-%m-%d"
+ start_datetime:
+ type: MinMaxDatetime
+ datetime: "{{ config.start_date }}"
+ datetime_format: "%Y-%m-%d"
+ datetime_format: "%Y-%m-%d"
+ lookback_window: P30D
+ cursor_granularity: P1D
+ cursor_datetime_formats:
+ - "%Y-%m-%d"
+ campaigns_report_daily:
+ type: DeclarativeStream
+ name: campaigns_report_daily
+ selector:
+ extractor:
+ field_path:
+ - data
+ - reportingDataResponse
+ - row
+ retriever:
+ type: SimpleRetriever
+ paginator:
+ type: DefaultPaginator
+ page_size_option:
+ type: RequestOption
+ field_name: limit
+ inject_into: request_parameter
+ page_token_option:
+ type: RequestOption
+ field_name: offset
+ inject_into: request_parameter
+ pagination_strategy:
+ type: OffsetIncrement
+ page_size: 1000
+ requester:
+ $ref: "#/definitions/base_requester"
+ path: /reports/campaigns
+ http_method: POST
+ error_handler:
+ type: CompositeErrorHandler
+ error_handlers:
+ - type: DefaultErrorHandler
+ response_filters:
+ - type: HttpResponseFilter
+ action: RETRY
+ http_codes:
+ - 500
+ - 429
+ backoff_strategies:
+ - type: ExponentialBackoffStrategy
+ factor: 2
+ request_headers:
+ X-AP-Context: orgId={{ config.org_id }}
+ request_body_json:
+ endTime: "{{ stream_slice.end_time }}"
+ groupBy: "[ 'countryOrRegion' ]"
+ selector: >-
+ { "orderBy": [ { "field": "countryOrRegion", "sortOrder":
+ "ASCENDING" } ] }
+ timeZone: UTC
+ startTime: "{{ stream_slice.start_time }}"
+ granularity: "{{ parameters.granularity }}"
+ returnRowTotals: "true"
+ returnGrandTotals: "true"
+ record_selector:
+ type: RecordSelector
+ extractor:
+ type: DpathExtractor
+ field_path:
+ - data
+ - reportingDataResponse
+ - row
+ primary_key:
+ - date
+ - campaignId
+ schema_loader:
+ type: InlineSchemaLoader
+ schema:
+ $ref: "#/schemas/campaigns_report_daily"
+ transformations:
+ - type: AddFields
+ fields:
+ - path:
+ - campaignId
+ value: "{{ record.metadata.campaignId }}"
+ - type: AddFields
+ fields:
+ - path:
+ - date
+ value: "{{ stream_slice.start_time }}"
+ incremental_sync:
+ type: DatetimeBasedCursor
+ step: P1D
+ cursor_field: date
+ end_datetime:
+ type: MinMaxDatetime
+ datetime: "{{ config.end_date or today_utc() }}"
+ datetime_format: "%Y-%m-%d"
+ start_datetime:
+ type: MinMaxDatetime
+ datetime: "{{ config.start_date }}"
+ datetime_format: "%Y-%m-%d"
+ datetime_format: "%Y-%m-%d"
+ lookback_window: P30D
+ cursor_granularity: P1D
+ cursor_datetime_formats:
+ - "%Y-%m-%d"
+ base_requester:
+ type: HttpRequester
+ url_base: https://api.searchads.apple.com/api/v5
+ authenticator:
+ type: OAuthAuthenticator
+ client_id: "{{ config.client_id }}"
+ grant_type: client_credentials
+ client_secret: "{{ config.client_secret }}"
+ token_refresh_endpoint: >-
+ https://appleid.apple.com/auth/oauth2/token?grant_type=client_credentials&scope=searchadsorg
+
+streams:
+ - $ref: "#/definitions/streams/campaigns"
+ - $ref: "#/definitions/streams/adgroups"
+ - $ref: "#/definitions/streams/keywords"
+ - $ref: "#/definitions/streams/campaigns_report_daily"
+ - $ref: "#/definitions/streams/adgroups_report_daily"
+ - $ref: "#/definitions/streams/keywords_report_daily"
+
+spec:
+ type: Spec
+ connection_specification:
+ type: object
+ $schema: http://json-schema.org/draft-07/schema#
+ required:
+ - org_id
+ - client_id
+ - start_date
+ - client_secret
+ properties:
+ org_id:
+ type: integer
+ description: >-
+ The identifier of the organization that owns the campaign. Your Org Id
+ is the same as your account in the Apple Search Ads UI.
+ order: 0
+ title: Org Id
+ end_date:
+ type: string
+ description: Data is retrieved until that date (included)
+ order: 1
+ title: End Date
+ pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}$
+ examples:
+ - "2021-01-01"
+ client_id:
+ type: string
+ description: >-
+ A user identifier for the token request. See here
+ order: 2
+ title: Client Id
+ airbyte_secret: true
+ start_date:
+ type: string
+ description: Start getting data from that date.
+ order: 3
+ title: Start Date
+ pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}$
+ examples:
+ - "2020-01-01"
+ client_secret:
+ type: string
+ description: >-
+ A string that authenticates the user’s setup request. See here
+ order: 4
+ title: Client Secret
+ airbyte_secret: true
+ additionalProperties: true
+
+metadata:
+ assist: {}
+ testedStreams:
+ adgroups:
+ hasRecords: true
+ streamHash: e8dfe90ac8da81ddc911285b96a9d5358b4cdc88
+ hasResponse: true
+ primaryKeysAreUnique: true
+ primaryKeysArePresent: true
+ responsesAreSuccessful: true
+ keywords:
+ hasRecords: true
+ streamHash: 0f7a53c234d0587d4d79d37961eaacbc3e9229c8
+ hasResponse: true
+ primaryKeysAreUnique: true
+ primaryKeysArePresent: true
+ responsesAreSuccessful: true
+ campaigns:
+ hasRecords: true
+ streamHash: 4bdacb2e6aa3f599de57b5c28821ebfb754f65e6
+ hasResponse: true
+ primaryKeysAreUnique: true
+ primaryKeysArePresent: true
+ responsesAreSuccessful: true
+ adgroups_report_daily:
+ hasRecords: true
+ streamHash: 68e04fd9d81f2d1b014a7ece6d5e4a3849d16331
+ hasResponse: true
+ primaryKeysAreUnique: true
+ primaryKeysArePresent: true
+ responsesAreSuccessful: true
+ keywords_report_daily:
+ hasRecords: true
+ streamHash: 5697c3787baae2b23fcba258e5ab3d5f9626b328
+ hasResponse: true
+ primaryKeysAreUnique: true
+ primaryKeysArePresent: true
+ responsesAreSuccessful: true
+ campaigns_report_daily:
+ hasRecords: true
+ streamHash: 064ace495001016049f80029ed354fe47a1aa5fa
+ hasResponse: true
+ primaryKeysAreUnique: true
+ primaryKeysArePresent: true
+ responsesAreSuccessful: true
+ yamlComponents:
+ global:
+ - authenticator
+ autoImportSchema:
+ adgroups: true
+ keywords: true
+ campaigns: true
+ adgroups_report_daily: true
+ keywords_report_daily: false
+ campaigns_report_daily: true
+
+schemas:
+ adgroups:
+ type: object
+ $schema: http://json-schema.org/schema#
+ required:
+ - id
+ properties:
+ id:
+ type: number
+ name:
+ type:
+ - string
+ - "null"
+ orgId:
+ type:
+ - number
+ - "null"
+ status:
+ type:
+ - string
+ - "null"
+ cpaGoal:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ deleted:
+ type:
+ - boolean
+ - "null"
+ startTime:
+ type:
+ - string
+ - "null"
+ campaignId:
+ type:
+ - number
+ - "null"
+ creationTime:
+ type:
+ - string
+ - "null"
+ pricingModel:
+ type:
+ - string
+ - "null"
+ displayStatus:
+ type:
+ - string
+ - "null"
+ servingStatus:
+ type:
+ - string
+ - "null"
+ defaultBidAmount:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ modificationTime:
+ type:
+ - string
+ - "null"
+ targetingDimensions:
+ type:
+ - object
+ - "null"
+ properties:
+ deviceClass:
+ type:
+ - object
+ - "null"
+ properties:
+ included:
+ type:
+ - array
+ - "null"
+ items:
+ type:
+ - string
+ - "null"
+ appCategories:
+ type:
+ - object
+ - "null"
+ properties: {}
+ appDownloaders:
+ type:
+ - object
+ - "null"
+ properties:
+ excluded:
+ type:
+ - array
+ - "null"
+ included:
+ type:
+ - array
+ - "null"
+ automatedKeywordsOptIn:
+ type:
+ - boolean
+ - "null"
+ additionalProperties: true
+ keywords:
+ type: object
+ $schema: http://json-schema.org/schema#
+ required:
+ - id
+ properties:
+ id:
+ type: number
+ text:
+ type:
+ - string
+ - "null"
+ status:
+ type:
+ - string
+ - "null"
+ deleted:
+ type:
+ - boolean
+ - "null"
+ adGroupId:
+ type:
+ - number
+ - "null"
+ bidAmount:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ matchType:
+ type:
+ - string
+ - "null"
+ campaignId:
+ type:
+ - number
+ - "null"
+ creationTime:
+ type:
+ - string
+ - "null"
+ modificationTime:
+ type:
+ - string
+ - "null"
+ additionalProperties: true
+ campaigns:
+ type: object
+ $schema: http://json-schema.org/schema#
+ required:
+ - id
+ properties:
+ id:
+ type: number
+ name:
+ type:
+ - string
+ - "null"
+ orgId:
+ type:
+ - number
+ - "null"
+ adamId:
+ type:
+ - number
+ - "null"
+ status:
+ type:
+ - string
+ - "null"
+ deleted:
+ type:
+ - boolean
+ - "null"
+ startTime:
+ type:
+ - string
+ - "null"
+ billingEvent:
+ type:
+ - string
+ - "null"
+ budgetAmount:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ budgetOrders:
+ type:
+ - array
+ - "null"
+ creationTime:
+ type:
+ - string
+ - "null"
+ paymentModel:
+ type:
+ - string
+ - "null"
+ adChannelType:
+ type:
+ - string
+ - "null"
+ displayStatus:
+ type:
+ - string
+ - "null"
+ servingStatus:
+ type:
+ - string
+ - "null"
+ supplySources:
+ type:
+ - array
+ - "null"
+ items:
+ type:
+ - string
+ - "null"
+ modificationTime:
+ type:
+ - string
+ - "null"
+ sapinLawResponse:
+ type:
+ - string
+ - "null"
+ dailyBudgetAmount:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ locInvoiceDetails:
+ type:
+ - object
+ - "null"
+ properties:
+ buyerName:
+ type:
+ - string
+ - "null"
+ buyerEmail:
+ type:
+ - string
+ - "null"
+ clientName:
+ type:
+ - string
+ - "null"
+ orderNumber:
+ type:
+ - string
+ - "null"
+ billingContactEmail:
+ type:
+ - string
+ - "null"
+ countriesOrRegions:
+ type:
+ - array
+ - "null"
+ items:
+ type:
+ - string
+ - "null"
+ servingStateReasons:
+ type:
+ - array
+ - "null"
+ items:
+ type:
+ - string
+ - "null"
+ countryOrRegionServingStateReasons:
+ type:
+ - object
+ - "null"
+ properties:
+ JP:
+ type:
+ - array
+ - "null"
+ items:
+ type:
+ - string
+ - "null"
+ KR:
+ type:
+ - array
+ - "null"
+ items:
+ type:
+ - string
+ - "null"
+ US:
+ type:
+ - array
+ - "null"
+ items:
+ type:
+ - string
+ - "null"
+ VN:
+ type:
+ - array
+ - "null"
+ items:
+ type:
+ - string
+ - "null"
+ additionalProperties: true
+ adgroups_report_daily:
+ type: object
+ $schema: http://json-schema.org/schema#
+ required:
+ - date
+ - adGroupId
+ properties:
+ metadata:
+ type:
+ - object
+ - "null"
+ properties:
+ orgId:
+ type:
+ - number
+ - "null"
+ deleted:
+ type:
+ - boolean
+ - "null"
+ adGroupId:
+ type:
+ - number
+ - "null"
+ startTime:
+ type:
+ - string
+ - "null"
+ campaignId:
+ type:
+ - number
+ - "null"
+ adGroupName:
+ type:
+ - string
+ - "null"
+ pricingModel:
+ type:
+ - string
+ - "null"
+ adGroupStatus:
+ type:
+ - string
+ - "null"
+ countryOrRegion:
+ type:
+ - string
+ - "null"
+ defaultBidAmount:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ modificationTime:
+ type:
+ - string
+ - "null"
+ adGroupDisplayStatus:
+ type:
+ - string
+ - "null"
+ adGroupServingStatus:
+ type:
+ - string
+ - "null"
+ automatedKeywordsOptIn:
+ type:
+ - boolean
+ - "null"
+ date:
+ type: string
+ other:
+ type:
+ - boolean
+ - "null"
+ total:
+ type:
+ - object
+ - "null"
+ properties:
+ ttr:
+ type:
+ - number
+ - "null"
+ taps:
+ type:
+ - number
+ - "null"
+ avgCPM:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ avgCPT:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ localSpend:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ impressions:
+ type:
+ - number
+ - "null"
+ tapInstalls:
+ type:
+ - number
+ - "null"
+ totalAvgCPI:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ viewInstalls:
+ type:
+ - number
+ - "null"
+ tapInstallCPI:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ totalInstalls:
+ type:
+ - number
+ - "null"
+ tapInstallRate:
+ type:
+ - number
+ - "null"
+ tapRedownloads:
+ type:
+ - number
+ - "null"
+ tapNewDownloads:
+ type:
+ - number
+ - "null"
+ viewRedownloads:
+ type:
+ - number
+ - "null"
+ totalInstallRate:
+ type:
+ - number
+ - "null"
+ totalRedownloads:
+ type:
+ - number
+ - "null"
+ viewNewDownloads:
+ type:
+ - number
+ - "null"
+ totalNewDownloads:
+ type:
+ - number
+ - "null"
+ adGroupId:
+ type: number
+ additionalProperties: true
+ keywords_report_daily:
+ type: object
+ $schema: http://json-schema.org/schema#
+ required:
+ - date
+ - keywordId
+ properties:
+ metadata:
+ type:
+ - object
+ - "null"
+ properties:
+ orgId:
+ type:
+ - number
+ - "null"
+ deleted:
+ type:
+ - boolean
+ - "null"
+ keyword:
+ type:
+ - string
+ - "null"
+ adGroupId:
+ type:
+ - number
+ - "null"
+ bidAmount:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ keywordId:
+ type:
+ - number
+ - "null"
+ matchType:
+ type:
+ - string
+ - "null"
+ campaignId:
+ type:
+ - number
+ - "null"
+ adGroupName:
+ type:
+ - string
+ - "null"
+ keywordStatus:
+ type:
+ - string
+ - "null"
+ adGroupDeleted:
+ type:
+ - boolean
+ - "null"
+ countryOrRegion:
+ type:
+ - string
+ - "null"
+ modificationTime:
+ type:
+ - string
+ - "null"
+ keywordDisplayStatus:
+ type:
+ - string
+ - "null"
+ date:
+ type: string
+ other:
+ type:
+ - boolean
+ - "null"
+ total:
+ type:
+ - object
+ - "null"
+ properties:
+ ttr:
+ type:
+ - number
+ - "null"
+ taps:
+ type:
+ - number
+ - "null"
+ avgCPT:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ localSpend:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ impressions:
+ type:
+ - number
+ - "null"
+ tapInstalls:
+ type:
+ - number
+ - "null"
+ totalAvgCPI:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ viewInstalls:
+ type:
+ - number
+ - "null"
+ tapInstallCPI:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ totalInstalls:
+ type:
+ - number
+ - "null"
+ tapInstallRate:
+ type:
+ - number
+ - "null"
+ tapRedownloads:
+ type:
+ - number
+ - "null"
+ tapNewDownloads:
+ type:
+ - number
+ - "null"
+ viewRedownloads:
+ type:
+ - number
+ - "null"
+ totalInstallRate:
+ type:
+ - number
+ - "null"
+ totalRedownloads:
+ type:
+ - number
+ - "null"
+ viewNewDownloads:
+ type:
+ - number
+ - "null"
+ totalNewDownloads:
+ type:
+ - number
+ - "null"
+ insights:
+ type:
+ - object
+ - "null"
+ properties:
+ bidRecommendation:
+ type:
+ - object
+ - "null"
+ properties: {}
+ keywordId:
+ type: number
+ additionalProperties: true
+ campaigns_report_daily:
+ type: object
+ $schema: http://json-schema.org/schema#
+ required:
+ - date
+ - campaignId
+ properties:
+ metadata:
+ type:
+ - object
+ - "null"
+ properties:
+ app:
+ type:
+ - object
+ - "null"
+ properties:
+ adamId:
+ type:
+ - number
+ - "null"
+ appName:
+ type:
+ - string
+ - "null"
+ orgId:
+ type:
+ - number
+ - "null"
+ deleted:
+ type:
+ - boolean
+ - "null"
+ campaignId:
+ type:
+ - number
+ - "null"
+ dailyBudget:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ billingEvent:
+ type:
+ - string
+ - "null"
+ campaignName:
+ type:
+ - string
+ - "null"
+ adChannelType:
+ type:
+ - string
+ - "null"
+ displayStatus:
+ type:
+ - string
+ - "null"
+ servingStatus:
+ type:
+ - string
+ - "null"
+ supplySources:
+ type:
+ - array
+ - "null"
+ items:
+ type:
+ - string
+ - "null"
+ campaignStatus:
+ type:
+ - string
+ - "null"
+ countryOrRegion:
+ type:
+ - string
+ - "null"
+ modificationTime:
+ type:
+ - string
+ - "null"
+ countriesOrRegions:
+ type:
+ - array
+ - "null"
+ items:
+ type:
+ - string
+ - "null"
+ servingStateReasons:
+ type:
+ - array
+ - "null"
+ items:
+ type:
+ - string
+ - "null"
+ countryOrRegionServingStateReasons:
+ type:
+ - object
+ - "null"
+ date:
+ type: string
+ other:
+ type:
+ - boolean
+ - "null"
+ total:
+ type:
+ - object
+ - "null"
+ properties:
+ ttr:
+ type:
+ - number
+ - "null"
+ taps:
+ type:
+ - number
+ - "null"
+ avgCPM:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ avgCPT:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ localSpend:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ impressions:
+ type:
+ - number
+ - "null"
+ tapInstalls:
+ type:
+ - number
+ - "null"
+ totalAvgCPI:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ viewInstalls:
+ type:
+ - number
+ - "null"
+ tapInstallCPI:
+ type:
+ - object
+ - "null"
+ properties:
+ amount:
+ type:
+ - string
+ - "null"
+ currency:
+ type:
+ - string
+ - "null"
+ totalInstalls:
+ type:
+ - number
+ - "null"
+ tapInstallRate:
+ type:
+ - number
+ - "null"
+ tapRedownloads:
+ type:
+ - number
+ - "null"
+ tapNewDownloads:
+ type:
+ - number
+ - "null"
+ viewRedownloads:
+ type:
+ - number
+ - "null"
+ totalInstallRate:
+ type:
+ - number
+ - "null"
+ totalRedownloads:
+ type:
+ - number
+ - "null"
+ viewNewDownloads:
+ type:
+ - number
+ - "null"
+ totalNewDownloads:
+ type:
+ - number
+ - "null"
+ campaignId:
+ type: number
+ additionalProperties: true
diff --git a/airbyte-integrations/connectors/source-apple-search-ads-custom/metadata.yaml b/airbyte-integrations/connectors/source-apple-search-ads-custom/metadata.yaml
new file mode 100644
index 000000000000..3497e4451559
--- /dev/null
+++ b/airbyte-integrations/connectors/source-apple-search-ads-custom/metadata.yaml
@@ -0,0 +1,35 @@
+metadataSpecVersion: "1.0"
+data:
+ allowedHosts:
+ hosts:
+ - "api.searchads.apple.com"
+ registryOverrides:
+ oss:
+ enabled: true
+ cloud:
+ enabled: true
+ remoteRegistries:
+ pypi:
+ enabled: false
+ packageName: airbyte-source-apple-search-ads-custom
+ connectorBuildOptions:
+ baseImage: docker.io/airbyte/source-declarative-manifest:6.9.2@sha256:ea8087899b36a891ce16e47035b10de8d52b0fb041b593b18e53ed2d699e3b46
+ connectorSubtype: api
+ connectorType: source
+ definitionId: a2c32418-3f7a-40e3-8378-2bcfc62aa298
+ dockerImageTag: 0.0.1
+ dockerRepository: airbyte/source-apple-search-ads-custom
+ githubIssueLabel: source-apple-search-ads-custom
+ icon: icon.svg
+ license: MIT
+ name: Apple Search Ads Custom
+ releaseDate: 2024-12-11
+ releaseStage: alpha
+ supportLevel: community
+ documentationUrl: https://docs.airbyte.com/integrations/sources/apple-search-ads-custom
+ tags:
+ - language:manifest-only
+ - cdk:low-code
+ ab_internal:
+ ql: 100
+ sl: 100
diff --git a/docs/integrations/sources/apple-search-ads-custom.md b/docs/integrations/sources/apple-search-ads-custom.md
new file mode 100644
index 000000000000..f2d73353a604
--- /dev/null
+++ b/docs/integrations/sources/apple-search-ads-custom.md
@@ -0,0 +1,33 @@
+# Apple Search Ads Custom
+Update api to v5
+
+## Configuration
+
+| Input | Type | Description | Default Value |
+|-------|------|-------------|---------------|
+| `org_id` | `integer` | Org Id. The identifier of the organization that owns the campaign. Your Org Id is the same as your account in the Apple Search Ads UI. | |
+| `end_date` | `string` | End Date. Data is retrieved until that date (included) | |
+| `client_id` | `string` | Client Id. A user identifier for the token request. See <a href="https://developer.apple.com/documentation/apple_search_ads/implementing_oauth_for_the_apple_search_ads_api">here</a> | |
+| `start_date` | `string` | Start Date. Start getting data from that date. | |
+| `client_secret` | `string` | Client Secret. A string that authenticates the user’s setup request. See <a href="https://developer.apple.com/documentation/apple_search_ads/implementing_oauth_for_the_apple_search_ads_api">here</a> | |
+
+## Streams
+| Stream Name | Primary Key | Pagination | Supports Full Sync | Supports Incremental |
+|-------------|-------------|------------|---------------------|----------------------|
+| campaigns | id | DefaultPaginator | ✅ | ❌ |
+| adgroups | id | DefaultPaginator | ✅ | ❌ |
+| keywords | id | DefaultPaginator | ✅ | ❌ |
+| campaigns_report_daily | date.campaignId | DefaultPaginator | ✅ | ✅ |
+| adgroups_report_daily | date.adGroupId | DefaultPaginator | ✅ | ✅ |
+| keywords_report_daily | date.keywordId | DefaultPaginator | ✅ | ✅ |
+
+## Changelog
+
+
+ Expand to review
+
+| Version | Date | Pull Request | Subject |
+|------------------|-------------------|--------------|----------------|
+| 0.0.1 | 2024-12-11 | | Initial release by [@canhhungit](https://github.com/canhhungit) via Connector Builder |
+
+