- Standard Image Ads: Provide asset_bundle_id or existing_image_ids
- Spark Ads: Provide tiktok_item_id to boost an existing organic TikTok post as a paid ad
- Carousel Ads: First call create_tiktok_carousel_card to get a card_id, then provide card_id + card_type here
- App Promotion: Set objective=APP_PROMOTION + app_id for app install campaigns
- Call this tool ONLY ONCE per campaign
- Creates REAL campaigns that cost REAL money
- Do NOT retry automatically if errors occur
- Report errors to user instead of retrying
OpenAPI
/api-reference/openapi.json post /api/v1/tools/create_tiktok_campaign/execute
openapi: 3.1.0
info:
contact:
email: [email protected]
name: ADSMCP Support
description: >-
REST endpoints for every ADSMCP tool. Same surface as the MCP server, over
plain HTTP for consumers that can't speak SSE (n8n, Zapier, Make, curl, any
language's HTTP client).
## Envelope
Every request wraps tool-specific input in an `arguments` object:
```json
{ "arguments": { <tool-specific fields> } }
```
Every response wraps the result in either a success envelope (`success:
true`, `data: {...}`) or an error envelope (`success: false`, `error:
"..."`, `is_error: true`).
## Authentication
Pass your API key as `Authorization: Bearer sk_live_...` on every request.
Generate keys at https://adsmcp.si/dashboard/api-tokens.
## Quota & billing
Every successful billable call decrements your monthly tool-call allowance.
The current counter is attached to every 200 response under `data.quota`:
```json
"quota": { "used": 42, "limit": 150, "tier": "plus", "period_end":
"2026-05-01" }
```
When the limit is hit, the API returns HTTP 402 with a full `quota` block
including `upgrade_url`. Read-only diagnostic tools (`get_usage_status`,
`list_connected_accounts`, `get_connections_status`) are exempt and never
consume quota.
## Idempotency
Write operations accept an `Idempotency-Key: <uuid>` header. A repeated call
with the same key returns the cached result rather than executing twice.
**Strongly recommended for n8n, Zapier, and any retry-prone client** — it
prevents duplicate campaigns when networks misbehave. Generate a fresh UUID
per logical operation (not per retry).
## Multi-account users
Customers with multiple connected accounts on the same platform (e.g. an
agency with 10 Meta ad accounts) must specify which account to use via
`ad_account_id`, `customer_id`, `advertiser_id`, or `account_id` depending
on the platform. Omitting it returns HTTP 400 with a list of valid account
IDs. See `list_connected_accounts` to discover available IDs.
## HTTP status codes
- `200` — success (parse `data`)
- `400` — tool-level error (surface `error` to users)
- `401` — bad/missing API key
- `402` — ADSMCP quota exhausted
- `404` — unknown tool name
- `429` — upstream ad platform rate-limited us (Meta/Google/etc.) — retry
with backoff
- `500` — server error, report to support
## Streaming
This endpoint is plain request-response JSON. There is **no SSE, no chunked
streaming**. Safe to use from n8n Cloud's HTTP Request node, Zapier
Webhooks, Make HTTP module, curl, and every mainstream HTTP library.
title: ADSMCP REST API
version: 1.0.0
servers:
- description: Production
url: https://api.adsmcp.si
security: []
tags:
- description: Audit tools
name: audit
- description: General (Account Management) tools
name: general
- description: Google Ads tools
name: google-ads
- description: LinkedIn Ads tools
name: linkedin-ads
- description: Meta Ads tools
name: meta-ads
- description: Monitoring & Reporting tools
name: monitoring
- description: TikTok Ads tools
name: tiktok-ads
paths:
/api/v1/tools/create_tiktok_campaign/execute:
post:
tags:
- tiktok-ads
summary: Create TikTok Campaign
description: >
User wants to create a TikTok ad campaign with IMAGES, Spark Ads, or
Carousel ads (not video).
LONG-RUNNING TOOL: Creates a TikTok In-Feed ad campaign with image
creatives, Spark Ads (boost organic posts), or Carousel ads.
Supported creative types:
- Standard Image Ads: Provide asset_bundle_id or existing_image_ids
- Spark Ads: Provide tiktok_item_id to boost an existing organic TikTok
post as a paid ad
- Carousel Ads: First call create_tiktok_carousel_card to get a card_id,
then provide card_id + card_type here
- App Promotion: Set objective=APP_PROMOTION + app_id for app install
campaigns
Emits MCP progress updates during campaign creation (typically 15-30
seconds).
Progress stages: validate - commit.
CRITICAL WARNING:
- Call this tool ONLY ONCE per campaign
- Creates REAL campaigns that cost REAL money
- Do NOT retry automatically if errors occur
- Report errors to user instead of retrying
operationId: execute_create_tiktok_campaign
parameters:
- description: >-
Client-generated UUID to make writes idempotent. Strongly
recommended for write tools. A repeat call with the same key returns
the cached result instead of re-executing. Example:
550e8400-e29b-41d4-a716-446655440000
example: 550e8400-e29b-41d4-a716-446655440000
in: header
name: Idempotency-Key
required: false
schema:
format: uuid
type: string
requestBody:
content:
application/json:
example:
arguments:
ad_text: string
app_id: string
app_promotion_type: string
budget_daily: 1
budget_lifetime: 1
campaign_name: string
display_name: string
landing_page_url: https://example.com
objective: TRAFFIC
schedule_end_time: string
schema:
properties:
arguments:
description: Input schema for creating TikTok In-Feed image ad campaigns
properties:
ad_text:
description: >-
Ad text (1-100 characters). Recommended: 50 characters
or less for no truncation.
maxLength: 100
minLength: 1
title: Ad Text
type: string
advertiser_id:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
TikTok advertiser ID. Required for multi-account users.
Get from list_connected_accounts.
title: Advertiser Id
app_id:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
TikTok app ID for APP_PROMOTION campaigns. Required when
objective is APP_PROMOTION.
title: App Id
app_promotion_type:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
App promotion type for APP_PROMOTION campaigns. Options:
'APP_INSTALL' (new installs), 'APP_RETARGETING'
(re-engage existing users). Default: APP_INSTALL
title: App Promotion Type
asset_bundle_id:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
Asset bundle ID from validate_and_prepare_tiktok_assets
tool. Use this for NEW image uploads. Mutually exclusive
with existing_image_ids.
title: Asset Bundle Id
audience_ids:
anyOf:
- items:
type: string
type: array
- type: 'null'
default: null
description: >-
Custom audience IDs to include (DMP audiences,
lookalikes).
title: Audience Ids
budget_daily:
anyOf:
- minimum: 1
type: number
- type: 'null'
default: null
description: >-
Daily budget in account currency (minimum varies by
region, typically $20-50/day). Mutually exclusive with
budget_lifetime.
title: Budget Daily
budget_lifetime:
anyOf:
- minimum: 1
type: number
- type: 'null'
default: null
description: >-
Lifetime budget in account currency (total spend over
campaign duration). Requires schedule_end_time. Mutually
exclusive with budget_daily.
title: Budget Lifetime
budget_optimize_on:
anyOf:
- type: boolean
- type: 'null'
default: null
description: >-
Campaign Budget Optimization (CBO). TikTok default: true
(enabled). When enabled, TikTok auto-distributes budget
across ad groups. Set to false to manage budgets per ad
group manually.
title: Budget Optimize On
call_to_action:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
Call-to-action button text. Options: 'LEARN_MORE',
'SHOP_NOW', 'SIGN_UP', 'DOWNLOAD', 'CONTACT_US',
'APPLY_NOW', 'BOOK_NOW', 'GET_QUOTE', 'SUBSCRIBE',
'ORDER_NOW', 'BUY_NOW', 'GET_OFFER', 'WATCH_NOW'.
Default: auto-selected by TikTok.
title: Call To Action
campaign_name:
description: >-
Campaign name (will be automatically suffixed with
timestamp for uniqueness)
title: Campaign Name
type: string
card_id:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
Carousel card ID for multi-card image ads. Create
carousel cards first in TikTok Ads Manager, then provide
the card ID here. When using carousel, asset_bundle_id
and existing_image_ids are NOT required.
title: Card Id
card_type:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
Carousel card type: 'IMAGE' (image carousel) or
'PRODUCT' (product catalog carousel). Required when
card_id is provided.
title: Card Type
comment_disabled:
anyOf:
- type: boolean
- type: 'null'
default: null
description: >-
Disable comments on ads. Default: false (comments
allowed).
title: Comment Disabled
display_name:
description: >-
Brand/business name displayed on the ad (max 40
characters)
maxLength: 40
title: Display Name
type: string
excluded_audience_ids:
anyOf:
- items:
type: string
type: array
- type: 'null'
default: null
description: Custom audience IDs to exclude.
title: Excluded Audience Ids
existing_image_ids:
anyOf:
- items:
type: string
type: array
- type: 'null'
default: null
description: >-
List of existing TikTok image IDs from
discover_tiktok_assets tool. Use this to REUSE images
from TikTok Asset Library. Mutually exclusive with
asset_bundle_id.
title: Existing Image Ids
interest_category_ids:
anyOf:
- items:
type: string
type: array
- type: 'null'
default: null
description: >-
Interest category IDs for interest-based targeting. Get
IDs from TikTok Ads Manager or search_tiktok_interests
tool.
title: Interest Category Ids
landing_page_url:
description: Landing page URL (must be HTTPS).
title: Landing Page Url
type: string
languages:
anyOf:
- items:
type: string
type: array
- type: 'null'
default: null
description: >-
Language targeting codes (e.g., ['en', 'es']). Default:
all languages.
title: Languages
objective:
anyOf:
- type: string
- type: 'null'
default: TRAFFIC
description: >-
Campaign objective. Options: 'TRAFFIC' (website visits),
'CONVERSIONS' (website conversions), 'LEAD_GENERATION'
(leads), 'REACH' (maximum impressions), 'VIDEO_VIEWS'
(video views), 'APP_PROMOTION' (app installs — requires
app_id). Default: TRAFFIC
title: Objective
operating_systems:
anyOf:
- items:
type: string
type: array
- type: 'null'
default: null
description: >-
Target device OS. Options: 'ANDROID', 'IOS'. Default:
all.
title: Operating Systems
optimization_event:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
Conversion event to optimize for when pixel_id is
provided. Options: COMPLETE_PAYMENT, ON_WEB_CART (add to
cart), ON_WEB_DETAIL (view content), ON_WEB_REGISTER
(registration), FORM (form submit), CONVERSION_LEADS
(lead gen), INITIATE_ORDER, PAGE_VISIT,
CLICK_LANDING_PAGE, ON_WEB_SUBSCRIBE, PHONE_CONNECT,
CONSULT, SEARCH, SUBSCRIBE, DOWNLOAD_FINISH. Default:
COMPLETE_PAYMENT
title: Optimization Event
pixel_id:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
TikTok Pixel ID for conversion tracking. Required for
CONVERSIONS objective.
title: Pixel Id
placement_type:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
Placement type: 'PLACEMENT_TYPE_AUTOMATIC' (recommended)
or 'PLACEMENT_TYPE_NORMAL' (manual). Default:
PLACEMENT_TYPE_AUTOMATIC.
title: Placement Type
placements:
anyOf:
- items:
type: string
type: array
- type: 'null'
default: null
description: >-
Manual placement selection (when
placement_type=PLACEMENT_TYPE_NORMAL). Options:
'PLACEMENT_TIKTOK', 'PLACEMENT_PANGLE',
'PLACEMENT_GLOBAL_APP_BUNDLE'.
title: Placements
schedule_end_time:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
Campaign end time in format 'YYYY-MM-DD HH:MM:SS'.
Required when using budget_lifetime. Optional with
budget_daily.
title: Schedule End Time
target_age_groups:
anyOf:
- items:
type: string
type: array
- type: 'null'
default: null
description: >-
Age groups to target. Options: 'AGE_13_17', 'AGE_18_24',
'AGE_25_34', 'AGE_35_44', 'AGE_45_54', 'AGE_55_100'.
Default: all 18+.
title: Target Age Groups
target_gender:
anyOf:
- type: string
- type: 'null'
default: GENDER_UNLIMITED
description: >-
Gender targeting: 'GENDER_UNLIMITED', 'GENDER_MALE',
'GENDER_FEMALE'.
title: Target Gender
target_locations:
anyOf:
- items:
type: string
type: array
- type: 'null'
default: null
description: >-
List of TikTok location IDs. Default: ['6252001']
(United States). Common IDs: USA=6252001, UK=2635167,
Canada=6251999, Australia=2077456.
title: Target Locations
tiktok_item_id:
anyOf:
- type: string
- type: 'null'
default: null
description: >-
TikTok organic post ID for Spark Ads. Boosts an existing
TikTok post as a paid ad. The post's video/content
becomes the ad creative. Get the post ID from TikTok Ads
Manager > Spark Ads. When using Spark Ads,
asset_bundle_id and existing_image_ids are NOT required.
title: Tiktok Item Id
video_download_disabled:
anyOf:
- type: boolean
- type: 'null'
default: null
description: >-
Disable video download on TikTok. Default: false (users
can download).
title: Video Download Disabled
required:
- campaign_name
- ad_text
- display_name
- landing_page_url
type: object
required:
- arguments
type: object
description: >-
All tool arguments are wrapped in an `arguments` object. The fields
accepted inside `arguments` are listed below — required fields are
marked with a red asterisk.
required: true
responses:
'200':
content:
application/json:
example:
data:
quota:
limit: 150
period_end: '2026-05-01'
tier: plus
used: 42
text: (tool-specific textual output for create_tiktok_campaign)
success: true
tool: create_tiktok_campaign
schema:
$ref: '#/components/schemas/SuccessResponse'
description: >-
Tool executed successfully. `data.text` carries the human-readable
result (markdown-friendly). `data.quota` shows your current usage
against the plan limit. `data.structured` appears when the tool
emits machine-parseable structured content. `data.content` appears
for tools that return non-text blocks (images, resources).
'400':
content:
application/json:
example:
error: >-
You have 25 meta_ads accounts connected. Please specify which
account to use by passing the ad_account_id parameter:
- Acme Holdings (ad_account_id="act_123456789")
- Acme EU (ad_account_id="act_987654321")
is_error: true
success: false
tool: create_tiktok_campaign
schema:
$ref: '#/components/schemas/ErrorResponse'
description: >-
Tool-level error. The `error` string is safe to surface to end
users. Common causes: missing required argument, multi-account user
didn't specify which account, upstream platform validation failure.
'401':
content:
application/json:
example:
error: >-
Not authenticated. Please connect your ADSMCP account first
at https://adsmcp.si
is_error: true
success: false
tool: create_tiktok_campaign
schema:
$ref: '#/components/schemas/ErrorResponse'
description: Invalid, expired, or revoked API key.
'402':
content:
application/json:
example:
error: |-
🚨 Monthly limit reached (150/150 tool calls on Plus tier).
Upgrade to Pro at https://adsmcp.si to keep building.
is_error: true
quota:
limit: 150
period_end: '2026-05-01'
tier: plus
upgrade_url: https://adsmcp.si
used: 150
success: false
tool: create_tiktok_campaign
schema:
$ref: '#/components/schemas/QuotaErrorResponse'
description: >-
Quota exhausted for the current billing period. The response
includes a `quota` block with the current used/limit/tier values and
an `upgrade_url` to move up a tier.
'404':
content:
application/json:
example:
error: 'Tool not found: create_tiktok_campaign'
is_error: true
success: false
tool: create_tiktok_campaign
schema:
$ref: '#/components/schemas/ErrorResponse'
description: Unknown tool_name. Check /openapi.json for the full catalog.
'429':
content:
application/json:
example:
error: >-
Upstream platform rate limit hit (Meta Business Use Case
throttle at 95%). Retry after 60 seconds.
is_error: true
success: false
tool: create_tiktok_campaign
schema:
$ref: '#/components/schemas/ErrorResponse'
description: >-
Rate-limited by the upstream ad platform (Meta, Google, LinkedIn,
TikTok). Retry with exponential backoff. Not the same as ADSMCP's
own quota — that returns 402.
'500':
content:
application/json:
example:
error: 'Internal error: RuntimeError'
is_error: true
success: false
tool: create_tiktok_campaign
schema:
$ref: '#/components/schemas/ErrorResponse'
description: >-
Unexpected server error. Report to [email protected] with
request_id.
security:
- ApiKeyAuth: []
components:
schemas:
SuccessResponse:
description: >-
Returned on HTTP 200. `data.text` is the primary human-readable output.
`data.quota` is always present for billable calls. `data.structured` is
set only when the tool emits machine-parseable structured content.
`data.content` is set only when the tool emits non-text content blocks.
properties:
data:
properties:
content:
description: Non-text content blocks (images, resources).
items:
$ref: '#/components/schemas/ContentBlock'
type: array
quota:
$ref: '#/components/schemas/QuotaBlock'
structured:
additionalProperties: true
description: >-
Machine-parseable structured content when the tool provides it
(e.g. account selection prompts, widget payloads).
type: object
text:
description: >-
Human-readable output. Markdown-friendly for tools that emit
formatted lists, tables, or recommendations.
type: string
required:
- text
type: object
success:
const: true
type: boolean
tool:
description: Echoed tool_name from the request URL.
type: string
required:
- success
- data
- tool
type: object
ErrorResponse:
description: >-
Returned on HTTP 4xx / 5xx (except 402 which uses `QuotaErrorResponse`).
`error` is always a human-readable string safe to surface to end users.
properties:
error:
description: Human-readable error message.
type: string
is_error:
const: true
type: boolean
structured_content:
additionalProperties: true
description: >-
Present when the underlying tool attached structured metadata to the
error (e.g. account-selection lists).
type: object
success:
const: false
type: boolean
tool:
type: string
required:
- success
- error
- tool
type: object
QuotaErrorResponse:
description: >-
Returned on HTTP 402 when the monthly quota is exhausted. Identical to
`ErrorResponse` but with an additional `quota` block.
properties:
error:
type: string
is_error:
const: true
type: boolean
quota:
$ref: '#/components/schemas/QuotaBlock'
success:
const: false
type: boolean
tool:
type: string
required:
- success
- error
- tool
- quota
type: object
ContentBlock:
additionalProperties: true
description: >-
A non-text content block. Rare today; tools that attach images,
resources, or widget payloads populate `data.content` with blocks of
this shape.
properties:
type:
example: image
type: string
required:
- type
type: object
QuotaBlock:
description: >-
Current quota state for the API key owner. Attached to every successful
billable response under `data.quota`, and to 402 errors under `quota`
(plus `upgrade_url`).
properties:
limit:
description: Tool call allowance for the current tier.
example: 150
type: integer
period_end:
description: When the monthly counter resets (ISO date).
example: '2026-05-01'
format: date
type: string
tier:
description: Subscription tier of the account that owns the API key.
enum:
- free
- plus
- pro
- max
example: plus
type: string
upgrade_url:
description: Upgrade link (present only on 402 quota errors).
format: uri
type: string
used:
description: Tool calls consumed this billing period.
example: 42
type: integer
required:
- used
- limit
- tier
- period_end
type: object
securitySchemes:
ApiKeyAuth:
bearerFormat: API Key (sk_live_...)
description: >-
API key from https://adsmcp.si/dashboard/api-tokens. Prefix `sk_live_`. Treat as a
secret — never commit.
scheme: bearer
type: http