The TikTok Ads Manager UI is fine for browsing, but if you run more
than two campaigns you eventually need yesterday's spend in a Google
Sheet before you've made coffee. The platform's CSV export button
is the only path the UI offers — and it's the same number of clicks
every morning.
This post walks through replacing that chore with a 30-line cron job,
using the official TikTok Marketing API and a small open-source CLI
called aigen-reports.
What you'll end up with
Every morning at 02:00 your server pulls yesterday's campaign metrics
for each of your TikTok ad accounts and appends them to a single Google
Sheets tab. Total operator effort: zero.
Mon 03:00 → 12 rows (4 campaigns × 3 metrics) → Sheets:Daily!A2
Tue 03:00 → 12 rows → Sheets:Daily!A14
Wed 03:00 → 12 rows → Sheets:Daily!A26
Prerequisites
- Python 3.10+ on the machine that will run cron.
- A TikTok for Business account with at least one advertiser (sandbox works for testing — you can switch to a real account once approved).
- A Google Cloud project with the Sheets API enabled and a service account JSON key file. (Optional — if you only want CSV output you can skip this.)
Step 1 — Create the Marketing API app
- Open https://business-api.tiktok.com/portal/.
- Click Become a developer → fill in the basic profile.
- Click Create an App.
- App name: anything (this is what reviewers see — make it specific).
- App description: 2–3 sentences saying it's a read-only reporting utility. Don't oversell.
- Permission category: tick Reporting only. No write categories, no Ads Management, no Creative Management. The fewer categories you ask for the faster the review.
- Set the redirect URI to
http://localhost:8765/callbackfor local testing. - Submit for review. While you wait, you can develop against the sandbox.
Step 2 — Install the CLI
pip install aigen-reports
Step 3 — Authorize once
Set your app credentials:
export TIKTOK_APP_ID=...
export TIKTOK_APP_SECRET=...
export TIKTOK_REDIRECT_URI=http://localhost:8765/callback
Run the auth flow:
aigen-reports auth
The browser opens, you click Authorize, the CLI exchanges the auth
code for an access token and stores it encrypted at
~/.aigen-reports/credentials.json.
Token lifecycle. TikTok access tokens expire (typically 24 h);
the refresh token is good for ~1 year. The CLI refreshes
automatically.
Step 4 — Pull a report
aigen-reports pull \
--advertiser 7xxxxxxxxxx \
--metric spend,clicks,impressions,conversions \
--breakdown campaign \
--range last-1d \
--out yesterday.csv
That's the entire reporting flow. The output is a plain CSV:
campaign_id,campaign_name,stat_time_day,spend,clicks,impressions,conversions
17xxxxxxxxx,Evergreen-EN,2026-04-16,148.21,512,18342,9
17xxxxxxxxx,Evergreen-DE,2026-04-16,212.04,743,24011,14
...
Step 5 — Pipe it to Google Sheets
If you want the output in Sheets instead of CSV, install the optional
extra and point --out at a sheet ID:
pip install 'aigen-reports[gsheet]'
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
aigen-reports pull \
--advertiser 7xxxxxxxxxx \
--metric spend,clicks,conversions \
--range last-1d \
--out gsheet:1AbCdEfGhIjKlMnOpQrStUvWxYz
Share the Sheet with the service account's email so it can append.
Step 6 — Schedule it
Add the same command to cron:
# /etc/cron.d/aigen-reports
0 2 * * * www-data /usr/local/bin/aigen-reports pull \
--advertiser 7xxxxxxxxxx \
--metric spend,clicks,conversions \
--range last-1d \
--out gsheet:1AbCdEfGhIjKlMnOpQrStUvWxYz
Done. From here on you don't open the TikTok Ads Manager UI just to
look at numbers.
Failure modes I hit (and how to recover)
-
code: 40105 access_token has expired— the refresh failed, runaigen-reports authagain. -
code: 40002 advertiser_id not in your business— the operator who authorized the app no longer has access to that advertiser. Re- authorize with someone who does. -
Rate-limit response (
code: 50002) — TikTok caps requests per app per minute. The CLI retries with exponential backoff; if you're pulling 50+ accounts in parallel, stagger them across the hour.
What this is not
- It is not a dashboard. It writes a CSV, that's it.
- It is not a campaign manager. No write scopes are requested.
- It is not a hosted SaaS. It runs on your machine, your data stays on your machine.
If you need a dashboard, paid hosting, or campaign management, this
isn't the tool you want. If you need yesterday's TikTok Ads numbers in
a CSV at 02:01 every morning, it is.
Source
- CLI: https://github.com/ArtificialIntelligentGeneration/aigen-reports
- Curated docs / SDK list: https://github.com/ArtificialIntelligentGeneration/awesome-tiktok-ads-api
- Site: https://aigen-agency.com
Bug reports on GitHub Issues, everything else by email.
— Julian
Top comments (0)