> ## Documentation Index
> Fetch the complete documentation index at: https://www.adspirer.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create TikTok Campaign

> 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




## OpenAPI

````yaml /api-reference/openapi.json post /api/v1/tools/create_tiktok_campaign/execute
openapi: 3.1.0
info:
  contact:
    email: support@adspirer.com
    name: Adspirer Support
  description: >-
    REST endpoints for every Adspirer 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://adspirer.ai/keys.


    ## 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` — Adspirer 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: Adspirer REST API
  version: 1.0.0
servers:
  - description: Production
    url: https://api.adspirer.ai
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 Adspirer account first
                  at https://adspirer.ai
                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://adspirer.ai to keep building.
                is_error: true
                quota:
                  limit: 150
                  period_end: '2026-05-01'
                  tier: plus
                  upgrade_url: https://adspirer.ai
                  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 Adspirer'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 support@adspirer.com 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://adspirer.ai/keys. Prefix `sk_live_`. Treat as a
        secret — never commit.
      scheme: bearer
      type: http

````