TikTok Marketing API — Overview¶
The TikTok Marketing API gives programmatic access to the advertising accounts of Nova Play, a mobile game studio that runs user-acquisition campaigns for 10 games. Each game has its own advertiser account (one account per game and OS), and every account contains campaigns, ad groups and ads whose daily performance you can download through the Reporting endpoint.
This documentation covers everything you need to pull daily ad performance:
| Section | What it covers |
|---|---|
| Authentication | How to send your access token |
| Advertiser | List the advertiser accounts your token can access |
| Campaign | Campaign metadata, naming convention, statuses |
| Ad Group | Targeting (locations, OS, audience), optimization goal, app id |
| Ad | Creatives (video / image / playable) |
| Reporting | /report/integrated/get/ — daily metrics at advertiser, campaign, ad group or ad level |
| Tools | Resolve numeric location_ids to countries and app_id to store packages |
| Errors & rate limits | Error codes, the 60 requests/minute limit, retry rules |
Base URL¶
https://business-api.huydata.com/open_api/v1.3
All endpoints are GET requests. Every path ends with a trailing slash (/campaign/get/, not /campaign/get). A request without the trailing slash receives an HTTP 307 redirect to the slashed path; most clients follow it, but curl does not unless you pass -L, so always write the slash.
Request format¶
- Parameters are sent as query string parameters, even for the Reporting endpoint.
- Parameters whose value is a list or an object (
advertiser_ids,fields,dimensions,metrics,filtering) are sent as JSON-encoded strings. For exampledimensions=["ad_id","stat_time_day","country_code"]. Because the value contains quotes, brackets and commas, it must be URL-encoded. Withcurl, use-Gtogether with--data-urlencodeand let curl do the encoding for you. - The access token is sent in the
Access-TokenHTTP header (see Authentication). - Dates use the
YYYY-MM-DDformat and the account time zone, which is UTC for every Nova Play account.
Response envelope¶
Every endpoint returns an HTTP 200 with the same JSON envelope:
{
"code": 0,
"message": "OK",
"request_id": "6e596d719a0141599ce7",
"data": { ... }
}
| Field | Type | Description |
|---|---|---|
code |
integer | 0 means success. Any other value is an error; see Errors & rate limits. |
message |
string | "OK" on success, otherwise a human-readable error description. |
request_id |
string | Unique id of the request. Also returned in the x-request-id response header. Quote it when you report a problem. |
data |
object | The payload. Empty object {} on error. |
Important: errors are returned with HTTP status 200 and code != 0. Checking the HTTP status is not enough; your client must read code from the JSON body on every call. The only cases with a different HTTP status are an unknown route (HTTP 404) and a non-GET method (HTTP 405); both still return the envelope with code 40000.
List endpoints return their rows in data.list together with a data.page_info object:
"page_info": {"page": 1, "page_size": 10, "total_number": 48, "total_page": 5}
page starts at 1, page_size defaults to 10 and may be at most 1000. Keep requesting page + 1 until page >= total_page.
Data freshness¶
- Report dates are daily, in UTC. A report date
Dbecomes available at 00:10 UTC onD + 1. Requests that include today's date return no rows for it (no error). - Spend, impressions and clicks are final when a date becomes available.
- Conversions and purchases keep growing for 3 days after the report date (the attribution window). The values for the last three available report dates will still change on the next day; re-pull them. See Reporting → Data freshness.
- The earliest report date in this account is
2026-06-30.
Quickstart¶
The three calls below are enough to get yesterday's spend per ad for one game. Export your token first:
export TIKTOK_ACCESS_TOKEN="<your personal token>"
export BASE="https://business-api.huydata.com/open_api/v1.3"
1. Find your advertiser accounts
curl -s "$BASE/oauth2/advertiser/get/" -H "Access-Token: $TIKTOK_ACCESS_TOKEN"
{
"code": 0,
"message": "OK",
"request_id": "6e596d719a0141599ce7",
"data": {
"list": [
{"advertiser_id": "7643153585721644371", "advertiser_name": "Dragon Merge Saga (Android)"},
{"advertiser_id": "7548458757843580535", "advertiser_name": "Idle Mining Empire (Android)"},
{"advertiser_id": "7990946724050865085", "advertiser_name": "Zombie Siege Defense (Android)"},
...
]
}
}
2. Pull ad-level performance for one day, split by country
curl -s -G "$BASE/report/integrated/get/" \
-H "Access-Token: $TIKTOK_ACCESS_TOKEN" \
--data-urlencode "advertiser_id=7643153585721644371" \
--data-urlencode "report_type=BASIC" \
--data-urlencode "data_level=AUCTION_AD" \
--data-urlencode 'dimensions=["ad_id","stat_time_day","country_code"]' \
--data-urlencode 'metrics=["campaign_id","campaign_name","adgroup_id","adgroup_name","ad_name","spend","impressions","clicks","conversion","purchase","total_purchase_value"]' \
--data-urlencode "start_date=2026-10-29" \
--data-urlencode "end_date=2026-10-29" \
--data-urlencode "page_size=1000"
{
"code": 0,
"message": "OK",
"request_id": "713e0b341c244abc9d7c",
"data": {
"list": [
{
"dimensions": {"ad_id": "1808121195245644392", "stat_time_day": "2026-10-29 00:00:00", "country_code": "JP"},
"metrics": {
"campaign_id": "1871286220402645533",
"campaign_name": "DMS_TT_AND_EA_INSTALL_202602",
"adgroup_id": "1836683088316451285",
"adgroup_name": "EA_Interest_Gaming_JP-KR",
"ad_name": "PLAY_Meme_v2",
"spend": "20.42",
"impressions": "2646",
"clicks": "19",
"conversion": "2",
"purchase": "0",
"total_purchase_value": "0.00"
}
},
...
],
"page_info": {"page": 1, "page_size": 1000, "total_number": 64, "total_page": 1}
}
}
Note that every metric value is a string, including the numeric ones, and stat_time_day is returned as "YYYY-MM-DD 00:00:00".
3. Check code, then page
If code is not 0, stop and read message. If page_info.total_page is greater than page, repeat the call with page=2, page=3, ... See Reporting for a paging example.
Entity hierarchy¶
Advertiser (one per game, e.g. "Dragon Merge Saga (Android)")
└── Campaign DMS_TT_AND_EA_INSTALL_202602 objective, daily budget, status
└── Ad group EA_Broad_JP-KR-TW targeting: location_ids, OS, audience, optimization goal
└── Ad VID_Tutorial_v1 the creative: video, image or playable
All ids (advertiser_id, campaign_id, adgroup_id, ad_id, app_id, location_id) are numeric but are returned as strings. Keep them as strings; several of them exceed the 53-bit range that is safe for floating-point numbers.