tiktok

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2026 License: BSD-3-Clause Imports: 11 Imported by: 0

README

go-tiktok/tiktok

go-tiktok/tiktok

CI Go Reference

A pure-Go, dependency-free, best-effort read client for public TikTok content, talking to TikTok's undocumented web JSON endpoints.

  • CGO_ENABLED=0, standard library only, zero third-party dependencies.
  • Stable, small Go API with an overridable base URL for network-free testing.
  • 100% test coverage against a mock server.

⚠️ Fragility & Terms-of-Service caveat

Read this before depending on the library.

TikTok does not publish or support a public web API. This client calls the same internal endpoints TikTok's own website uses, and TikTok actively defends them. In practice you should expect:

  • The library computes the X-Bogus signature in pure Go (verified byte-for-byte against the public reference implementation) and folds it into every item_list / user/list request, but as of 2025/2026 X-Bogus alone is necessary yet not sufficient. TikTok additionally enforces a browser-minted msToken cookie — generated by its webmssdk.js via canvas/WebGL/audio fingerprinting — and a newer X-Gnarly signature, both of which depend on a real JavaScript runtime and cannot be forged in pure Go. Supply an msToken and a sessionid captured from your own logged-in browser via WithMSToken/WithSessionID.
  • With no valid msToken, a correctly signed request still receives an HTTP 200 with an empty body (TikTok's anti-bot block). This is the wall you will hit anonymously; it is not a bug in the signer.
  • The endpoint shape, parameters, and response schema can change without notice, breaking this library at any time.

This project is therefore best-effort: the code builds correctly signed requests and parses correct responses, but working end-to-end against live TikTok requires credentials this pure-Go client cannot mint itself, and is not something the maintainers can promise to keep working.

You are responsible for complying with TikTok's Terms of Service and all applicable law and rate limits. Do not use this for anything abusive, high-volume, or that TikTok's terms prohibit.

Install

go get github.com/go-tiktok/tiktok

Usage

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/go-tiktok/tiktok"
)

func main() {
	c := tiktok.New(
		tiktok.WithMSToken("...msToken from a browser session..."),
		tiktok.WithSessionID("...sessionid cookie for authed reads..."),
	)

	// secUid is TikTok's opaque per-user id; obtain it once from a profile
	// page's embedded JSON, then pass it here.
	feed, err := c.UserPosts(context.Background(), "MS4wLjABAAAA...", 20, "0")
	if err != nil {
		log.Fatal(err)
	}

	for _, v := range feed.Videos {
		fmt.Printf("%s  %d likes  %s\n", v.Permalink, v.Likes, v.Description)
	}
	fmt.Printf("cursor=%s hasMore=%v\n", feed.Cursor, feed.HasMore)
}

An empty page (no videos, HasMore == false) is returned without error. A non-2xx status, an empty/anti-bot body, or malformed JSON returns a descriptive error including the HTTP status where relevant.

API

Symbol Purpose
New(...Option) *Client Construct a client.
WithHTTPClient, WithBaseURL, WithUserAgent, WithMSToken, WithSessionID Options.
(*Client).UserPosts(ctx, secUid, count, cursor) (*UserFeed, error) Fetch a user's recent videos via the web item_list API.
(*Client).FollowingFeed(ctx, count, maxCursor) (*UserFeed, error) The authenticated viewer's following feed (needs session + msToken).
(*Client).Recommend(ctx, count, cursor) (*UserFeed, error) The "For You" / home recommend feed (needs msToken).
(*Client).Following(ctx, secUid, count, maxCursor) (*FollowingList, error) The accounts a user follows (user/list, scene=21).
(*Client).ProfileSecUID(ctx, username) (string, error) Resolve a public @handle to its opaque secUid (no signing needed).
(*Client).ViewerSecUID(ctx) (string, error) The logged-in viewer's own secUid (needs a sessionid).
XBogus(query, userAgent, unixSeconds) string The pure-Go X-Bogus signer.
Video, UserFeed, FollowingList, FollowedUser Result types.

License

BSD-3-Clause. Copyright the go-tiktok/tiktok authors. See LICENSE.

Documentation

Overview

Package tiktok is a pure-Go, dependency-free, best-effort read client for public TikTok content, talking to TikTok's undocumented web JSON endpoints.

Best-effort and fragile by nature

TikTok does not publish or support a stable public web API. The endpoints used here are the ones its own website calls, and TikTok actively defends them. This client computes the "X-Bogus" request signature in pure Go (see XBogus, verified against the public reference implementation) and folds it into every signed request, but X-Bogus alone is no longer sufficient: TikTok also requires a browser-minted msToken cookie and a newer "X-Gnarly" signature, both derived from JavaScript fingerprinting that cannot be reproduced without a browser. Supply an msToken and sessionid captured from a real logged-in browser via WithMSToken and WithSessionID. TikTok returns anti-bot responses (HTTP 403/429, or a 200 with an empty or "{}" body) when it decides a request looks automated.

Consequently this client is BEST-EFFORT: it builds correct requests and parses correct responses, but it can and will break without notice when TikTok changes its web API or tightens its bot defenses. Use it accordingly, respect TikTok's Terms of Service, and do not rely on it for anything critical. Supplying msToken via WithMSToken and a sessionid via WithSessionID improves — but does not guarantee — success.

Index

Constants

View Source
const DefaultBaseURL = "https://www.tiktok.com"

DefaultBaseURL is the default TikTok web origin.

View Source
const DefaultUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " +
	"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"

DefaultUserAgent is a plausible desktop browser User-Agent. TikTok inspects this header; an empty or obviously automated value is more likely blocked.

Variables

This section is empty.

Functions

func XBogus added in v0.3.0

func XBogus(query, userAgent string, unixSeconds int64) string

XBogus computes TikTok's X-Bogus signature for the given query string and User-Agent at the given Unix time (seconds). The returned value is the raw 28-character parameter (without the leading "X-Bogus=").

Types

type Client

type Client struct {
	// BaseURL is the TikTok web origin (default https://www.tiktok.com).
	BaseURL string
	// HTTPClient performs requests (default http.DefaultClient).
	HTTPClient *http.Client
	// UserAgent is sent as the User-Agent header.
	UserAgent string
	// MSToken is TikTok's msToken, sent as both a query param and a cookie
	// when non-empty.
	MSToken string
	// SessionID is the sessionid cookie for authenticated reads, sent when
	// non-empty.
	SessionID string
	// contains filtered or unexported fields
}

Client is a best-effort read client for public TikTok content.

A zero Client is not ready for use; construct one with New.

func New

func New(opts ...Option) *Client

New constructs a Client with the given options applied.

func (*Client) Following added in v0.2.0

func (c *Client) Following(ctx context.Context, secUid string, count int, maxCursor string) (*FollowingList, error)

Following fetches one page of the accounts secUid follows via TikTok's web user list API:

GET {BaseURL}/api/user/list/?scene=21&secUid=<secUid>&count=<n>&maxCursor=<c>&...

It sets the same web parameters, headers and cookies (User-Agent, Referer, sessionid, msToken) as Client.UserPosts. count is the requested page size and maxCursor is the pagination cursor ("0" or "" for the first page).

IMPORTANT — this is behind TikTok's request-signing wall. The endpoint requires a valid signed parameter (X-Bogus / _signature) derived from the viewer's own secUid, which a pure-Go client cannot forge. Unsigned, TikTok answers an anti-bot response — a non-2xx status, an empty body, or a 200 whose statusCode field is non-zero — each returned here as an error. A caller should treat that as "this needs a signed/authenticated request" rather than as a transient bug.

func (*Client) FollowingFeed added in v0.3.0

func (c *Client) FollowingFeed(ctx context.Context, count int, maxCursor string) (*UserFeed, error)

FollowingFeed fetches one page of the authenticated viewer's following feed — the videos from accounts they follow — via TikTok's web following item_list endpoint:

GET {BaseURL}/api/following/item_list/?count=<n>&maxCursor=<c>&...&X-Bogus=…

It requires a session (see WithSessionID) and a browser-minted msToken (see WithMSToken); without a valid msToken TikTok answers the anti-bot empty body even though the X-Bogus signature is correct — see the note on XBogus.

func (*Client) ProfileSecUID added in v0.3.0

func (c *Client) ProfileSecUID(ctx context.Context, username string) (string, error)

ProfileSecUID fetches a public profile page and returns that account's secUid (the opaque id Client.UserPosts and Client.Following take). username is the @handle without the leading "@". This needs no signing and works anonymously.

func (*Client) Recommend added in v0.3.0

func (c *Client) Recommend(ctx context.Context, count int, cursor string) (*UserFeed, error)

Recommend fetches one page of the "For You" / home recommend feed via TikTok's web recommend item_list endpoint:

GET {BaseURL}/api/recommend/item_list/?count=<n>&...&X-Bogus=…

Like Client.FollowingFeed it needs a browser-minted msToken to get past the anti-bot layer; the request is otherwise correctly signed.

func (*Client) UserPosts

func (c *Client) UserPosts(ctx context.Context, secUid string, count int, cursor string) (*UserFeed, error)

UserPosts fetches a user's recent videos via TikTok's web item_list API:

GET {BaseURL}/api/post/item_list/?secUid=<secUid>&count=<n>&cursor=<c>&...

The secUid is TikTok's opaque secondary user id; the caller obtains it once (for example from a profile page's embedded JSON) and passes it here. count is the requested page size and cursor is the pagination cursor ("0" or "" for the first page). Headers (User-Agent, Referer) and cookies (sessionid, msToken) are set when configured.

An empty result (no videos, HasMore=false) is returned without error. A non-2xx status, an empty/anti-bot body, or malformed JSON returns an error.

func (*Client) ViewerSecUID added in v0.3.0

func (c *Client) ViewerSecUID(ctx context.Context) (string, error)

ViewerSecUID returns the authenticated viewer's own secUid. It fetches a TikTok web app page carrying the session cookie and reads the viewer out of the embedded rehydration JSON's app-context. A session is required (see WithSessionID); without one, TikTok serves a logged-out page that carries no viewer identity and this returns an error.

type FollowedUser added in v0.2.0

type FollowedUser struct {
	SecUID   string // TikTok's opaque per-account id (the channel [Client.UserPosts] takes)
	UniqueID string // the @handle, without the "@"
	Nickname string // the display name ("" when the account sets none)
}

FollowedUser is one account the viewer follows, as returned by the user list.

type FollowingList added in v0.2.0

type FollowingList struct {
	Users     []FollowedUser
	MaxCursor string
	HasMore   bool
}

FollowingList is one page of the viewer's following list. MaxCursor is the pagination cursor to pass on the next call, and HasMore reports whether another page exists.

type Option

type Option func(*Client)

Option configures a Client.

func WithBaseURL

func WithBaseURL(u string) Option

WithBaseURL overrides the TikTok web origin (useful for testing).

func WithHTTPClient

func WithHTTPClient(h *http.Client) Option

WithHTTPClient sets the underlying http.Client.

func WithMSToken

func WithMSToken(t string) Option

WithMSToken sets the msToken query param / cookie.

func WithSessionID

func WithSessionID(s string) Option

WithSessionID sets the sessionid cookie for authenticated reads.

func WithUserAgent

func WithUserAgent(ua string) Option

WithUserAgent overrides the User-Agent header.

type UserFeed

type UserFeed struct {
	Username string
	Videos   []Video
	Cursor   string
	HasMore  bool
}

UserFeed is a page of a user's videos.

type Video

type Video struct {
	ID          string
	Description string
	Author      string // unique_id / username
	Permalink   string // https://www.tiktok.com/@<author>/video/<id>
	CoverURL    string // thumbnail
	PlayURL     string // video URL (often expiring)
	Likes       int
	Comments    int
	Shares      int
	Plays       int
	CreateTime  time.Time
}

Video is a single public TikTok video.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL