---
title: "Create a TikTok video campaign (paused)"
method: POST
path: "/api/v1/tools/tiktok_create_video_campaign/execute"
tags: ["TikTok Ads"]
---

# Create a TikTok video campaign (paused)

`POST /api/v1/tools/tiktok_create_video_campaign/execute`

## Request

- Base URL: `https://adako.ai`
- URL: `https://adako.ai/api/v1/tools/tiktok_create_video_campaign/execute`
- Auth: HTTP bearer

Builds a complete TikTok campaign — campaign, one ad group and one in-feed video ad — from a video URL, an existing video id, or an organic post for a Spark Ad. The campaign is created PAUSED and its ad group and ad enabled inside it, so nothing spends until the campaign is turned on, and turning it on launches everything.
Use when: the user wants a new TikTok campaign and has given the pieces: what it should achieve, a daily budget, where it should run, the video, the TikTok account the ad should appear as, and (for a video) a cover image. Resolve every place, language and interest with tiktok_search_targeting first, pick the identity with tiktok_list_identities, and confirm the objective with tiktok_explain_objective — this tool takes ids and refuses names.
Do not call it twice for the same campaign. It creates three objects and Adako has no delete tool: a duplicate must be paused and abandoned by hand. If a call fails, read the error — it names exactly which objects were created before the failure — and fix forward rather than retrying.
Do not invent a budget, an audience, an identity or a landing page. If the user has not named one, ask. Do not use a WEB_CONVERSIONS objective without checking tiktok_list_pixels: optimising for an event that is not firing burns the budget in the learning phase and never settles.
What it validates before creating anything: the objective / optimisation goal / billing combination, the campaign and ad group budget range and precision for the account's currency, the bid against its limits and both budgets, the schedule (days are the advertiser's, and a start more than a few hours in the past is refused), the pixel and event when the objective needs them, every location id against TikTok's list (including overlaps and the under-18 rules), the language codes, the identity (it must exist, be available, and be able to carry the post), the cover image, the ad text (no emoji; Chinese and Japanese characters count double), and the video itself — which is uploaded and read back from TikTok first, so a video that is too short never leaves a campaign behind.
Returns the campaign, ad group and ad ids, read back from TikTok, plus what to do next. Say explicitly that the campaign is paused when you report the result, with the two links the result gives (TikTok Ads Manager and the campaign's page in Adako), and offer "enable all": one tiktok_resume_campaign call, listed in the result as go_live.enable_all, one approval. TikTok also reviews the ad before it delivers, which usually takes a few hours.

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `arguments` object, required
    - `advertiser_id` string: TikTok advertiser id (a long numeric string). Only needed when the user has authorised more than one advertiser. Omit it to use the primary one.
    - `objective` 'REACH' | 'TRAFFIC' | 'VIDEO_VIEWS' | 'ENGAGEMENT' | 'WEB_CONVERSIONS', required: What the campaign buys. Call tiktok_explain_objective first if the user described a goal rather than naming one — the objective cannot be changed after the campaign exists.
    - `campaign_name` string, required: Campaign name as it appears in Ads Manager. No emoji.
    - `campaign_daily_budget` number: Daily budget for the campaign, a decimal in the account currency (60 means sixty, not 6000). Whole numbers only in currencies such as JPY, KRW, IDR, VND and TWD. Give this or campaign_lifetime_budget.
    - `campaign_lifetime_budget` number: Budget for the whole campaign instead of a daily one (TikTok's BUDGET_MODE_TOTAL). Decimal in the account currency.
    - `adgroup_name` string, required: Ad group name. No emoji.
    - `adgroup_daily_budget` number: Daily budget for the ad group, decimal in the account currency. Cannot exceed the campaign budget. Give this or adgroup_lifetime_budget.
    - `adgroup_lifetime_budget` number: Budget for the ad group's whole flight instead of a daily one. Needs end_date: a total budget paces to the end of the flight.
    - `start_date` string: First day the ad group may deliver, YYYY-MM-DD in the advertiser's timezone: from 00:00 that day there, or from now if it is today. A past day is refused. Omit to start from the moment it is created — it still only delivers once resumed.
    - `end_date` string: Last day, inclusive, in the advertiser's timezone: delivery stops at 23:59:59 that day there. Omit to run open-ended.
    - `optimization_goal` string: What the ad group optimises for. Omit to take the objective's default — tiktok_explain_objective lists the valid pairs.
    - `pixel_id` string: Pixel to optimise against. Required for WEB_CONVERSIONS; from tiktok_list_pixels.
    - `optimization_event` string: The pixel event to optimise for, e.g. ON_WEB_ORDER. Required for WEB_CONVERSIONS; pick one that is actually firing.
    - `bid` number: Manual bid (cost cap), decimal in the account currency. The unit follows the optimisation goal: per click for CLICK and PAGE_VISIT, per 1,000 impressions for REACH, per focused view for ENGAGED_VIEW and ENGAGED_VIEW_FIFTEEN, and a target cost per result for FOLLOWERS, CONVERT and VALUE. It must be lower than both the ad group and the campaign budget. Omit to let TikTok bid automatically, which is the right default for a new ad group.
    - `location_ids` string[], required: TikTok location ids from tiktok_search_targeting. Never a country or city name, and never a place together with a place inside it (a country and one of its cities) — TikTok refuses overlapping locations.
    - `age_groups` string[]: Age bands to target. Leave unset to reach every age TikTok allows, which includes 13–17 in most markets — pass the adult bands explicitly if the product is for adults only. In the US, Canada, Latin America, the EEA, the UK and Switzerland, TikTok limits an ad group that narrows by gender or interests to 18+, and refuses AGE_13_17 combined with them.
    - `gender` 'GENDER_UNLIMITED' | 'GENDER_MALE' | 'GENDER_FEMALE': Gender to target. Leave unset unless the product genuinely requires it.
    - `languages` string[]: Language codes exactly as tiktok_search_targeting (type: language) returns them, e.g. "en", "pt-BR". Checked against TikTok's list before anything is created.
    - `interest_category_ids` string[]: Interest category ids from tiktok_search_targeting (type: interest). Omit to let TikTok find the audience itself.
    - `interest_keyword_ids` string[]: Additional interest ids from tiktok_search_targeting (type: interest_keyword). Omit unless the user asked for a specific interest the categories do not cover.
    - `operating_systems` string[]: Target only one mobile operating system: ANDROID or IOS. TikTok takes a single value; leave unset for both.
    - `placement_type` 'PLACEMENT_TYPE_AUTOMATIC' | 'PLACEMENT_TYPE_NORMAL': PLACEMENT_TYPE_AUTOMATIC (default, and usually cheapest) or PLACEMENT_TYPE_NORMAL to choose placements, which then requires placements.
    - `placements` string[]: Which placements, required when placement_type is PLACEMENT_TYPE_NORMAL and ignored otherwise. PLACEMENT_PANGLE is off-app inventory; PLACEMENT_GLOBAL_APP_BUNDLE only reaches Brazil, Indonesia, Vietnam, the Philippines, Thailand, Malaysia, Mexico, Saudi Arabia and Japan.
    - `special_industries` string[]: Set when the ads promote housing, employment or credit opportunities (TikTok's special ad categories, generally available to advertisers registered in the US or Canada). The ad group may then not target by gender, age below 18+ or interest keywords. Ask the user rather than guess.
    - `video_url` string: The video file for the ad. Adako hosts no files: the platform downloads this URL itself, from its own servers and often hours later, so it must be a public link straight to the file — not a file on the computer, not a Drive, Dropbox or design-tool share page, not a link that expires or asks for a login. Call check_media first: it repairs the usual share links, checks the file against this platform, and says where to put a file that has no link yet.
    - `video_id` string: A video already in the library, from tiktok_list_ad_videos.
    - `spark_item_id` string: An organic TikTok post id, for a Spark Ad from an existing post. Needs the posting account's identity and its permission.
    - `image_ids` string[]: The cover image, from tiktok_upload_images: exactly one id, with the same aspect ratio as the video. Required with video_url or video_id — TikTok refuses a video ad without one. Not used with spark_item_id, which keeps the post's own cover.
    - `ad_name` string, required: Ad name, for the account's own reporting. No emoji.
    - `ad_text` string, required: The caption shown with the video: up to 100 characters as TikTok counts them (each Chinese or Japanese character counts as two), no emoji. The first 40 characters are what actually gets read in feed.
    - `call_to_action` 'LEARN_MORE' | 'SHOP_NOW' | 'SIGN_UP' | 'DOWNLOAD_NOW' | 'CONTACT_US' | 'APPLY_NOW' | 'BOOK_NOW' | 'GET_QUOTE' | 'SUBSCRIBE' | 'WATCH_NOW' | 'PLAY_GAME' | 'INSTALL_NOW' | 'READ_MORE' | 'VIEW_NOW' | 'ORDER_NOW', required: Button text on the ad.
    - `landing_page_url` string: Where the ad sends people, https only. Required for TRAFFIC and WEB_CONVERSIONS; optional for REACH, VIDEO_VIEWS and ENGAGEMENT.
    - `identity_id` string: The identity the ad posts as, from tiktok_list_identities. TikTok requires one on every ad; ask the user which account the ad should appear as.
    - `identity_type` 'CUSTOMIZED_USER' | 'AUTH_CODE' | 'TT_USER' | 'BC_AUTH_TT': Identity kind, from tiktok_list_identities; read from TikTok when omitted. TT_USER or BC_AUTH_TT run a video_id as a Spark Ad; AUTH_CODE only runs spark_item_id; TikTok no longer accepts new ads as CUSTOMIZED_USER on placements that include TikTok.
    - `identity_authorized_bc_id` string: The Business Center a BC_AUTH_TT identity is authorised through, from tiktok_list_identities. Required for BC_AUTH_TT; read from TikTok when omitted.
    - `idempotency_key` string: Optional caller-supplied key; identical keys never execute twice.
    - `raw_data` boolean: Return compact JSON only (no markdown). Use when you will compute on the result.

## Response `200`

The tool ran. A write returns proposal_id and approve_url while the change waits for approval.

- SuccessEnvelope
  - `success` unknown, required
  - `tool` string, required
  - `data` object, required: Machine-readable result.
  - `markdown` string, required: The same result written for a person or a model.
  - `quota` Quota: Task usage for the current billing period.
    - `plan` string
    - `used` integer
    - `limit` integer
    - `period_end` string
    - `upgrade_url` string
  - `proposal_id` string: Present for writes. Nothing changes on the ad platform until it is approved.
  - `approve_url` string: Where a person approves the proposal.
  - `request_id` string, required

## Other responses

- `400`: Invalid arguments, or the ad account could not be resolved.
- `401`: Missing, invalid, revoked or expired API key.
- `402`: Monthly task quota used up, or the plan does not include this tool.
- `403`: The connected ad account lacks the access level this tool needs.
- `404`: Unknown tool name.
- `409`: Not connected, reconnect needed, confirmation required, a proposal already pending or no longer pending, an identical create that failed earlier today (proposal_failed_before), a create that duplicates an approved one (duplicate_create), the ad-account limit of the plan reached (account_limit), or an Idempotency-Key reused with different arguments.
- `429`: Rate limited by Adako or by the ad platform. See Retry-After.
- `500`: Unexpected error inside Adako.
- `502`: The ad platform returned an error.

---

[API](https://skmtc.dev/adako/apis/adako-rest-api.md) · [All operations](https://skmtc.dev/adako/apis/adako-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/adako/apis/adako-rest-api/revisions/59ee60d48a56?raw)
