How to Set Up TikTok Ads API Reporting
Pull TikTok ad performance data automatically for cross-platform analysis.
Jay Banlasan
The AI Systems Guy
TikTok ads API reporting automation pulls your ad data into the same pipeline as Meta and Google. Instead of logging into three platforms every morning, you pull everything into one database. I set this up for any client running TikTok alongside other channels.
TikTok's API is newer than Meta's but follows similar patterns. The authentication is different, but the data structure is straightforward once you get past the initial setup.
What You Need Before Starting
- A TikTok For Business account
- A TikTok Marketing API app (create at ads.tiktok.com/marketing_api)
- An access token with reporting permissions
- Python 3.8+ with
requestsinstalled
Step 1: Get Your API Credentials
Go to TikTok Marketing API portal. Create an app. Get approved (usually takes 1-2 business days). Once approved, generate a long-lived access token.
Store it in your .env:
TIKTOK_ACCESS_TOKEN=your_token_here
TIKTOK_ADVERTISER_ID=your_advertiser_id
Step 2: Build the Data Fetcher
import requests
import os
from datetime import datetime, timedelta
from dotenv import load_dotenv
load_dotenv()
TIKTOK_BASE = "https://business-api.tiktok.com/open_api/v1.3"
def fetch_tiktok_ads(date=None):
if not date:
date = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
token = os.getenv("TIKTOK_ACCESS_TOKEN")
advertiser_id = os.getenv("TIKTOK_ADVERTISER_ID")
headers = {"Access-Token": token}
params = {
"advertiser_id": advertiser_id,
"report_type": "BASIC",
"data_level": "AUCTION_AD",
"dimensions": '["ad_id", "stat_time_day"]',
"metrics": '["spend", "impressions", "clicks", "cpc", "ctr", "conversion", "cost_per_conversion", "reach"]',
"start_date": date,
"end_date": date,
"page_size": 100,
}
resp = requests.get(f"{TIKTOK_BASE}/report/integrated/get/", headers=headers, params=params)
data = resp.json()
if data.get("code") != 0:
print(f"TikTok API error: {data.get('message')}")
return []
rows = []
for item in data.get("data", {}).get("list", []):
metrics = item.get("metrics", {})
dimensions = item.get("dimensions", {})
rows.append({
"date": date,
"ad_id": dimensions.get("ad_id", ""),
"spend": float(metrics.get("spend", 0)),
"impressions": int(metrics.get("impressions", 0)),
"clicks": int(metrics.get("clicks", 0)),
"cpc": float(metrics.get("cpc", 0)),
"ctr": float(metrics.get("ctr", 0)),
"conversions": int(metrics.get("conversion", 0)),
"cpa": float(metrics.get("cost_per_conversion", 0)),
"reach": int(metrics.get("reach", 0)),
})
return rows
Step 3: Get Campaign and Ad Names
TikTok's reporting endpoint returns IDs, not names. You need a separate call:
def get_ad_details(ad_ids):
token = os.getenv("TIKTOK_ACCESS_TOKEN")
advertiser_id = os.getenv("TIKTOK_ADVERTISER_ID")
headers = {"Access-Token": token}
params = {
"advertiser_id": advertiser_id,
"filtering": f'{{"ad_ids": {ad_ids}}}',
"fields": '["ad_id", "ad_name", "campaign_name", "adgroup_name"]',
}
resp = requests.get(f"{TIKTOK_BASE}/ad/get/", headers=headers, params=params)
data = resp.json()
details = {}
for ad in data.get("data", {}).get("list", []):
details[ad["ad_id"]] = {
"ad_name": ad.get("ad_name", ""),
"campaign_name": ad.get("campaign_name", ""),
"adgroup_name": ad.get("adgroup_name", ""),
}
return details
Step 4: Store in Your Unified Database
import sqlite3
def store_tiktok_data(db_path, rows, ad_details):
conn = sqlite3.connect(db_path)
conn.execute("""CREATE TABLE IF NOT EXISTS tiktok_daily (
id INTEGER PRIMARY KEY, date TEXT, ad_id TEXT, ad_name TEXT,
campaign_name TEXT, adgroup_name TEXT, spend REAL, impressions INTEGER,
clicks INTEGER, cpc REAL, ctr REAL, conversions INTEGER, cpa REAL,
reach INTEGER, fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP
)""")
for row in rows:
details = ad_details.get(row["ad_id"], {})
conn.execute("""INSERT INTO tiktok_daily
(date, ad_id, ad_name, campaign_name, adgroup_name, spend, impressions,
clicks, cpc, ctr, conversions, cpa, reach)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)""",
(row["date"], row["ad_id"], details.get("ad_name", ""),
details.get("campaign_name", ""), details.get("adgroup_name", ""),
row["spend"], row["impressions"], row["clicks"], row["cpc"],
row["ctr"], row["conversions"], row["cpa"], row["reach"]))
conn.commit()
conn.close()
Step 5: Run It Daily
if __name__ == "__main__":
rows = fetch_tiktok_ads()
if rows:
ad_ids = [r["ad_id"] for r in rows]
details = get_ad_details(ad_ids)
store_tiktok_data("ads_unified.db", rows, details)
print(f"Stored {len(rows)} TikTok ad rows")
else:
print("No TikTok data to pull")
0 7 * * * cd /path/to/project && python3 tiktok_pull.py >> /var/log/tiktok.log 2>&1
Now your TikTok data lives alongside Meta and Google in the same database. Same queries, same dashboards, same alerts.
What to Build Next
Add TikTok data to your cross-platform dashboard. Then build a comparison report that shows which platform delivers the best CPA for each audience segment.
Related Reading
- AI in Paid Advertising: The Complete Overview - the full picture of AI-powered ad operations
- Data Flow Architecture for Non-Engineers - how data flows through your systems
- The Integration Hierarchy - prioritizing which integrations to build first
Want this system built for your business?
Get a free assessment. We will map every system your business needs and show you the ROI.
Get Your Free Assessment