TikTok Skills
Agent skills for safely transferring videos and photo posts through TikTok's official Content
Posting API. The first skill, tiktok-content-posting, defaults to an editable TikTok draft,
previews every operation before it writes, and verifies the asynchronous result instead of treating
an upload response as a published post.
Install
npx skills add L4A-ai/tiktok-skills --skill tiktok-content-posting --agent codex --yes
60-second zero-TikTok-write evaluation
Want to inspect a real posting plan before creating a TikTok app? The dry-run command below needs no
TikTok account, access token, or media file and makes no network request. The install command above
places the local Codex copy under .agents/skills/:
TIKTOK_SKILL_DIR="$PWD/.agents/skills/tiktok-content-posting"
env -u TIKTOK_ACCESS_TOKEN node "$TIKTOK_SKILL_DIR/scripts/tiktok-post.mjs" photos \
https://media.example.invalid/launch-1.webp \
https://media.example.invalid/launch-2.webp \
--expected-open-id EVAL_ONLY_NOT_A_REAL_ACCOUNT \
--title 'Launch notes' \
--description 'Two-frame product update.' \
--dry-run
Verify these exact facts in the JSON result:
dry_runistrue;executedandpublishedarefalse;- the mode is
draftand the preview contains two photos; account_info, URL reachability/redirect, and remote-media checks remainunchecked;creator_infoisnot_required, andurl_ownershipis exactlyunchecked_by_cli.
The CLI does not read a token, call TikTok, resolve the reserved .invalid URLs, initialize a post,
upload media, or create a draft. The URLs and account ID above are evaluation-only. Stop here—never
add --yes to this example. For a real post, continue with the account-bound workflow below.
Deterministic proof card showing a real dry run with no execution or publication and all remote checks left unchecked
Ran it? Submit the two-minute structured tester report.
Choose “installed and ran” only if you independently installed and actually ran
tiktok-content-posting for your own non-internal purpose. A count-eligible reporter must also
attest that they are not a maintainer, a maintainer's teammate, or an internal tester. Install-only
and failed attempts have separate non-counting outcomes. Report one concrete redacted mismatch—or
explicitly say all observed fields matched—without sharing tokens, account identifiers, private
URLs, media, or complete local paths.
The feed card below summarizes only the fixed tokenless dry-run. It is not evidence of adoption, TikTok authorization, upload, or publication. The PNG links to its inspectable SVG source.
tiktok-content-posting
The skill supports:
- local video upload and verified-server video URLs;
- photo posts from verified HTTPS URLs;
- inbox drafts for final editing in TikTok;
- Direct Post with explicit privacy, commercial, music-usage, and AIGC choices;
- token-bound account checks, creator-capability checks, and
publish_idstatus polling; - dry-run-by-default execution, with a reviewed plan ID and
--yesrequired for any media transfer.
It uses one account authorized by the user. It does not automate comments, likes, follows, account rotation, cookies, or TikTok's browser UI.
Quick start
Run these commands from the installed skill directory:
# Check local runtime, ffprobe availability, and whether a token is configured.
node scripts/tiktok-post.mjs doctor
# Resolve the token-bound account before planning a draft.
node scripts/tiktok-post.mjs account
# Plan a draft upload. This sends nothing.
node scripts/tiktok-post.mjs video ./launch.mp4 \
--expected-open-id '<open_id>'
# After the user reviews the media and exact plan, copy its confirmation_id.
node scripts/tiktok-post.mjs video ./launch.mp4 \
--expected-open-id '<open_id>' \
--confirm-plan '<confirmation_id>' \
--yes
# Check whether it reached the inbox, is processing, failed, or was published.
node scripts/tiktok-post.mjs status '<publish_id>'
Photo drafts use verified URLs:
node scripts/tiktok-post.mjs photos \
https://media.example.com/1.jpg \
https://media.example.com/2.jpg \
--expected-open-id '<open_id>'
Direct Post is deliberately more explicit:
node scripts/tiktok-post.mjs creator
node scripts/tiktok-post.mjs video ./launch.mp4 \
--mode direct \
--privacy SELF_ONLY \
--commercial none \
--expected-creator '<creator_username>'
# After approval, rerun with the same content options and add:
# --music-usage-confirmed --confirm-plan '<confirmation_id>' --yes
Use --aigc when the video requires TikTok's AI-generated-content disclosure.
TikTok setup and platform limits
This is not a zero-configuration uploader. The operator needs a TikTok developer app, an OAuth authorization from the destination creator, and the appropriate approved scope:
video.uploadfor inbox drafts;video.publishfor Direct Post.user.info.basicfor the token-bound draft account check.
The account command reads the current
token's open_id and display name; every draft plan requires that exact open_id and checks it
again before init, so changing accounts cannot silently redirect an approved upload.
Inject the resulting user access token as TIKTOK_ACCESS_TOKEN from a keychain or secret manager;
the CLI deliberately rejects token flags and does not implement OAuth refresh itself.
TikTok restricts unaudited Direct Post clients to private accounts and SELF_ONLY visibility.
Public Direct Post requires TikTok audit approval, and TikTok's current guidelines say an API client
must serve a broad creator-facing use case rather than exist only as an internal uploader for the
operator's own or team's accounts. The skill reports these boundaries; it does not work around them
with browser automation.
See the skill's references for setup, endpoint contracts, media limits, required consent, and dated evidence. The authoritative upstream documentation is TikTok's Content Posting API and Content Sharing Guidelines.
Safety model
Every video and photos command is a dry run unless --yes is present. A compliant workflow is:
doctor -> account for draft / creator for direct -> preview + plan ID -> confirmation -> execution -> status
The plan ID binds metadata, the draft account open_id or Direct Post username, URLs, and the
SHA-256 of a local video. Paid or third-party commercial posts additionally require an explicit
Branded Content Policy confirmation.
Draft delivery and publication are different outcomes. SEND_TO_USER_INBOX means the media is ready
for the user in TikTok; only a later completion state means the content was actually published.