Export TikTok Ads data to BigQuery: the agency guide
Three ways to export TikTok Ads data to BigQuery — connector vendors, the Marketing API pipeline, and CSV — plus the restatement trap that corrupts spend tables.
TL;DR
There is no native BigQuery connector for TikTok Ads — Google's Data Transfer Service covers Google sources and a short third-party list that, as of this writing, doesn't include TikTok. That leaves three routes: a connector vendor (Fivetran, Airbyte, Supermetrics, Windsor.ai, Funnel — fastest, priced per connection, which compounds painfully across an agency's client list), a DIY pipeline on the TikTok Marketing API's reporting endpoints (a scheduled cloud job writing to a date-partitioned table — a day to build, nearly free to run), or CSV exports (fine for a one-off audit, not a pipeline). Whichever route you pick, the part everyone gets wrong is the same: TikTok restates metrics for days after the fact as attributed conversions land, so a pipeline that only appends "yesterday" freezes wrong numbers forever. Re-fetch a trailing window every night and MERGE. The cross-platform schema this feeds, and the full restatement methodology, live in the ads-data-to-BigQuery hub.
The reason an agency wants TikTok spend data in BigQuery is the same reason it wants the GA4 event-level export there: the platform UI is a silo, and the questions that matter — blended CAC across platforms, TikTok's claimed conversions versus what GA4 and the client's order database say — are join questions. The GA4 export gives you the event log. The spend export gives you the other side of the join. TikTok's Ads Manager will happily show you TikTok's version of reality; BigQuery is where you referee it.
Route 1: a connector vendor
Fivetran, Airbyte (cloud or self-hosted), Supermetrics, Windsor.ai, and Funnel all ship maintained TikTok Ads connectors that land normalized tables in BigQuery on a schedule. This is the right answer when the pipeline must exist by Friday and nobody on the team owns Python.
The agency-specific catch is pricing shape: most vendors charge per connection or per account, and an agency doesn't have one TikTok advertiser account — it has thirty. A price that reads as trivial for one in-house team multiplies into a real line item across a client roster, and it's a cost you re-incur for every platform you add. Self-hosted Airbyte dodges the per-connection fee in exchange for owning the upgrade treadmill. Run the math at your client count before committing; the hub post has the decision framework.
Route 2: the Marketing API pipeline
The DIY route is less work than its reputation suggests, because you don't need TikTok's full Marketing API surface — only the reporting endpoints.
Auth. Register a developer app, get it approved for the Reporting scope, and store the long-lived access token in Secret Manager — never in the job's code or environment file. One app can report across every advertiser account the agency's Business Center can access, which is the structural advantage over per-account connector pricing.
The pull. The synchronous integrated-report endpoint covers routine daily pulls; the asynchronous report-task flow exists for backfills and big accounts (submit, poll, download). Request the ad-level grain with daily granularity — stat_time_day, with campaign, ad group, and ad IDs as dimensions — and the core metrics: spend, impressions, clicks, conversions, conversion value. Pull at the finest grain you'll ever need; you can aggregate up in SQL forever, but you can't disaggregate what you never stored.
The schedule. A small Cloud Run job (or Cloud Function) triggered by Cloud Scheduler at ~06:00 in the agency's timezone, looping advertiser accounts, writing to a table partitioned on the stat date and clustered by advertiser and campaign. Compute cost is effectively zero; storage at daily ad-level grain is megabytes per client per year.
Backfill once via the async flow — TikTok's reporting lookback is generous enough to recover a year or more of daily history, so even a brand-new pipeline starts with a usable baseline.
Route 3: CSV, and when it's legitimate
Ads Manager's export button is the right tool exactly twice: the one-off audit (a new-client takeover, a pitch analysis) and the sanity check that your pipeline's numbers match the UI's before anyone builds a dashboard on them. As a recurring process it fails the way every manual process fails — silently, on the week someone's on vacation.
The restatement trap
This is the failure that quietly corrupts most DIY spend tables. TikTok attributes conversions inside windows that extend days past the impression or click — so the conversions column for a given day keeps changing after that day ends. A pipeline that appends yesterday's rows and never looks back permanently freezes whatever the numbers were at fetch time. Weeks later, your BigQuery table disagrees with Ads Manager, nobody trusts the dashboard, and the pipeline dies of reputation failure.
The fix is mechanical: every night, re-fetch the trailing 28 days (long enough to cover the longest attribution window you'll use) and MERGE on the natural key — stat date plus ad ID — updating metrics on match, inserting on miss. Spend and impressions barely move; conversions converge to match the UI. The generalized version of this pattern, which is identical for every ad platform, is covered in the hub.
One related discipline: the quality of the conversions TikTok reports here is a function of your event setup. If the pixel/Events API layer double-fires or drops events, you're exporting precise records of wrong numbers — that layer is its own checklist in our TikTok pixel + Events API setup guide.
Pipelines are infrastructure — treat them like it
A spend pipeline is a tracking asset with the same failure modes as a pixel: tokens expire, API versions deprecate, a client's Business Center permission gets revoked during an org cleanup, and nothing announces the breakage except a dashboard that's quietly three weeks stale. The discipline that works is the one from our verification playbook: a recurring task that checks the table's freshest partition date, owned by a person, on a cadence. In Phloz, the pipeline lives as a node on the client's tracking infrastructure map with that verification task attached to it — so "TikTok spend table is stale" surfaces as an overdue task, not as a client asking why the numbers stopped.
Next in the series: the Meta Ads version (same architecture, different API personality), and the hub with the cross-platform schema that makes all of these land in one queryable spend table.