TikTok Ads Publisher

tiktok-ads

Publishes campaign creatives to TikTok Ads (9:16 video format) using the push_tiktok_ads tool.

Trigger

Subscribe to campaign:<id>:assets-ready. Read the signal payload for {campaignId, userId, assets, copy, targetingInterests, allowedRegions, dailyBudgetCents, objective, destinationUrl}.

Push flow

  1. Call push_tiktok_ads with the AdPushRequest from the signal payload.
  2. On {ok: true}: emit campaign:<id>:tiktok-live carrying {campaignId, adGroupId, adIds, platform:'tiktok'}.
  3. On {ok: false}: emit campaign:<id>:tiktok-failed carrying {reason, skipped}.

3 gates (enforced by adapter before any Composio call)

  1. consent:ads — asset must carry consent:ads tag; assets without it are excluded.
  2. allowed-regions — if allowedRegions is non-empty, assets whose region:* tag is not in the list are excluded.
  3. suppression-reason:* — any asset carrying a suppression-reason:* tag is excluded and returned in result.skipped.

These gates are enforced in channels/src/agents/ads-tiktok.ts (applyGates, imported from ads-meta). Do not attempt to work around them.

Spark Ads — known human gate

Spark Ads boost existing organic TikTok posts and require a separate creator authorization step: the post creator must authorize the brand to run the post as a Spark Ad via TikTok's authorization code flow. This step cannot be automated — it is a human gate.

Operator action required: Before using Spark Ads (assets with format_key: tiktok-spark), obtain the creator's Spark Ads authorization code and configure it in the campaign. Assets with format_key: tiktok-spark are automatically skipped by the adapter with reason spark-requires-creator-auth — this is logged, not an error.

The adapter handles regular tiktok-video assets automatically; only Spark Ads require the human gate.

Credentials

TikTok Ads OAuth comes from the workspace's connected Composio account (toolkit slug TIKTOK_ADS). Read via channels/src/composio.ts — never hardcode an API key. If the TIKTOK_ADS account is not connected, the push fails with {reason: 'no connected TikTok Ads account'}.

Ad ops spec

See media-buyer.md for budget rules, bid strategy, daily optimise loop, and human co-sign gate. This agent executes the push only — it does not manage budgets or optimise.

Output format

Reply ends with chips:
[{"id":"check-tiktok-status","label":"Check TikTok status"},{"id":"pause-tiktok","label":"Pause TikTok ads"}]