Skip to content
douyin

CLI reference

Every flag and subcommand for douyin.

douyin reads public Douyin data through its public web surfaces: the hot-search billboard and the signed www.douyin.com/aweme/v1/web/* API. No API key is required. Read operations also work over HTTP (douyin serve) and MCP (douyin mcp).

Run douyin <command> --help for the exact flag list on any command.

Global flags

These apply to every command. Output is a table at a terminal and JSONL when piped.

  -o, --output string      output: auto|table|markdown|json|jsonl|csv|tsv|url|raw (default "auto")
      --fields strings     comma-separated columns to show
      --no-header          omit the header row
      --template string    Go text/template applied per record
  -n, --limit int          stop after N records (0 = no limit)
  -q, --quiet              suppress progress output
  -v, --verbose            increase verbosity (repeatable)
      --color string       color: auto|always|never (default "auto")
      --rate duration      minimum delay between requests
      --timeout duration   per-request timeout
      --retries int        retry attempts on rate limit or 5xx (default -1)
      --user-agent string  override the User-Agent sent with each request
      --no-cache           bypass on-disk caches
      --data-dir string    override the data directory
      --profile string     named profile to load
      --db string          tee every record into a store (e.g. out.db, postgres://...)
      --dry-run            print actions, do not perform them

Read commands

douyin hot

The Douyin hot-search billboard (抖音热搜), in rank order.

Usage:
  douyin hot [flags]

Flags:
      --tab string   billboard tab: realtime|video|music|star (default "realtime")

Fields: rank, word, hot_value, label, tab, url

The realtime tab is the open word billboard: a single anonymous GET returns the real trending phrases from any IP. The video, music, and star tabs hit the richer billboards, which are anti-bot-walled from non-China IPs. An empty list maps to exit 3 (no results) and a server block maps to exit 4 (needs auth); the command never prints an empty result as if it were data.

douyin video

One video record. Accepts a https://www.douyin.com/video/<id> URL or a bare numeric aweme id. Returns a single Video.

Usage:
  douyin video <url-or-id> [flags]

Fields include id, desc, create_time, author, author_id, author_sec_uid, music_id, music_title, music_author, hashtags, duration, cover, play_addr, download_addr, width, height, digg_count, share_count, comment_count, play_count, collect_count, url.

Walled: the signed aweme/detail call is anti-bot-walled from non-China and datacenter IPs. When walled it exits 4 (needs auth) with the residential-session hint, never a crash or faked data.

douyin user

A profile record, addressed by sec_uid. Accepts a https://www.douyin.com/user/<sec_uid> URL or a bare sec_uid (the long MS4wLjABAAAA... token). The visible Douyin number is not accepted as input, because the web API addresses users by sec_uid. Returns a single User.

Usage:
  douyin user <secuid-or-url> [flags]

Fields include id, sec_uid, unique_id, nickname, signature, verified, private, region, follower_count, following_count, total_favorited, aweme_count, favoriting_count, avatar, url.

Walled like video.

douyin posts

A user's public videos. Accepts the same input as user. Pages the signed aweme/post endpoint by cursor until there are no more or the limit is reached. Emits Video records.

Usage:
  douyin posts <secuid-or-url> [flags]

Flags:
      --cursor string   resume from a paging cursor

Walled like video.

douyin comments

Comments under a video. Accepts the same input as video. Pages the signed comment/list endpoint. Emits top-level Comment records.

Usage:
  douyin comments <url-or-id> [flags]

Fields: id, video_id, text, author, author_id, author_sec_uid, create_time, digg_count, reply_count, parent_id, url.

Walled like video.

Mixed search hits, videos and users. The query is variadic, so douyin search study with me is one query of three words. Emits SearchHit records.

Usage:
  douyin search [query...] [flags]

Fields: type (video or user), id, title, author, url.

Walled like video.

Escape-hatch and server commands

douyin raw

Fetch a url and print its body untouched. An inspection escape hatch: fetches one endpoint (the open billboard or a signed call) and prints its raw body to stdout, including an empty body when walled. Not a record stream, and not exposed over HTTP or MCP.

Usage:
  douyin raw <url> [flags]

douyin serve

Serve the read operations over HTTP (NDJSON). Each operation mounts at /v1/<command>; flags become query parameters and a positional argument can trail the path. The server also mounts GET /healthz and GET /v1/openapi.json.

Usage:
  douyin serve [flags]

Flags:
      --addr string    listen address (default ":8080")
      --allow-writes   expose write operations

douyin mcp

Run as an MCP server over stdio. Each read operation becomes an MCP tool whose argument schema is the operation's input struct.

Usage:
  douyin mcp [flags]

douyin completion

Generate the autocompletion script for bash, zsh, fish, or powershell.

Usage:
  douyin completion <shell>

douyin version

Print version information.

Usage:
  douyin version [flags]

Flags:
      --short   print just the version number

Exit codes

Code Meaning
0 ok
1 generic error
2 usage
3 no results
4 needs auth / anti-bot wall
5 rate limited
6 not found
7 unsupported
8 network

The walled signed surfaces and the non-realtime billboard tabs map to exit 4 (needs auth) when the server returns a block. That is the honest "this needs a residential session" outcome, distinct from a genuine empty result (exit 3) and from a missing record (exit 6).