TikTok

May 7, 2026 ยท View on GitHub

Mode: ๐Ÿ” Browser ยท Domain: tiktok.com

Commands

CommandDescription
opencli tiktok profileGet user profile info
opencli tiktok searchSearch videos
opencli tiktok exploreTrending videos from explore page
opencli tiktok userGet recent videos from a user via page-context APIs
opencli tiktok followingList accounts you follow
opencli tiktok friendsFriend suggestions
opencli tiktok liveBrowse live streams
opencli tiktok notificationsGet notifications
opencli tiktok creator-videosList TikTok Studio creator videos and metrics
opencli tiktok likeLike a video
opencli tiktok unlikeUnlike a video
opencli tiktok saveAdd to Favorites
opencli tiktok unsaveRemove from Favorites
opencli tiktok followFollow a user
opencli tiktok unfollowUnfollow a user
opencli tiktok commentComment on a video

Usage Examples

# View a user's profile
opencli tiktok profile --username tiktok

# Search videos
opencli tiktok search "cooking" --limit 10

# Trending explore videos
opencli tiktok explore --limit 20

# Recent videos from a user
opencli tiktok user dictogo --limit 20

# Browse live streams
opencli tiktok live --limit 10

# List who you follow
opencli tiktok following

# List your TikTok Studio creator videos
opencli tiktok creator-videos --limit 20

# Friend suggestions
opencli tiktok friends --limit 10

# Like/unlike a video
opencli tiktok like "https://www.tiktok.com/@user/video/123"
opencli tiktok unlike "https://www.tiktok.com/@user/video/123"

# Save/unsave (Favorites)
opencli tiktok save "https://www.tiktok.com/@user/video/123"
opencli tiktok unsave "https://www.tiktok.com/@user/video/123"

# Follow/unfollow
opencli tiktok follow nasa
opencli tiktok unfollow nasa

# Comment on a video
opencli tiktok comment "https://www.tiktok.com/@user/video/123" "Great!"

# JSON output
opencli tiktok profile --username tiktok -f json

Output

explore

ColumnTypeNotes
indexint1-based position in the recommend feed
idstringTikTok video id; round-trips into video URL
authorstringuniqueId of the video author (without @)
urlstringCanonical https://www.tiktok.com/@author/video/id
coverstringCover image URL (may be empty)
titlestringCleaned description (synonym of desc)
descstringCleaned description (whitespace collapsed, โ‰ค500 chars)
playsint | nullPlay count (null if upstream did not expose)
likesint | nullDigg count
commentsint | nullComment count
sharesint | nullShare count
createTimeint | nullUnix seconds when the video was posted

user

Same video columns as explore, plus:

ColumnTypeNotes
sourcestringprofile-api, bootstrap, or lower-authority search-fallback

user resolves the profile secUid, pages /api/post/item_list/, and uses exact-author /api/search/general/full/ only as a fallback when profile data is short. source lets callers distinguish first-party profile rows from fallback search rows.

friends

ColumnTypeNotes
indexint1-based position in the suggestion list
usernamestringuniqueId of the suggested account (no @)
namestringDisplay nickname (falls back to username)
secUidstringTikTok internal stable id (round-trips into other endpoints)
verifiedbooltrue when the account carries a verified badge
followersint | nullFollower count if exposed by the suggestion payload
followingint | nullFollowing count if exposed
urlstringCanonical profile URL

following

Same column shape as friends. secUid and follower / following counts come from /api/user/list/?scene=21 (TikTok's own following endpoint), which is the same data their web client renders on the page.

notifications

ColumnTypeNotes
indexint1-based position
idstringNotice id (or idx-<n> fallback when upstream omits)
fromstringuniqueId of the actor (without @); empty for system notices
textstringCleaned notice text (โ‰ค220 chars)
createTimeint | nullUnix seconds when the notice fired

--type accepts all / likes / comments / mentions / followers (any other value raises ArgumentError, no silent default).

live

ColumnTypeNotes
indexint1-based position
streamerstringHost's uniqueId (without @)
namestringHost's display nickname
titlestringStream title (โ‰ค200 chars, whitespace collapsed)
viewersint | nullCurrent viewer count
likesint | nullCumulative like count for the room
secUidstringHost's TikTok internal stable id
urlstringCanonical /@streamer/live URL

comment / follow / unfollow (write commands)

These three commands click the live UI button + verify the post-click state before returning. They never return a silent failure row โ€” every failure path raises a typed error. The result enum makes idempotent fast paths (already-following / already-not-following / already-friends) explicit, so callers can distinguish "we just did it" from "it was already done".

comment

ColumnTypeNotes
urlstringCanonical video URL the comment was posted on
textstringComment text actually submitted (trimmed, โ‰ค150 chars)
resultenumposted (only โ€” TikTok permits duplicate comments, no idempotent fast path)

follow

ColumnTypeNotes
usernamestringTarget user's uniqueId (without @)
urlstringCanonical profile URL
resultenumfollowed / already-following / already-friends (mutual)

unfollow

ColumnTypeNotes
usernamestringTarget user's uniqueId (without @)
urlstringCanonical profile URL
resultenumunfollowed / already-not-following

Validation (no silent clamp)

--limit is validated upfront and ArgumentError is thrown for 0, negative, non-integer or out-of-range values โ€” no silent clamp to the cap. Per-command caps:

CommandDefaultMax
explore20120
user20120
friends20100
following20200
notifications15100
live1060

null semantics: a numeric column returning null means upstream did not expose that field on this row (e.g. some live cards omit like_count). A column never returns 0 as an unknown sentinel. Authentication / empty result states raise AuthRequiredError / EmptyResultError instead of returning empty rows โ€” callers can treat any returned row as real data.

Write commands โ€” typed errors and retryability

comment / follow / unfollow validate input upfront and verify post-click state. Failure modes:

FailureTyped errorretryable (in hint)
Empty / overlong / malformed inputArgumentErrorn/a
Not logged in (no session cookie + no viewer secUid)AuthRequiredErrorn/a
Required button missing (UI changed, blocked, private account)CommandExecutionErrorfollow / unfollow: true (idempotent); comment: false
State did not flip within timeout (likes/follows count unchanged)CommandExecutionErrorfollow / unfollow: true; comment: false
Captcha / rate-limit popup detectedCommandExecutionErrorsame as above

The retryable= flag is encoded in the error hint string in the form retryable=<true\|false> reason=<...> so downstream agents and scripts can grep it without parsing structured metadata. Comment is retryable=false because the server may still have accepted the comment when our state-verify times out (server-fan-out semantics) โ€” auto-retrying would double-post. Follow / unfollow are retryable=true because TikTok dedupes the relation flip server-side, so a transient blip can be safely retried.

Importing retryable as a first-class metadata layer in OpenCLI core is a candidate for follow-up โ€” for now we keep the contract human-readable.

Implementation Notes

explore / user / friends / following / notifications / live all run inside the live page (Strategy.COOKIE + browser: true) and call TikTok's own internal JSON endpoints with fetch(..., { credentials: 'include' }). The session cookie + msToken come from the logged-in browser, the same way TikTok's web client requests them. Each command first reads the warm __UNIVERSAL_DATA_FOR_REHYDRATION__ snapshot for fast first-page results, then falls back to the corresponding API endpoint when more rows are requested (/api/recommend/item_list/, /api/user/detail/, /api/post/item_list/, /api/search/general/full/, /api/recommend/user/, /api/user/list/, /api/notice/multi/, /api/live/discover/get/).

This refactor applies the page-context API baseline across TikTok read commands: typed errors, full numeric stats columns, and no DOM-link scraping.

comment / follow / unfollow (Route 1) keep the UI button as the trigger and harden every transition with state verification + typed errors. We do not call /api/commit/follow/user/ or /api/comment/publish/ directly: those endpoints require X-Bogus signing engineering, which is a separate scope. The IIFE checks sessionid/sid_tt cookies and the __UNIVERSAL_DATA_FOR_REHYDRATION__ viewer snapshot for logged-in state, then asserts a button-text flip (Follow โ†’ Following etc.) or comment-list delta within 5โ€“8 seconds. Captcha / rate-limit popups (.secsdk-captcha-wrapper, "Too many requests" body text) are detected both before and after the click so a flash captcha cannot masquerade as a successful state transition.

Prerequisites

  • Chrome running and logged into tiktok.com
  • Browser Bridge extension installed
  • creator-videos requires access to TikTok Studio for the logged-in creator account