Contents
TikTok's Upgraded Smart+ Web Conversions API replaced the legacy Smart+ Campaign Creation API (/campaign/spc/create/), which stopped accepting new campaigns after March 31, 2026.1 The Upgraded Smart+ API uses three separate endpoints — one each for campaign, ad group, and ad creation — instead of the legacy API's single-endpoint approach.1 This structure gives advertisers per-component control over budget strategy, targeting mode, bidding, and creative assets while retaining optional AI-driven automation.2
The Web Conversions objective (WEB_CONVERSIONS) targets website purchase or signup events. It requires a TikTok Pixel or Events API integration as a prerequisite, and bills on an OCPM (Optimized Cost Per Mille) basis.3
The legacy Smart+ API created campaigns, ad groups, and ads in a single /campaign/spc/create/ call. The Upgraded Smart+ API splits this into three POST requests: /v1.3/smart_plus/campaign/create/, /v1.3/smart_plus/adgroup/create/, and /v1.3/smart_plus/ad/create/.1
The legacy API supported one ad group per campaign. The upgraded API allows up to 30 ad groups per campaign, each with independent targeting, budgets (when Campaign Budget Optimization is off), and schedules.12
The legacy API's creation endpoint was deprecated on March 31, 2026. Its update and status-change endpoints (/campaign/spc/update/ and /campaign/status/update/) remain functional until June 30, 2026. The Manual Campaign Management API (/campaign/create/) follows a separate deprecation timeline, with creation disabled after December 31, 2026.1
Three requirements must be met before making API calls:1
The developer app needs three permission scopes: Ads Management > Upgraded Smart Plus Ads, Reporting > Upgraded Smart+ Report, and Creative Management > Creative tool.1
POST /v1.3/smart_plus/campaign/create/
Set objective_type to WEB_CONVERSIONS. The only other required fields are advertiser_id and campaign_name.1
The budget_optimize_on field controls whether budget is managed at the campaign level (Campaign Budget Optimization / CBO) or at the ad group level.1
budget_optimize_on | budget_mode options | Where budget is set |
|---|---|---|
true (default) | BUDGET_MODE_TOTAL or BUDGET_MODE_DYNAMIC_DAILY_BUDGET | Campaign level — all ad groups share a single budget |
false | BUDGET_MODE_INFINITE, BUDGET_MODE_DAY, or BUDGET_MODE_TOTAL | Ad group level — each ad group has its own budget |
When CBO is on, the budget field is required at the campaign level. When CBO is off and budget_mode is BUDGET_MODE_INFINITE, no budget value is needed at the campaign level.1
TikTok recommends setting a daily campaign budget of at least 10x the historical Cost Per Action (CPA) for the equivalent objective, with 30x being the recommended starting point for Target CPA or Minimum ROAS bidding.4
curl -X POST 'https://business-api.tiktok.com/open_api/v1.3/smart_plus/campaign/create/' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"advertiser_id": "123456789",
"campaign_name": "Q2 Web Conversions - CBO",
"objective_type": "WEB_CONVERSIONS",
"budget_optimize_on": true,
"budget_mode": "BUDGET_MODE_DYNAMIC_DAILY_BUDGET",
"budget": 500
}'
The response returns a campaign_id used in the ad group creation step.1
curl -X POST 'https://business-api.tiktok.com/open_api/v1.3/smart_plus/campaign/create/' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"advertiser_id": "123456789",
"campaign_name": "Q2 Web Conversions - AdGroup Budgets",
"objective_type": "WEB_CONVERSIONS",
"budget_optimize_on": false,
"budget_mode": "BUDGET_MODE_INFINITE"
}'
POST /v1.3/smart_plus/adgroup/create/
The ad group defines targeting, optimization goal, bidding, budget (when CBO is off), schedule, and placements.1
| Field | Value | Notes |
|---|---|---|
promotion_type | WEBSITE | Required for Web Conversions |
optimization_goal | CONVERT, LANDING_PAGE, or CLICK | LANDING_PAGE requires a Pixel-based event source (not Events API alone) |
billing_event | OCPM | The only billing event for Web Conversions |
pixel_id | Your Pixel ID | Required to associate conversion events |
optimization_event | e.g. COMPLETE_PAYMENT, INITIATE_CHECKOUT | The specific Pixel event to optimize toward when goal is CONVERT |
bid_type | Behavior | When to use bid_price / conversion_bid_price |
|---|---|---|
BID_TYPE_NO_BID | Maximum delivery — spend the full budget as fast as possible | Neither field is needed |
BID_TYPE_CUSTOM | Cost Cap — TikTok targets a cost per result | Set conversion_bid_price for CONVERT or LANDING_PAGE; set bid_price for CLICK |
Cost Cap bidding (BID_TYPE_CUSTOM) is only available with a daily budget. It cannot be used with lifetime (BUDGET_MODE_TOTAL) budgets.1
Web Conversions supports both automatic and manual targeting.2
Automatic targeting (targeting_optimization_mode: "AUTOMATIC"): TikTok's system selects audiences using real-time signals. Two categories of constraints are available within targeting_spec:
location_ids, gender, languages)interest_category_ids, age_groups)Manual targeting (targeting_optimization_mode: "MANUAL"): Full control over demographics, interests, behaviors, device types, custom audiences, and lookalike audiences through the targeting_spec object.1
When budget_optimize_on is false at the campaign level, each ad group needs its own budget configuration:
Campaign budget_mode | Allowed ad group budget_mode | Ad group budget required? |
|---|---|---|
BUDGET_MODE_INFINITE or BUDGET_MODE_TOTAL | BUDGET_MODE_TOTAL or BUDGET_MODE_DYNAMIC_DAILY_BUDGET | Yes |
BUDGET_MODE_DAY | BUDGET_MODE_DYNAMIC_DAILY_BUDGET only | Yes |
When CBO is on, budget fields at the ad group level are not supported. The optional min_budget and max_budget fields (ad group-level daily floor and ceiling) are available only when CBO is on, the campaign uses a daily budget, and the bid type is BID_TYPE_NO_BID.1
Schedule is set with schedule_type: SCHEDULE_FROM_NOW (continuous, daily budget only) or SCHEDULE_START_END (with schedule_start_time and schedule_end_time in YYYY-MM-DD HH:MM:SS format).1
Set placement_type to PLACEMENT_TYPE_NORMAL and placements to an array containing one or more of PLACEMENT_TIKTOK, PLACEMENT_PANGLE, and PLACEMENT_GLOBAL_APP_BUNDLE. Omit both fields entirely for automatic placement selection.23
curl -X POST 'https://business-api.tiktok.com/open_api/v1.3/smart_plus/adgroup/create/' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"advertiser_id": "123456789",
"campaign_id": "CAMPAIGN_ID_FROM_STEP_1",
"adgroup_name": "US Purchasers - Auto Targeting",
"promotion_type": "WEBSITE",
"optimization_goal": "CONVERT",
"pixel_id": "YOUR_PIXEL_ID",
"optimization_event": "COMPLETE_PAYMENT",
"billing_event": "OCPM",
"bid_type": "BID_TYPE_NO_BID",
"schedule_type": "SCHEDULE_FROM_NOW",
"targeting_optimization_mode": "AUTOMATIC",
"targeting_spec": {
"location_ids": ["6252001"]
},
"placement_type": "PLACEMENT_TYPE_NORMAL",
"placements": ["PLACEMENT_TIKTOK"]
}'
curl -X POST 'https://business-api.tiktok.com/open_api/v1.3/smart_plus/adgroup/create/' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"advertiser_id": "123456789",
"campaign_id": "CAMPAIGN_ID_FROM_STEP_1",
"adgroup_name": "US 25-44 Purchasers - Manual",
"promotion_type": "WEBSITE",
"optimization_goal": "CONVERT",
"pixel_id": "YOUR_PIXEL_ID",
"optimization_event": "COMPLETE_PAYMENT",
"billing_event": "OCPM",
"bid_type": "BID_TYPE_CUSTOM",
"conversion_bid_price": 15.00,
"budget_mode": "BUDGET_MODE_DYNAMIC_DAILY_BUDGET",
"budget": 200,
"schedule_type": "SCHEDULE_START_END",
"schedule_start_time": "2026-04-01 00:00:00",
"schedule_end_time": "2026-04-30 23:59:59",
"targeting_optimization_mode": "MANUAL",
"targeting_spec": {
"location_ids": ["6252001"],
"age_groups": ["AGE_25_34", "AGE_35_44"],
"gender": "GENDER_UNLIMITED",
"languages": ["en"]
},
"placement_type": "PLACEMENT_TYPE_NORMAL",
"placements": ["PLACEMENT_TIKTOK", "PLACEMENT_GLOBAL_APP_BUNDLE"]
}'
POST /v1.3/smart_plus/ad/create/
The ad object holds creative assets, ad text, identity, call-to-action, and destination URL.1
Web Conversions ads support three formats: Video (SINGLE_VIDEO), Carousel (CAROUSEL), and TikTok Post (via tiktok_item_id). A single ad can contain up to 50 creative items combined across these formats.2 Each Carousel can contain up to 35 images and 1 music track.2
The creative_list array contains one entry per creative asset. Each entry includes a creative_info object specifying the format and media:
| Format | ad_format value | Required creative_info fields |
|---|---|---|
| Uploaded video | SINGLE_VIDEO | video_info.video_id + image_info.web_uri (thumbnail) |
| Carousel | CAROUSEL | image_info array (up to 35 images) + optional music_info |
| TikTok Post (Spark Ad) | SINGLE_VIDEO | tiktok_item_id (the identity must match the post owner) |
Every ad requires an identity — the TikTok account shown as the ad's publisher. The identity_type field determines which credentials are needed:1
identity_type | Additional required fields | Use case |
|---|---|---|
CUSTOMIZED_USER | None (uses a system-generated profile) | Non-Spark uploaded videos only |
AUTH_CODE | identity_id | Spark Ads via authorization code |
TT_USER | identity_id | Spark Ads via linked TikTok account |
BC_AUTH_TT | identity_id + identity_authorized_bc_id | Spark Ads via Business Center authorization |
The ad_text_list array accepts up to 5 text variations. TikTok's system tests combinations of creative assets and text, then allocates delivery toward higher-performing pairs.2
CTA and destination are configured together. If no CTA is needed, omit all CTA and destination fields.1
| CTA type | How to configure | Destination options |
|---|---|---|
| Dynamic (system-selected) | Set call_to_action_id in ad_configuration | URL, URL + deeplink, or Custom Page |
| Standard (fixed label) | Set call_to_action_list with up to 3 CTA strings | URL, URL + deeplink, or Custom Page |
For URL destinations, set landing_page_url_list with one or more URLs. For deeplinks, add deeplink and deeplink_type: "NORMAL" — deeplinks accept both Universal/App Links (https://) and custom URL schemes (scheme://resource).1
For Custom Page (TikTok Instant Page) destinations, set page_list with the page ID. Do not specify landing_page_url_list when using Custom Page.1
curl -X POST 'https://business-api.tiktok.com/open_api/v1.3/smart_plus/ad/create/' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"advertiser_id": "123456789",
"adgroup_id": "ADGROUP_ID_FROM_STEP_2",
"ad_name": "Spring Sale Video Ad",
"creative_list": [
{
"creative_info": {
"ad_format": "SINGLE_VIDEO",
"video_info": {"video_id": "v1234567890"},
"image_info": [{"web_uri": "https://example.com/thumbnail.jpg"}],
"identity_type": "BC_AUTH_TT",
"identity_id": "IDENTITY_ID",
"identity_authorized_bc_id": "BC_ID"
}
}
],
"ad_text_list": [
{"ad_text": "Shop the spring collection"},
{"ad_text": "New arrivals — 20% off this week"}
],
"landing_page_url_list": [
{"landing_page_url": "https://www.example.com/spring-sale"}
],
"ad_configuration": {
"call_to_action_id": "CTA_ID"
}
}'
curl -X POST 'https://business-api.tiktok.com/open_api/v1.3/smart_plus/ad/create/' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"advertiser_id": "123456789",
"adgroup_id": "ADGROUP_ID_FROM_STEP_2",
"ad_name": "Organic Post Spark Ad",
"creative_list": [
{
"creative_info": {
"ad_format": "SINGLE_VIDEO",
"tiktok_item_id": "TIKTOK_POST_ID",
"identity_type": "TT_USER",
"identity_id": "TIKTOK_IDENTITY_ID"
}
}
],
"ad_text_list": [
{"ad_text": "See what everyone is talking about"}
],
"landing_page_url_list": [
{"landing_page_url": "https://www.example.com/product"}
],
"ad_configuration": {
"call_to_action_list": ["Shop Now"]
}
}'
When Campaign Budget Optimization is on, all ad groups within the campaign must use identical values for these fields: promotion_type, optimization_goal, optimization_event, billing_event, bid_type, bid_price, conversion_bid_price, deep_bid_type, vbo_window, and roas_bid.1
When CBO is off, all ad groups must still share the same bid_type, deep_bid_type, vbo_window, and budget_mode.1
Violating these constraints returns a validation error on the ad group creation request. The API does not partially enforce uniformity — every field listed must match exactly.1
When running both Pixel (browser-side) and Events API (server-side), the same conversion event may be reported twice. TikTok deduplicates using the event_id parameter: if both Pixel and Events API send the same event_id for the same event type within 48 hours, TikTok counts it once.5
To set this up, generate a unique event_id per conversion (e.g., an order ID), pass it in the Pixel's ttq.track() call, and include the same value in the Events API request body. Without deduplication, conversion counts will be inflated and the optimization model will receive inaccurate signal data.5
CBO + lifetime budget + Cost Cap conflict. Setting budget_optimize_on: true with budget_mode: BUDGET_MODE_TOTAL and bid_type: BID_TYPE_CUSTOM will fail. Cost Cap bidding requires a daily budget.1
Non-uniform ad group fields under CBO. Creating a second ad group with a different optimization_event (e.g., ADD_TO_CART when the first uses COMPLETE_PAYMENT) while CBO is on returns a validation error. Switch CBO off or use the same event across all ad groups.1
LANDING_PAGE goal without Pixel. The LANDING_PAGE optimization goal requires a Pixel event source. An Events API-only setup does not satisfy this requirement — use CONVERT or CLICK instead.3
Mixing Spark and non-Spark ads. Web Conversions campaigns do not support mixing Spark Ads and non-Spark Ads within the same campaign.3
Editing during learning phase. Changes to bid, audience, or creative within the first 7 days of a campaign's delivery can reset the learning phase. TikTok recommends waiting 7 days before adjusting, then changing bids by no more than 15% every 2 days.4
Missing identity fields for BC_AUTH_TT. When identity_type is BC_AUTH_TT, both identity_id and identity_authorized_bc_id must be set inside the creative_info object. Omitting identity_authorized_bc_id returns an error.1
Budget floors. For Target CPA or Minimum ROAS strategies, a daily budget below 10x the historical CPA typically results in underdelivery.4
TikTok's Upgraded Smart+ Web Conversions API replaced the legacy Smart+ Campaign Creation API (/campaign/spc/create/), which stopped accepting new campaigns after March 31, 2026.1 The Upgraded Smart+ API uses three separate endpoints — one each for campaign, ad group, and ad creation — instead of the legacy API's single-endpoint approach.1 This structure gives advertisers per-component control over budget strategy, targeting mode, bidding, and creative assets while retaining optional AI-driven automation.2
The Web Conversions objective (WEB_CONVERSIONS) targets website purchase or signup events. It requires a TikTok Pixel or Events API integration as a prerequisite, and bills on an OCPM (Optimized Cost Per Mille) basis.3
The legacy Smart+ API created campaigns, ad groups, and ads in a single /campaign/spc/create/ call. The Upgraded Smart+ API splits this into three POST requests: /v1.3/smart_plus/campaign/create/, /v1.3/smart_plus/adgroup/create/, and /v1.3/smart_plus/ad/create/.1
The legacy API supported one ad group per campaign. The upgraded API allows up to 30 ad groups per campaign, each with independent targeting, budgets (when Campaign Budget Optimization is off), and schedules.12
The legacy API's creation endpoint was deprecated on March 31, 2026. Its update and status-change endpoints (/campaign/spc/update/ and /campaign/status/update/) remain functional until June 30, 2026. The Manual Campaign Management API (/campaign/create/) follows a separate deprecation timeline, with creation disabled after December 31, 2026.1
Three requirements must be met before making API calls:1
The developer app needs three permission scopes: Ads Management > Upgraded Smart Plus Ads, Reporting > Upgraded Smart+ Report, and Creative Management > Creative tool.1
POST /v1.3/smart_plus/campaign/create/
Set objective_type to WEB_CONVERSIONS. The only other required fields are advertiser_id and campaign_name.1
The budget_optimize_on field controls whether budget is managed at the campaign level (Campaign Budget Optimization / CBO) or at the ad group level.1
budget_optimize_on | budget_mode options | Where budget is set |
|---|---|---|
true (default) | BUDGET_MODE_TOTAL or BUDGET_MODE_DYNAMIC_DAILY_BUDGET | Campaign level — all ad groups share a single budget |
false | BUDGET_MODE_INFINITE, BUDGET_MODE_DAY, or BUDGET_MODE_TOTAL | Ad group level — each ad group has its own budget |
When CBO is on, the budget field is required at the campaign level. When CBO is off and budget_mode is BUDGET_MODE_INFINITE, no budget value is needed at the campaign level.1
TikTok recommends setting a daily campaign budget of at least 10x the historical Cost Per Action (CPA) for the equivalent objective, with 30x being the recommended starting point for Target CPA or Minimum ROAS bidding.4
curl -X POST 'https://business-api.tiktok.com/open_api/v1.3/smart_plus/campaign/create/' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"advertiser_id": "123456789",
"campaign_name": "Q2 Web Conversions - CBO",
"objective_type": "WEB_CONVERSIONS",
"budget_optimize_on": true,
"budget_mode": "BUDGET_MODE_DYNAMIC_DAILY_BUDGET",
"budget": 500
}'
The response returns a campaign_id used in the ad group creation step.1
curl -X POST 'https://business-api.tiktok.com/open_api/v1.3/smart_plus/campaign/create/' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"advertiser_id": "123456789",
"campaign_name": "Q2 Web Conversions - AdGroup Budgets",
"objective_type": "WEB_CONVERSIONS",
"budget_optimize_on": false,
"budget_mode": "BUDGET_MODE_INFINITE"
}'
POST /v1.3/smart_plus/adgroup/create/
The ad group defines targeting, optimization goal, bidding, budget (when CBO is off), schedule, and placements.1
| Field | Value | Notes |
|---|---|---|
promotion_type | WEBSITE | Required for Web Conversions |
optimization_goal | CONVERT, LANDING_PAGE, or CLICK | LANDING_PAGE requires a Pixel-based event source (not Events API alone) |
billing_event | OCPM | The only billing event for Web Conversions |
pixel_id | Your Pixel ID | Required to associate conversion events |
optimization_event | e.g. COMPLETE_PAYMENT, INITIATE_CHECKOUT | The specific Pixel event to optimize toward when goal is CONVERT |
bid_type | Behavior | When to use bid_price / conversion_bid_price |
|---|---|---|
BID_TYPE_NO_BID | Maximum delivery — spend the full budget as fast as possible | Neither field is needed |
BID_TYPE_CUSTOM | Cost Cap — TikTok targets a cost per result | Set conversion_bid_price for CONVERT or LANDING_PAGE; set bid_price for CLICK |
Cost Cap bidding (BID_TYPE_CUSTOM) is only available with a daily budget. It cannot be used with lifetime (BUDGET_MODE_TOTAL) budgets.1
Web Conversions supports both automatic and manual targeting.2
Automatic targeting (targeting_optimization_mode: "AUTOMATIC"): TikTok's system selects audiences using real-time signals. Two categories of constraints are available within targeting_spec:
location_ids, gender, languages)interest_category_ids, age_groups)Manual targeting (targeting_optimization_mode: "MANUAL"): Full control over demographics, interests, behaviors, device types, custom audiences, and lookalike audiences through the targeting_spec object.1
When budget_optimize_on is false at the campaign level, each ad group needs its own budget configuration:
Campaign budget_mode | Allowed ad group budget_mode | Ad group budget required? |
|---|---|---|
BUDGET_MODE_INFINITE or BUDGET_MODE_TOTAL | BUDGET_MODE_TOTAL or BUDGET_MODE_DYNAMIC_DAILY_BUDGET | Yes |
BUDGET_MODE_DAY | BUDGET_MODE_DYNAMIC_DAILY_BUDGET only | Yes |
When CBO is on, budget fields at the ad group level are not supported. The optional min_budget and max_budget fields (ad group-level daily floor and ceiling) are available only when CBO is on, the campaign uses a daily budget, and the bid type is BID_TYPE_NO_BID.1
Schedule is set with schedule_type: SCHEDULE_FROM_NOW (continuous, daily budget only) or SCHEDULE_START_END (with schedule_start_time and schedule_end_time in YYYY-MM-DD HH:MM:SS format).1
Set placement_type to PLACEMENT_TYPE_NORMAL and placements to an array containing one or more of PLACEMENT_TIKTOK, PLACEMENT_PANGLE, and PLACEMENT_GLOBAL_APP_BUNDLE. Omit both fields entirely for automatic placement selection.23
curl -X POST 'https://business-api.tiktok.com/open_api/v1.3/smart_plus/adgroup/create/' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"advertiser_id": "123456789",
"campaign_id": "CAMPAIGN_ID_FROM_STEP_1",
"adgroup_name": "US Purchasers - Auto Targeting",
"promotion_type": "WEBSITE",
"optimization_goal": "CONVERT",
"pixel_id": "YOUR_PIXEL_ID",
"optimization_event": "COMPLETE_PAYMENT",
"billing_event": "OCPM",
"bid_type": "BID_TYPE_NO_BID",
"schedule_type": "SCHEDULE_FROM_NOW",
"targeting_optimization_mode": "AUTOMATIC",
"targeting_spec": {
"location_ids": ["6252001"]
},
"placement_type": "PLACEMENT_TYPE_NORMAL",
"placements": ["PLACEMENT_TIKTOK"]
}'
curl -X POST 'https://business-api.tiktok.com/open_api/v1.3/smart_plus/adgroup/create/' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"advertiser_id": "123456789",
"campaign_id": "CAMPAIGN_ID_FROM_STEP_1",
"adgroup_name": "US 25-44 Purchasers - Manual",
"promotion_type": "WEBSITE",
"optimization_goal": "CONVERT",
"pixel_id": "YOUR_PIXEL_ID",
"optimization_event": "COMPLETE_PAYMENT",
"billing_event": "OCPM",
"bid_type": "BID_TYPE_CUSTOM",
"conversion_bid_price": 15.00,
"budget_mode": "BUDGET_MODE_DYNAMIC_DAILY_BUDGET",
"budget": 200,
"schedule_type": "SCHEDULE_START_END",
"schedule_start_time": "2026-04-01 00:00:00",
"schedule_end_time": "2026-04-30 23:59:59",
"targeting_optimization_mode": "MANUAL",
"targeting_spec": {
"location_ids": ["6252001"],
"age_groups": ["AGE_25_34", "AGE_35_44"],
"gender": "GENDER_UNLIMITED",
"languages": ["en"]
},
"placement_type": "PLACEMENT_TYPE_NORMAL",
"placements": ["PLACEMENT_TIKTOK", "PLACEMENT_GLOBAL_APP_BUNDLE"]
}'
POST /v1.3/smart_plus/ad/create/
The ad object holds creative assets, ad text, identity, call-to-action, and destination URL.1
Web Conversions ads support three formats: Video (SINGLE_VIDEO), Carousel (CAROUSEL), and TikTok Post (via tiktok_item_id). A single ad can contain up to 50 creative items combined across these formats.2 Each Carousel can contain up to 35 images and 1 music track.2
The creative_list array contains one entry per creative asset. Each entry includes a creative_info object specifying the format and media:
| Format | ad_format value | Required creative_info fields |
|---|---|---|
| Uploaded video | SINGLE_VIDEO | video_info.video_id + image_info.web_uri (thumbnail) |
| Carousel | CAROUSEL | image_info array (up to 35 images) + optional music_info |
| TikTok Post (Spark Ad) | SINGLE_VIDEO | tiktok_item_id (the identity must match the post owner) |
Every ad requires an identity — the TikTok account shown as the ad's publisher. The identity_type field determines which credentials are needed:1
identity_type | Additional required fields | Use case |
|---|---|---|
CUSTOMIZED_USER | None (uses a system-generated profile) | Non-Spark uploaded videos only |
AUTH_CODE | identity_id | Spark Ads via authorization code |
TT_USER | identity_id | Spark Ads via linked TikTok account |
BC_AUTH_TT | identity_id + identity_authorized_bc_id | Spark Ads via Business Center authorization |
The ad_text_list array accepts up to 5 text variations. TikTok's system tests combinations of creative assets and text, then allocates delivery toward higher-performing pairs.2
CTA and destination are configured together. If no CTA is needed, omit all CTA and destination fields.1
| CTA type | How to configure | Destination options |
|---|---|---|
| Dynamic (system-selected) | Set call_to_action_id in ad_configuration | URL, URL + deeplink, or Custom Page |
| Standard (fixed label) | Set call_to_action_list with up to 3 CTA strings | URL, URL + deeplink, or Custom Page |
For URL destinations, set landing_page_url_list with one or more URLs. For deeplinks, add deeplink and deeplink_type: "NORMAL" — deeplinks accept both Universal/App Links (https://) and custom URL schemes (scheme://resource).1
For Custom Page (TikTok Instant Page) destinations, set page_list with the page ID. Do not specify landing_page_url_list when using Custom Page.1
curl -X POST 'https://business-api.tiktok.com/open_api/v1.3/smart_plus/ad/create/' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"advertiser_id": "123456789",
"adgroup_id": "ADGROUP_ID_FROM_STEP_2",
"ad_name": "Spring Sale Video Ad",
"creative_list": [
{
"creative_info": {
"ad_format": "SINGLE_VIDEO",
"video_info": {"video_id": "v1234567890"},
"image_info": [{"web_uri": "https://example.com/thumbnail.jpg"}],
"identity_type": "BC_AUTH_TT",
"identity_id": "IDENTITY_ID",
"identity_authorized_bc_id": "BC_ID"
}
}
],
"ad_text_list": [
{"ad_text": "Shop the spring collection"},
{"ad_text": "New arrivals — 20% off this week"}
],
"landing_page_url_list": [
{"landing_page_url": "https://www.example.com/spring-sale"}
],
"ad_configuration": {
"call_to_action_id": "CTA_ID"
}
}'
curl -X POST 'https://business-api.tiktok.com/open_api/v1.3/smart_plus/ad/create/' \
-H 'Access-Token: YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"advertiser_id": "123456789",
"adgroup_id": "ADGROUP_ID_FROM_STEP_2",
"ad_name": "Organic Post Spark Ad",
"creative_list": [
{
"creative_info": {
"ad_format": "SINGLE_VIDEO",
"tiktok_item_id": "TIKTOK_POST_ID",
"identity_type": "TT_USER",
"identity_id": "TIKTOK_IDENTITY_ID"
}
}
],
"ad_text_list": [
{"ad_text": "See what everyone is talking about"}
],
"landing_page_url_list": [
{"landing_page_url": "https://www.example.com/product"}
],
"ad_configuration": {
"call_to_action_list": ["Shop Now"]
}
}'
When Campaign Budget Optimization is on, all ad groups within the campaign must use identical values for these fields: promotion_type, optimization_goal, optimization_event, billing_event, bid_type, bid_price, conversion_bid_price, deep_bid_type, vbo_window, and roas_bid.1
When CBO is off, all ad groups must still share the same bid_type, deep_bid_type, vbo_window, and budget_mode.1
Violating these constraints returns a validation error on the ad group creation request. The API does not partially enforce uniformity — every field listed must match exactly.1
When running both Pixel (browser-side) and Events API (server-side), the same conversion event may be reported twice. TikTok deduplicates using the event_id parameter: if both Pixel and Events API send the same event_id for the same event type within 48 hours, TikTok counts it once.5
To set this up, generate a unique event_id per conversion (e.g., an order ID), pass it in the Pixel's ttq.track() call, and include the same value in the Events API request body. Without deduplication, conversion counts will be inflated and the optimization model will receive inaccurate signal data.5
CBO + lifetime budget + Cost Cap conflict. Setting budget_optimize_on: true with budget_mode: BUDGET_MODE_TOTAL and bid_type: BID_TYPE_CUSTOM will fail. Cost Cap bidding requires a daily budget.1
Non-uniform ad group fields under CBO. Creating a second ad group with a different optimization_event (e.g., ADD_TO_CART when the first uses COMPLETE_PAYMENT) while CBO is on returns a validation error. Switch CBO off or use the same event across all ad groups.1
LANDING_PAGE goal without Pixel. The LANDING_PAGE optimization goal requires a Pixel event source. An Events API-only setup does not satisfy this requirement — use CONVERT or CLICK instead.3
Mixing Spark and non-Spark ads. Web Conversions campaigns do not support mixing Spark Ads and non-Spark Ads within the same campaign.3
Editing during learning phase. Changes to bid, audience, or creative within the first 7 days of a campaign's delivery can reset the learning phase. TikTok recommends waiting 7 days before adjusting, then changing bids by no more than 15% every 2 days.4
Missing identity fields for BC_AUTH_TT. When identity_type is BC_AUTH_TT, both identity_id and identity_authorized_bc_id must be set inside the creative_info object. Omitting identity_authorized_bc_id returns an error.1
Budget floors. For Target CPA or Minimum ROAS strategies, a daily budget below 10x the historical CPA typically results in underdelivery.4