TikTok Ads
You authorise on TikTok's own platform and caOS registers whichever advertisers the authorisation returns. There is nothing to type, and no place to type an advertiser by hand either.
Start
Connectauthorise on the platform
Under Sources · Connect new source · TikTok Ads, the card opens TikTok's authorisation screen. The link is valid for 10 minutes and works once.
The window only closes after caOS has registered the advertisers, so there is no background step. Then tick the ones that belong to the workspace and apply a tag. Name and currency come from the API itself.
Whoever clicks must already have access to the advertiser in Business Center. caOS registers exactly what comes back in the response. If the account did not come, the fix is on TikTok's side, not on the caOS screen.
Your credential, and what happens to it
Connect once and you are connected. The credential renews itself, indefinitely. You do not need a date in the calendar and you do not need to reconnect periodically.
There is only one way the connection drops: someone revokes access on the platform side (password changed, person removed from the account, authorisation cancelled). The account then shows up under Lost connections and reconnecting fixes it, keeping the tags it already had.
Your credential is encrypted end to end. It is encrypted before it is stored, and the key does not live in the database, so even database access does not reveal it. Nobody at caOS, and not you either, can read the credential back after it is saved. The screen only shows that it exists and is valid.
Only the metrics you asked for are read. caOS does not write to your ad account in order to extract data, and it stores no personal data about who saw the ad. Processing follows Brazilian data protection law (LGPD), and deletion is yours: revoking the connection erases the stored credential.
Reference
Metrics and dimensionswhat each field means
TikTok splits metrics into tables by subject: the basic one carries spend and delivery, while video and engagement live in their own tables, joined by ad and day.
Core metrics11
| API field | What it is | Where it shows up |
|---|---|---|
| spend | How much was spent, in the account currency. | Spend in Pacer. |
| impressions | How many times the ad was shown. | Impressions. |
| clicks | Clicks through to the destination. | Clicks. |
| reach | Distinct people who saw the ad. | Reach. Do not sum it across days or ads. |
| frequency | Impressions per person. | Frequency. Pacer recomputes it as impressions ÷ reach for the period. |
| conversion | Attributed conversions. | There is also real_time_conversion, the version that is still going to move. |
| cost_per_conversion | Cost per conversion. | Recompute it from the sums if you are aggregating periods. |
| video_play_actions | Plays started: the video began playing. | Lives in the video table. This is the bigger number. |
| video_watched_2s | Watched 2 seconds. There is also 6 seconds. | Video table. |
| video_views_p100 | Watched to the end. Also 25, 50 and 75. | Video table. |
| likes | Likes. Comments, shares and follows come alongside. | Engagement table, separate from the basic one. |
Dimensions3
| API field | What it is | Where it shows up |
|---|---|---|
| stat_time_day | The day of the row. | Every metric table comes by day. |
| ad_id | The ad. | This is the key joining the basic, video and engagement tables. |
| advertiser_id | The advertiser. | Lives in the structure tables, not in the per-ad metric tables. |
Report parameters
The fields above say what comes back. These parameters say how: they decide the grain of the row, the period it covers and what counts as a conversion. Two reports from the same account showing different numbers almost always differ here.
| Parameter | What it changes | Values |
|---|---|---|
| report_type | Which family of metrics comes back. | BASIC brings performance; AUDIENCE brings age, gender and region. They are separate calls. |
| data_level | The grain of each row. | AUCTION_AD and AUCTION_CAMPAIGN. caOS extracts both, which is why there is an ad family and a campaign family. |
| service_type | Auction or reservation. | AUCTION. Media bought on reservation does not come through here. |
| dimensions | What each row is cut by. | ad_id or campaign_id, plus stat_time_day. Without the day dimension the API returns the running total. |
Everything you can pull
The tables above are what most reports use, but you are not stuck with them. The full TikTok catalogue has 20 tables and 841 fields, and you choose what goes in when you build the source. What is marked used by default is what the example source uses; the rest is available just the same.
The list below comes from the Xtractor catalogue itself, the same one the new source screen reads. If a field is here, the screen offers it.
ads_in_app_event_metrics_by_day176 fields
ad_id, stat_time_day, real_time_app_install, real_time_app_install_cost, app_install, cost_per_app_install, registration, cost_per_registration, registration_rate, total_registration, cost_per_total_registration, purchase, cost_per_purchase, purchase_rate, total_purchase, cost_per_total_purchase, value_per_total_purchase, total_purchase_value, total_active_pay_roas, app_event_add_to_cart, cost_per_app_event_add_to_cart, app_event_add_to_cart_rate, total_app_event_add_to_cart, cost_per_total_app_event_add_to_cart, value_per_total_app_event_add_to_cart, total_app_event_add_to_cart_value, checkout, cost_per_checkout, checkout_rate, total_checkout, cost_per_total_checkout, value_per_checkout, total_checkout_value, view_content, cost_per_view_content, view_content_rate, total_view_content, cost_per_total_view_content, value_per_total_view_content, total_view_content_value, next_day_open, cost_per_next_day_open, next_day_open_rate, total_next_day_open, cost_per_total_next_day_open, add_payment_info, cost_per_add_payment_info, add_payment_info_rate, total_add_payment_info, cost_total_add_payment_info, add_to_wishlist, cost_per_add_to_wishlist, add_to_wishlist_rate, total_add_to_wishlist, cost_per_total_add_to_wishlist, value_per_total_add_to_wishlist, total_add_to_wishlist_value, launch_app, cost_per_launch_app, launch_app_rate, total_launch_app, cost_per_total_launch_app, complete_tutorial, cost_per_complete_tutorial, complete_tutorial_rate, total_complete_tutorial, cost_per_total_complete_tutorial, value_per_total_complete_tutorial, total_complete_tutorial_value, create_group, cost_per_create_group, create_group_rate, total_create_group, cost_per_total_create_group, value_per_total_create_group, total_create_group_value, join_group, cost_per_join_group, join_group_rate, total_join_group, cost_per_total_join_group, value_per_total_join_group, total_join_group_value, create_gamerole, cost_per_create_gamerole, create_gamerole_rate, total_create_gamerole, cost_per_total_create_gamerole, value_per_total_create_gamerole, total_create_gamerole_value, spend_credits, cost_per_spend_credits, spend_credits_rate, total_spend_credits, cost_per_total_spend_credits, value_per_total_spend_credits, total_spend_credits_value, achieve_level, cost_per_achieve_level, achieve_level_rate, total_achieve_level, cost_per_total_achieve_level, value_per_total_achieve_level, total_achieve_level_value, unlock_achievement, cost_per_unlock_achievement, unlock_achievement_rate, total_unlock_achievement, cost_per_total_unlock_achievement, value_per_total_unlock_achievement, total_unlock_achievement_value, sales_lead, cost_per_sales_lead, sales_lead_rate, total_sales_lead, cost_per_total_sales_lead, value_per_total_sales_lead, total_sales_lead_value, in_app_ad_click, cost_per_in_app_ad_click, in_app_ad_click_rate, total_in_app_ad_click, cost_per_total_in_app_ad_click, value_per_total_in_app_ad_click, total_in_app_ad_click_value, in_app_ad_impr, cost_per_in_app_ad_impr, in_app_ad_impr_rate, total_in_app_ad_impr, cost_per_total_in_app_ad_impr, value_per_total_in_app_ad_impr, total_in_app_ad_impr_value, loan_apply, cost_per_loan_apply, loan_apply_rate, total_loan_apply, cost_per_total_loan_apply, loan_credit, cost_per_loan_credit, loan_credit_rate, total_loan_credit, cost_per_total_loan_credit, loan_disbursement, cost_per_loan_disbursement, loan_disbursement_rate, total_loan_disbursement, cost_per_total_loan_disbursement, login, cost_per_login, login_rate, total_login, cost_per_total_login, ratings, cost_per_ratings, ratings_rate, total_ratings, cost_per_total_ratings, value_per_total_ratings, total_ratings_value, search, cost_per_search, search_rate, total_search, cost_per_total_search, start_trial, cost_per_start_trial, start_trial_rate, total_start_trial, cost_per_total_start_trial, subscribe, cost_per_subscribe, subscribe_rate, total_subscribe, cost_per_total_subscribe, value_per_total_subscribe, total_subscribe_value
campaigns_in_app_event_metrics_by_day176 fields
campaign_id, stat_time_day, real_time_app_install, real_time_app_install_cost, app_install, cost_per_app_install, registration, cost_per_registration, registration_rate, total_registration, cost_per_total_registration, purchase, cost_per_purchase, purchase_rate, total_purchase, cost_per_total_purchase, value_per_total_purchase, total_purchase_value, total_active_pay_roas, app_event_add_to_cart, cost_per_app_event_add_to_cart, app_event_add_to_cart_rate, total_app_event_add_to_cart, cost_per_total_app_event_add_to_cart, value_per_total_app_event_add_to_cart, total_app_event_add_to_cart_value, checkout, cost_per_checkout, checkout_rate, total_checkout, cost_per_total_checkout, value_per_checkout, total_checkout_value, view_content, cost_per_view_content, view_content_rate, total_view_content, cost_per_total_view_content, value_per_total_view_content, total_view_content_value, next_day_open, cost_per_next_day_open, next_day_open_rate, total_next_day_open, cost_per_total_next_day_open, add_payment_info, cost_per_add_payment_info, add_payment_info_rate, total_add_payment_info, cost_total_add_payment_info, add_to_wishlist, cost_per_add_to_wishlist, add_to_wishlist_rate, total_add_to_wishlist, cost_per_total_add_to_wishlist, value_per_total_add_to_wishlist, total_add_to_wishlist_value, launch_app, cost_per_launch_app, launch_app_rate, total_launch_app, cost_per_total_launch_app, complete_tutorial, cost_per_complete_tutorial, complete_tutorial_rate, total_complete_tutorial, cost_per_total_complete_tutorial, value_per_total_complete_tutorial, total_complete_tutorial_value, create_group, cost_per_create_group, create_group_rate, total_create_group, cost_per_total_create_group, value_per_total_create_group, total_create_group_value, join_group, cost_per_join_group, join_group_rate, total_join_group, cost_per_total_join_group, value_per_total_join_group, total_join_group_value, create_gamerole, cost_per_create_gamerole, create_gamerole_rate, total_create_gamerole, cost_per_total_create_gamerole, value_per_total_create_gamerole, total_create_gamerole_value, spend_credits, cost_per_spend_credits, spend_credits_rate, total_spend_credits, cost_per_total_spend_credits, value_per_total_spend_credits, total_spend_credits_value, achieve_level, cost_per_achieve_level, achieve_level_rate, total_achieve_level, cost_per_total_achieve_level, value_per_total_achieve_level, total_achieve_level_value, unlock_achievement, cost_per_unlock_achievement, unlock_achievement_rate, total_unlock_achievement, cost_per_total_unlock_achievement, value_per_total_unlock_achievement, total_unlock_achievement_value, sales_lead, cost_per_sales_lead, sales_lead_rate, total_sales_lead, cost_per_total_sales_lead, value_per_total_sales_lead, total_sales_lead_value, in_app_ad_click, cost_per_in_app_ad_click, in_app_ad_click_rate, total_in_app_ad_click, cost_per_total_in_app_ad_click, value_per_total_in_app_ad_click, total_in_app_ad_click_value, in_app_ad_impr, cost_per_in_app_ad_impr, in_app_ad_impr_rate, total_in_app_ad_impr, cost_per_total_in_app_ad_impr, value_per_total_in_app_ad_impr, total_in_app_ad_impr_value, loan_apply, cost_per_loan_apply, loan_apply_rate, total_loan_apply, cost_per_total_loan_apply, loan_credit, cost_per_loan_credit, loan_credit_rate, total_loan_credit, cost_per_total_loan_credit, loan_disbursement, cost_per_loan_disbursement, loan_disbursement_rate, total_loan_disbursement, cost_per_total_loan_disbursement, login, cost_per_login, login_rate, total_login, cost_per_total_login, ratings, cost_per_ratings, ratings_rate, total_ratings, cost_per_total_ratings, value_per_total_ratings, total_ratings_value, search, cost_per_search, search_rate, total_search, cost_per_total_search, start_trial, cost_per_start_trial, start_trial_rate, total_start_trial, cost_per_total_start_trial, subscribe, cost_per_subscribe, subscribe_rate, total_subscribe, cost_per_total_subscribe, value_per_total_subscribe, total_subscribe_value
ad_groups78 fields
adgroup_id, age, display_mode, operation_system, creative_material_mode, excluded_audience, optimize_goal, budget_mode, brand_safety_partner, enable_inventory_filter, conversion_bid, interest_keywords, scheduled_budget, deep_external_action, modify_time, placement_type, is_comment_disable, audience, schedule_end_time, brand_safety, daily_retention_ratio, languages, rf_predict_cpr, deep_bid_type, skip_learning_phase, rf_predict_frequency, external_type, gender, category, pixel_id, frequency_schedule, keywords, enable_search_result, bid, app_type, app_download_url, create_time, frequency, include_custom_actions, ios14_quota_type, bid_type, app_id, split_test_adgroup_ids, advertiser_id, buy_reach, dayparting, buy_impression, automated_targeting, pacing, statistic_type, is_hfss, conversion_id, campaign_name, rf_buy_type, device_models, campaign_id, device_price, schedule_start_time, placement, opt_status, status, external_action, conversion_window, adgroup_name, billing_event, location, budget, video_download, deep_cpabid, is_share_disable, feed_type, schedule_infos, exclude_custom_actions, action_v2, is_new_structure, schedule_type, interest_category_v2, connection_type
ads_page_event_metrics_by_day78 fields
ad_id, stat_time_day, complete_payment_roas, complete_payment, cost_per_complete_payment, complete_payment_rate, value_per_complete_payment, total_complete_payment_rate, page_browse_view, cost_per_page_browse_view, page_browse_view_rate, total_page_browse_view_value, value_per_page_browse_view, button_click, cost_per_button_click, button_click_rate, value_per_button_click, total_button_click_value, online_consult, cost_per_online_consult, online_consult_rate, value_per_online_consult, total_online_consult_value, user_registration, cost_per_user_registration, user_registration_rate, value_per_user_registration, total_user_registration_value, product_details_page_browse, cost_per_product_details_page_browse, product_details_page_browse_rate, value_per_product_details_page_browse, total_product_details_page_browse_value, web_event_add_to_cart, cost_per_web_event_add_to_cart, web_event_add_to_cart_rate, value_per_web_event_add_to_cart, total_web_event_add_to_cart_value, on_web_order, cost_per_on_web_order, on_web_order_rate, value_per_on_web_order, total_on_web_order_value, initiate_checkout, cost_per_initiate_checkout, initiate_checkout_rate, value_per_initiate_checkout, total_initiate_checkout_value, add_billing, cost_per_add_billing, add_billing_rate, value_per_add_billing, total_add_billing_value, page_event_search, cost_per_page_event_search, page_event_search_rate, value_per_page_event_search, total_page_event_search_value, form, cost_per_form, form_rate, value_per_form, total_form_value, download_start, cost_per_download_start, download_start_rate, value_per_download_start, total_download_start_value, on_web_add_to_wishlist, cost_per_on_web_add_to_wishlist, on_web_add_to_wishlist_per_click, value_per_on_web_add_to_wishlist, total_on_web_add_to_wishlist_value, on_web_subscribe, cost_per_on_web_subscribe, on_web_subscribe_per_click, value_per_on_web_subscribe, total_on_web_subscribe_value
campaigns_page_event_metrics_by_day78 fields
campaign_id, stat_time_day, complete_payment_roas, complete_payment, cost_per_complete_payment, complete_payment_rate, value_per_complete_payment, total_complete_payment_rate, page_browse_view, cost_per_page_browse_view, page_browse_view_rate, total_page_browse_view_value, value_per_page_browse_view, button_click, cost_per_button_click, button_click_rate, value_per_button_click, total_button_click_value, online_consult, cost_per_online_consult, online_consult_rate, value_per_online_consult, total_online_consult_value, user_registration, cost_per_user_registration, user_registration_rate, value_per_user_registration, total_user_registration_value, product_details_page_browse, cost_per_product_details_page_browse, product_details_page_browse_rate, value_per_product_details_page_browse, total_product_details_page_browse_value, web_event_add_to_cart, cost_per_web_event_add_to_cart, web_event_add_to_cart_rate, value_per_web_event_add_to_cart, total_web_event_add_to_cart_value, on_web_order, cost_per_on_web_order, on_web_order_rate, value_per_on_web_order, total_on_web_order_value, initiate_checkout, cost_per_initiate_checkout, initiate_checkout_rate, value_per_initiate_checkout, total_initiate_checkout_value, add_billing, cost_per_add_billing, add_billing_rate, value_per_add_billing, total_add_billing_value, page_event_search, cost_per_page_event_search, page_event_search_rate, value_per_page_event_search, total_page_event_search_value, form, cost_per_form, form_rate, value_per_form, total_form_value, download_start, cost_per_download_start, download_start_rate, value_per_download_start, total_download_start_value, on_web_add_to_wishlist, cost_per_on_web_add_to_wishlist, on_web_add_to_wishlist_per_click, value_per_on_web_add_to_wishlist, total_on_web_add_to_wishlist_value, on_web_subscribe, cost_per_on_web_subscribe, on_web_subscribe_per_click, value_per_on_web_subscribe, total_on_web_subscribe_value
ads42 fields
ad_id, ad_format, campaign_name, external_action, identity_type, campaign_id, impression_tracking_url, brand_safety_postbid_partner, ad_name, avatar_icon_web_uri, ad_texts, vast_moat, is_creative_authorized, adgroup_id, image_ids, product_ids, call_to_action_id, video_id, adgroup_name, advertiser_id, open_url_type, creative_type, landing_page_url, modify_time, profile_image, call_to_action, identity_id, page_id, display_name, opt_status, playable_url, is_new_structure, click_tracking_url, ad_text, landing_page_urls, is_aco, open_url, app_name, status, create_time, card_id, fallback_type
ad_accounts29 fields
advertiser_id, name, company, contacter, promotion_area, balance, license_province, currency, promotion_center_city, display_timezone, email, telephone, phonenumber, language, industry, create_time, address, role, reason, promotion_center_province, timezone, license_url, country, status, brand, license_city, description, license_no, owner_bc_id
ads_basic_data_metrics_by_day used by default26 fields
ad_id, stat_time_day, spend, cpc, cpm, impressions, clicks, ctr, reach, cost_per_1000_reached, conversion, cost_per_conversion, conversion_rate, real_time_conversion, real_time_cost_per_conversion, real_time_conversion_rate, result, cost_per_result, result_rate, real_time_result, real_time_cost_per_result, real_time_result_rate, secondary_goal_result, cost_per_secondary_goal_result, secondary_goal_result_rate, frequency
campaigns_basic_data_metrics_by_day26 fields
campaign_id, stat_time_day, spend, cpc, cpm, impressions, clicks, ctr, reach, cost_per_1000_reached, conversion, cost_per_conversion, conversion_rate, real_time_conversion, real_time_cost_per_conversion, real_time_conversion_rate, result, cost_per_result, result_rate, real_time_result, real_time_cost_per_result, real_time_result_rate, secondary_goal_result, cost_per_secondary_goal_result, secondary_goal_result_rate, frequency
ads_attribution_metrics_by_day16 fields
ad_id, stat_time_day, vta_app_install, vta_conversion, cost_per_vta_conversion, vta_registration, cost_per_vta_registration, vta_purchase, cost_per_vta_purchase, cta_app_install, cta_conversion, cost_per_cta_conversion, cta_registration, cost_per_cta_registration, cta_purchase, cost_per_cta_purchase
campaigns16 fields
campaign_id, campaign_name, campaign_type, objective, objective_type, advertiser_id, budget_mode, deep_bid_type, status, create_time, modify_time, opt_status, is_new_structure, split_test_variable, budget, roas_bid
campaigns_attribution_metrics_by_day16 fields
campaign_id, stat_time_day, vta_app_install, vta_conversion, cost_per_vta_conversion, vta_registration, cost_per_vta_registration, vta_purchase, cost_per_vta_purchase, cta_app_install, cta_conversion, cost_per_cta_conversion, cta_registration, cost_per_cta_registration, cta_purchase, cost_per_cta_purchase
ads_attribute_metrics14 fields
ad_id, campaign_name, objective_type, campaign_id, adgroup_name, placement, adgroup_id, ad_name, ad_text, tt_app_id, tt_app_name, mobile_app_id, promotion_type, dpa_target_audience_type
campaigns_attribute_metrics13 fields
campaign_id, campaign_name, objective_type, adgroup_name, placement, adgroup_id, ad_name, ad_text, tt_app_id, tt_app_name, mobile_app_id, promotion_type, dpa_target_audience_type
ads_video_play_metrics_by_day used by default11 fields
ad_id, stat_time_day, video_play_actions, video_watched_2s, video_watched_6s, average_video_play, average_video_play_per_user, video_views_p25, video_views_p50, video_views_p75, video_views_p100
campaigns_video_play_metrics_by_day11 fields
campaign_id, stat_time_day, video_play_actions, video_watched_2s, video_watched_6s, average_video_play, average_video_play_per_user, video_views_p25, video_views_p50, video_views_p75, video_views_p100
ads_audience_age_gender_by_day9 fields
advertiser_id, campaign_id, stat_time_day, age, gender, spend, impressions, clicks, conversion
ads_engagement_metrics_by_day used by default9 fields
ad_id, stat_time_day, profile_visits, profile_visits_rate, likes, comments, shares, follows, clicks_on_music_disc
campaigns_engagement_metrics_by_day9 fields
campaign_id, stat_time_day, profile_visits, profile_visits_rate, likes, comments, shares, follows, clicks_on_music_disc
ads_audience_province_by_day8 fields
advertiser_id, ad_id, stat_time_day, province_id, spend, impressions, clicks, conversion
“Engagement” is not a column. Likes, comments, shares and follows live in the engagement table; clicks live in the basic one. Pacer adds likes, comments and shares to build the metric. If your report also counts clicks, say so in a note, because the definition changes the number.
Output
Where the data landsa spreadsheet and a warehouse are different jobs
Google Sheets
For building a report by hand
Tick spend, impressions, clicks and the campaign name, and the tab refreshes itself on every sync.
If you want video or engagement on the same row, tick those fields too when building the source: they come from different tables, and caOS joins them for you.
BigQuery
For modelling on top
20 datasets. Three structure tables on the ad side (accounts, ad groups and ads) and nine daily metric tables: basic, engagement, video, page event, in-app event, attribution, age and gender, region and attributes. The campaign side repeats the same family.
Joining video and engagement onto the basic table is a join by ad and day, and that is your work in the model.
Trust
Data freshnesswhy yesterday's number still moves
Ad platforms rewrite the past. A conversion attributed days later, revised spend, a corrected row: Tuesday's number changes on Thursday. If the extraction only ever brought the newest day, your spreadsheet would freeze at the first value and drift away from the platform with nobody noticing.
So caOS re-reads the last 28 days on every sync and rewrites what changed. Older history stays in the destination and is not touched. In practice: what sits in your spreadsheet or your warehouse is what the platform says today, not what it said on the day of the first load.
Metrics only go up to yesterday. The current day never arrives, however often you sync. A report that closes on the same day always shows the previous one.
Detail
Good to knowwhat usually raises questions
TikTok rewrites the ad name. On Smart+ generated ads, the platform pastes the caption or the file name in front of your taxonomy. The connector pulls the name faithfully, dirty from the source. Cleaning happens later, in the model.
Reach exists, and does not add up. Unlike Kwai and Google, TikTok delivers reach and frequency. But summing days or ads inflates the number.
Demographics only exist per campaign. Age and gender do not go down to the ad: the API collapses that cut at ad level, for privacy. Region does come per ad per day.
Support
When it failsthe message and what to do
“Invalid or expired state.” The link passed the 10 minutes or had already been used. Close it and click the card again.
It says connected and no account appears. The authorisation came back without a single advertiser. Whoever authorised had no access: fix it in Business Center and reconnect.
The sync turns red with a generic message. The most common cause is that access to that advertiser is gone: removed from Business Center, role changed, user deactivated. Ask whoever administers Business Center to give access back to the person who authorised, then sync again. Redoing the connection before that does not help.
This failure used to be silent: TikTok's API answers success even when it refuses, and the extraction finished green with zero rows. Today the error brings the sync down, which beats a lying green.
“Platform rate limit reached.” This is TikTok's own limit. Wait and sync later.