Skip to main content

TikTok Marketing

This page guides you through the process of setting up the TikTok Marketing source connector.

Prerequisites

For Airbyte Cloud:

  • A Tiktok Ads Business account with permission to access data from accounts you want to sync

For Airbyte Open Source: For the Production environment:

  • Access token
  • Secret
  • App ID

To access the Sandbox environment:

  • Access token
  • Advertiser ID

Setup guide

Step 1: Set up TikTok

  1. Create a TikTok For Business account: Link
  2. (Open source only) Create developer application: Link
  3. (Open source only) For a sandbox environment: create a Sandbox Ad Account Link

Step 2: Set up the source connector in Airbyte

For Airbyte Cloud:

  1. Log into your Airbyte Cloud account.
  2. In the left navigation bar, click Sources. In the top-right corner, click + new source.
  3. On the source setup page, select Tiktok Marketing from the Source type dropdown and enter a name for this connector.
  4. Select OAuth2.0 Authorization method, then click Authenticate your account.
  5. Log in and Authorize to the Tiktok account
  6. Choose required Start date
  7. click Set up source.

For Airbyte Open Source:

  1. Go to local Airbyte page.
  2. In the left navigation bar, click Sources. In the top-right corner, click + new source.
  3. On the Set up the source page, enter the name for the connector and select Tiktok Marketing from the Source type dropdown.
  4. Select Production Access Token or Sandbox Access Token Authorization method, then copy and paste info from step 1.
  5. Choose required Start date
  6. Click Set up source.

Supported streams and sync modes

StreamEnvironmentKeyIncremental
AdvertisersProd,Sandboxadvertiser_idNo
AdGroupsProd,Sandboxadgroup_idYes
AdsProd,Sandboxad_idYes
CampaignsProd,Sandboxcampaign_idYes
AdsReportsHourlyProd,Sandboxad_id, stat_time_hourYes
AdsReportsDailyProd,Sandboxad_id, stat_time_dayYes
AdsReportsLifetimeProd,Sandboxad_idNo
AdvertisersReportsHourlyProdadvertiser_id, stat_time_hourYes
AdvertisersReportsDailyProdadvertiser_id, stat_time_dayYes
AdvertisersReportsLifetimeProdadvertiser_idNo
AdGroupsReportsHourlyProd,Sandboxadgroup_id, stat_time_hourYes
AdGroupsReportsDailyProd,Sandboxadgroup_id, stat_time_dayYes
AdGroupsReportsLifetimeProd,Sandboxadgroup_idNo
AudiencesProd,Sandboxaudience_idNo
CampaignsReportsHourlyProd,Sandboxcampaign_id, stat_time_hourYes
CampaignsReportsDailyProd,Sandboxcampaign_id, stat_time_dayYes
CampaignsReportsLifetimeProd,Sandboxcampaign_idNo
CreativeAssetsImagesProd,Sandboximage_idYes
CreativeAssetsMusicProd,Sandboxmusic_idYes
CreativeAssetsPortfolioProd,Sandboxcreative_portfolio_idNo
CreativeAssetsVideoProd,Sandboxvideo_idYes
AdvertisersAudienceReportsDailyProdadvertiser_id, stat_time_day, gender, ageYes
AdvertisersAudienceReportsByCountryDailyProdadvertiser_id, stat_time_day, country_codeYes
AdvertisersAudienceReportsByPlatformDailyProdadvertiser_id, stat_time_day, platformYes
AdvertisersAudienceReportsLifetimeProdadvertiser_id, gender, ageNo
AdGroupAudienceReportsDailyProd,Sandboxadgroup_id, stat_time_day, gender, ageYes
AdGroupAudienceReportsByCountryDailyProd,Sandboxadgroup_id, stat_time_day, country_codeYes
AdGroupAudienceReportsByPlatformDailyProd,Sandboxadgroup_id, stat_time_day, platformYes
AdsAudienceReportsDailyProd,Sandboxad_id, stat_time_day, gender, ageYes
AdsAudienceReportsByCountryDailyProd,Sandboxad_id, stat_time_day, country_codeYes
AdsAudienceReportsByPlatformDailyProd,Sandboxad_id, stat_time_day, platformYes
CampaignsAudienceReportsDailyProd,Sandboxcampaign_id, stat_time_day, gender, ageYes
CampaignsAudienceReportsByCountryDailyProd,Sandboxcampaign_id, stat_time_day, country_codeYes
CampaignsAudienceReportsByPlatformDailyProd,Sandboxcampaign_id, stat_time_day, platformYes
info

TikTok Reporting API has some Data Latency, usually of about 11 hours. It is recommended to use higher values of attribution window (used in Incremental Syncs), at least 3 days, to ensure that the connector updates metrics in already presented records.

Report Aggregation

Reports synced by this connector can use either hourly, daily, or lifetime granularities for aggregating performance data. For example, if you select the daily-aggregation flavor of a report, the report will contain a row for each day for the duration of the report. Each row will indicate the number of impressions recorded on that day.

Output Schemas

Advertisers Stream

{
"contacter": "Ai***te",
"phonenumber": "+13*****5753",
"license_no": "",
"promotion_center_city": null,
"balance": 10,
"license_url": null,
"timezone": "Etc/GMT+8",
"reason": "",
"telephone": "+14*****6785",
"id": 7002238017842757633,
"language": "en",
"country": "US",
"role": "ROLE_ADVERTISER",
"license_province": null,
"display_timezone": "America/Los_Angeles",
"email": "i***************@**********",
"license_city": null,
"industry": "291905",
"create_time": 1630335591,
"promotion_center_province": null,
"address": "350 29th avenue, San Francisco",
"currency": "USD",
"promotion_area": "0",
"status": "STATUS_ENABLE",
"description": "https://",
"brand": null,
"name": "Airbyte0830",
"company": "Airbyte"
}

AdGroups Stream

{
"placement_type": "PLACEMENT_TYPE_AUTOMATIC",
"budget": 20,
"budget_mode": "BUDGET_MODE_DAY",
"display_mode": null,
"schedule_infos": null,
"billing_event": "CPC",
"conversion_window": null,
"adgroup_name": "Ad Group20211020010107",
"interest_keywords": [],
"is_comment_disable": 0,
"rf_buy_type": null,
"frequency": null,
"bid_type": "BID_TYPE_NO_BID",
"placement": null,
"bid": 0,
"include_custom_actions": [],
"operation_system": [],
"pixel_id": null,
"dayparting": "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
"app_type": null,
"conversion_id": 0,
"rf_predict_cpr": null,
"deep_bid_type": null,
"scheduled_budget": 0.0,
"adgroup_id": 1714125049901106,
"frequency_schedule": null,
"exclude_custom_actions": [],
"advertiser_id": 7002238017842757633,
"deep_cpabid": 0,
"is_new_structure": true,
"buy_impression": null,
"external_type": "WEBSITE",
"excluded_audience": [],
"deep_external_action": null,
"interest_category_v2": [],
"rf_predict_frequency": null,
"audience": [],
"pacing": "PACING_MODE_SMOOTH",
"brand_safety_partner": null,
"daily_retention_ratio": null,
"optimize_goal": "CLICK",
"enable_search_result": false,
"conversion_bid": 0,
"schedule_end_time": "2021-10-31 09:01:07",
"opt_status": "ENABLE",
"status": "ADGROUP_STATUS_CAMPAIGN_DISABLE",
"app_id": null,
"external_action": null,
"schedule_type": "SCHEDULE_START_END",
"brand_safety": "NO_BRAND_SAFETY",
"campaign_id": 1714125042508817,
"campaign_name": "Website Traffic20211020010104",
"split_test_adgroup_ids": [],
"action_v2": [],
"is_hfss": false,
"keywords": null,
"create_time": "2021-10-20 08:04:05",
"feed_type": null,
"languages": ["en"],
"enable_inventory_filter": false,
"device_price": [],
"location": [6252001],
"schedule_start_time": "2021-10-20 09:01:07",
"skip_learning_phase": 0,
"gender": "GENDER_UNLIMITED",
"creative_material_mode": "CUSTOM",
"app_download_url": null,
"device_models": [],
"automated_targeting": "OFF",
"connection_type": [],
"ios14_quota_type": "UNOCCUPIED",
"modify_time": "2022-03-24 12:06:54",
"category": 0,
"statistic_type": null,
"video_download": "ALLOW_DOWNLOAD",
"age": ["AGE_25_34", "AGE_35_44", "AGE_45_54"],
"buy_reach": null,
"is_share_disable": false
}

Ads Stream

{
"vast_moat": false,
"is_new_structure": true,
"campaign_name": "CampaignVadimTraffic",
"landing_page_urls": null,
"card_id": null,
"adgroup_id": 1728545385226289,
"campaign_id": 1728545382536225,
"status": "AD_STATUS_CAMPAIGN_DISABLE",
"brand_safety_postbid_partner": "UNSET",
"advertiser_id": 7002238017842757633,
"is_aco": false,
"ad_text": "Open-source\ndata integration for modern data teams",
"identity_id": "7080121820963422209",
"display_name": "airbyte",
"open_url": "",
"external_action": null,
"playable_url": "",
"create_time": "2022-03-28 12:09:09",
"product_ids": [],
"adgroup_name": "AdGroupVadim",
"fallback_type": "UNSET",
"creative_type": null,
"ad_name": "AdVadim-Optimized Version 3_202203281449_2022-03-28 05:03:44",
"video_id": "v10033g50000c90q1d3c77ub6e96fvo0",
"ad_format": "SINGLE_VIDEO",
"profile_image": "https://p21-ad-sg.ibyteimg.com/large/ad-site-i18n-sg/202203285d0de5c114d0690a462bb6a4",
"open_url_type": "NORMAL",
"click_tracking_url": null,
"page_id": null,
"ad_texts": null,
"landing_page_url": "https://airbyte.com",
"identity_type": "CUSTOMIZED_USER",
"avatar_icon_web_uri": "ad-site-i18n-sg/202203285d0de5c114d0690a462bb6a4",
"app_name": "",
"modify_time": "2022-03-28 21:34:26",
"opt_status": "ENABLE",
"call_to_action_id": "7080120957230238722",
"image_ids": ["v0201/7f371ff6f0764f8b8ef4f37d7b980d50"],
"ad_id": 1728545390695442,
"impression_tracking_url": null,
"is_creative_authorized": false
}

Campaigns Stream

{
"create_time": "2021-10-19 18:18:08",
"campaign_id": 1714073078669329,
"roas_bid": 0.0,
"advertiser_id": 7002238017842757633,
"modify_time": "2022-03-28 12:01:56",
"campaign_type": "REGULAR_CAMPAIGN",
"status": "CAMPAIGN_STATUS_DISABLE",
"objective_type": "TRAFFIC",
"split_test_variable": null,
"opt_status": "DISABLE",
"budget": 50,
"is_new_structure": true,
"deep_bid_type": null,
"campaign_name": "Website Traffic20211019110444",
"budget_mode": "BUDGET_MODE_DAY",
"objective": "LANDING_PAGE"
}

AdsReportsDaily Stream - BasicReports

{
"dimensions": {
"ad_id": 1728545390695442,
"stat_time_day": "2022-03-29 00:00:00"
},
"metrics": {
"real_time_result_rate": 0.93,
"campaign_id": 1728545382536225,
"placement": "Automatic Placement",
"frequency": 1.17,
"cpc": 0.35,
"ctr": 0.93,
"cost_per_result": 0.3509,
"impressions": 6137,
"cost_per_conversion": 0,
"real_time_result": 57,
"adgroup_id": 1728545385226289,
"result_rate": 0.93,
"cost_per_1000_reached": 3.801,
"ad_text": "Open-source\ndata integration for modern data teams",
"spend": 20,
"conversion_rate": 0,
"real_time_cost_per_conversion": 0,
"promotion_type": "Website",
"tt_app_id": 0,
"real_time_cost_per_result": 0.3509,
"conversion": 0,
"secondary_goal_result": null,
"campaign_name": "CampaignVadimTraffic",
"cpm": 3.26,
"result": 57,
"ad_name": "AdVadim-Optimized Version 3_202203281449_2022-03-28 05:03:44",
"secondary_goal_result_rate": null,
"clicks": 57,
"reach": 5262,
"cost_per_secondary_goal_result": null,
"real_time_conversion": 0,
"real_time_conversion_rate": 0,
"mobile_app_id": "0",
"tt_app_name": "0",
"adgroup_name": "AdGroupVadim",
"dpa_target_audience_type": null
}
}

AdvertisersReportsDaily Stream - BasicReports

{
"metrics": {
"cpm": 5.43,
"impressions": 3682,
"frequency": 1.17,
"reach": 3156,
"cash_spend": 20,
"ctr": 1.14,
"spend": 20,
"cpc": 0.48,
"cost_per_1000_reached": 6.337,
"clicks": 42,
"voucher_spend": 0
},
"dimensions": {
"stat_time_day": "2022-03-30 00:00:00",
"advertiser_id": 7002238017842757633
}
}

AdGroupsReportsDaily Stream - BasicReports

{
"metrics": {
"real_time_conversion": 0,
"real_time_cost_per_conversion": 0,
"cost_per_1000_reached": 3.801,
"mobile_app_id": "0",
"reach": 5262,
"cpm": 3.26,
"conversion": 0,
"promotion_type": "Website",
"clicks": 57,
"real_time_result_rate": 0.93,
"real_time_conversion_rate": 0,
"cost_per_conversion": 0,
"dpa_target_audience_type": null,
"result": 57,
"cpc": 0.35,
"impressions": 6137,
"cost_per_result": 0.3509,
"tt_app_id": 0,
"cost_per_secondary_goal_result": null,
"frequency": 1.17,
"spend": 20,
"secondary_goal_result_rate": null,
"real_time_cost_per_result": 0.3509,
"real_time_result": 57,
"placement": "Automatic Placement",
"result_rate": 0.93,
"tt_app_name": "0",
"campaign_name": "CampaignVadimTraffic",
"secondary_goal_result": null,
"campaign_id": 1728545382536225,
"conversion_rate": 0,
"ctr": 0.93,
"adgroup_name": "AdGroupVadim"
},
"dimensions": {
"adgroup_id": 1728545385226289,
"stat_time_day": "2022-03-29 00:00:00"
}
}

CampaignsReportsDaily Stream - BasicReports

{
"metrics": {
"cpc": 0.43,
"spend": 20,
"clicks": 46,
"cost_per_1000_reached": 4.002,
"impressions": 5870,
"ctr": 0.78,
"frequency": 1.17,
"cpm": 3.41,
"campaign_name": "CampaignVadimTraffic",
"reach": 4997
},
"dimensions": {
"campaign_id": 1728545382536225,
"stat_time_day": "2022-03-28 00:00:00"
}
}

AdsAudienceReportsDaily Stream - AudienceReports

{
{
"result": 17,
"clicks": 17,
"real_time_conversion_rate": 0,
"adgroup_id": 1728545385226289,
"cpm": 3.01,
"cost_per_result": 0.4165,
"real_time_cost_per_result": 0.4165,
"mobile_app_id": 0,
"spend": 7.08,
"cpc": 0.42,
"placement": "Automatic Placement",
"real_time_conversion": 0,
"dpa_target_audience_type": null,
"real_time_result_rate": 0.72,
"adgroup_name": "AdGroupVadim",
"tt_app_id": 0,
"ctr": 0.72,
"ad_text": "Open-source\ndata integration for modern data teams",
"result_rate": 0.72,
"ad_name": "AdVadim-Optimized Version 3_202203281449_2022-03-28 05:03:44",
"conversion_rate": 0,
"real_time_result": 17,
"tt_app_name": "0",
"cost_per_conversion": 0,
"real_time_cost_per_conversion": 0,
"conversion": 0,
"impressions": 2350,
"promotion_type": "Website",
"campaign_id": 1728545382536225,
"campaign_name": "CampaignVadimTraffic"
},
"dimensions": {
"gender": "MALE",
"age": "AGE_25_34",
"ad_id": 1728545390695442,
"stat_time_day": "2022-03-28 00:00:00"
}
}

AdvertisersAudienceReportsDaily Stream - AudienceReports

{
"dimensions": {
"stat_time_day": "2022-03-28 00:00:00",
"gender": "FEMALE",
"advertiser_id": 7002238017842757633,
"age": "AGE_35_44"
},
"metrics": {
"spend": 3.09,
"ctr": 0.93,
"cpc": 0.44,
"clicks": 7,
"cpm": 4.11,
"impressions": 752
}
}

AdGroupAudienceReportsDaily Stream - AudienceReports

{
"dimensions": {
"gender": "MALE",
"age": "AGE_25_34",
"stat_time_day": "2022-03-29 00:00:00",
"adgroup_id": 1728545385226289
},
"metrics": {
"cost_per_conversion": 0,
"campaign_id": 1728545382536225,
"campaign_name": "CampaignVadimTraffic",
"clicks": 20,
"dpa_target_audience_type": null,
"mobile_app_id": "0",
"promotion_type": "Website",
"conversion_rate": 0,
"cpm": 3.9,
"cost_per_result": 0.3525,
"cpc": 0.35,
"real_time_cost_per_conversion": 0,
"ctr": 1.11,
"spend": 7.05,
"result": 20,
"real_time_result": 20,
"impressions": 1806,
"conversion": 0,
"real_time_result_rate": 1.11,
"real_time_conversion_rate": 0,
"real_time_conversion": 0,
"adgroup_name": "AdGroupVadim",
"tt_app_name": "0",
"placement": "Automatic Placement",
"real_time_cost_per_result": 0.3525,
"result_rate": 1.11,
"tt_app_id": 0
}
}

CampaignsAudienceReportsByCountryDaily Stream - AudienceReports

{
"metrics": {
"impressions": 5870,
"campaign_name": "CampaignVadimTraffic",
"cpm": 3.41,
"clicks": 46,
"spend": 20,
"ctr": 0.78,
"cpc": 0.43
},
"dimensions": {
"stat_time_day": "2022-03-28 00:00:00",
"campaign_id": 1728545382536225,
"country_code": "US"
}
}

Performance considerations

The connector is restricted by requests limitation. This connector should not run into TikTok Marketing API limitations under normal usage. Please create an issue if you see any rate limit issues that are not automatically retried successfully.

Changelog

VersionDatePull RequestSubject
3.9.02023-10-2331623Add AdsAudienceReportsByProvince stream and expand base report metrics
3.8.02023-10-1931610Add Creative Assets and Audiences streams
3.7.12023-10-1931599Base image migration: remove Dockerfile and use the python-connector-base image
3.7.02023-10-1931493Add fields to Ads stream
3.6.02023-10-1831537Use default availability strategy
3.5.02023-10-1631445Apply minimum date restrictions
3.4.12023-08-0429083Added new is_smart_performance_campaign property to ad groups stream schema
3.4.02023-07-1327910Added include_deleted config param - include deleted ad_groups, ad, campaigns to reports
3.3.12023-07-0625423add new fields to ad reports streams
3.3.02023-07-0527988Add category_exclusion_ids field to ad_groups schema.
3.2.12023-05-2626569Fixed syncs with advertiser_id provided in input configuration
3.2.02023-05-2526565Change default value for attribution window to 3 days; add min/max validation
3.1.02023-05-1226024Updated the Ads stream schema
3.0.12023-04-0724712Added attribution window for *-reports streams
3.0.02023-03-2924630Migrate to v1.3 API
2.0.62023-03-3022134Add country_code and platform audience reports.
2.0.52023-03-2922863Specified date formatting in specification
2.0.42023-02-2322309Add Advertiser ID to filter reports and streams
2.0.32023-02-1523091Add more clear log message for 504 error
2.0.22023-02-0222309Chunk Advertiser IDs
2.0.12023-01-2722044Set AvailabilityStrategy for streams explicitly to None
2.0.02022-12-2020415Update schema types for AudienceReports and BasicReports streams.
1.0.12022-12-1620598Remove Audience Reports with Hourly granularity due to deprecated dimension.
1.0.02022-12-0519758Convert mobile_app_id from integer to string in AudienceReport streams.
0.1.172022-10-0417557Retry error 50002
0.1.162022-09-2817326Migrate to per-stream state
0.1.152022-08-3016137Fixed bug with normalization caused by unsupported nested cursor field
0.1.142022-06-2913890Removed granularity config option
0.1.132022-06-2813650Added video metrics to report streams
0.1.122022-05-2413127Fixed integration test
0.1.112022-04-2712838Added end date configuration for tiktok
0.1.102022-05-0712545Removed odd production authenication method
0.1.92022-04-3012500Improve input configuration copy
0.1.82022-04-2812435updated spec descriptions
0.1.72022-04-2712380fixed spec descriptions and documentation
0.1.62022-04-1911378updated logic for stream initializations, fixed errors in schemas, updated SAT and unit tests
0.1.52022-02-1710398Add Audience reports
0.1.42021-12-307636Add OAuth support
0.1.32021-12-108425Update title, description fields in spec
0.1.22021-12-028292Support reports
0.1.12021-11-087499Remove base-python dependencies
0.1.02021-09-185887Release TikTok Marketing CDK Connector