tiktok-web-signature: computing TikTok's request signatures in Python
tiktok web signature reverse engineer generates valid tiktok signatures for API requets
At a glance
- What is it?
- tiktok-web-signature is a pure Python reimplementation of the signature headers TikTok's web app sends, so a script can call the web API without a browser. It is a precise piece of reverse engineering pinned to one SDK build, and it goes stale the moment TikTok ships a new one.
- Who is it for?
- tiktok-web-signature suits a developer who needs to sign TikTok web API requests from Python without shipping a browser, and the fact that it computes everything offline with no external calls and no dependencies makes it easy to drop into an existing service.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 13 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A header you can compute instead of a browser you have to drive
TikTok's web app signs its API requests. Every call carries headers such as X-Dynosaur, X-Gnarly and X-Bogus, and the server refuses requests whose signature does not match the query, the body and the client context. That is a good design for a site that wants to make automated access hard.
This repository is a reimplementation of that signing algorithm, written in Python, so a script can produce the headers itself. The author describes it as a fully reverse-engineered generator that produces valid X-Gnarly, X-Bogus and X-Dynosaur signatures, and states that requests signed with these generators come back with a success status. Nothing is fetched to make that happen: the whole computation happens locally, and no external API calls appear in the feature list.
The method is described rather than asserted. The algorithm was recovered by deobfuscating the production webmssdk.js bundle, by static analysis of the ChaCha-based cipher, by dynamic tracing of signature generation at runtime, and by byte-level reconstruction of the payload serialization format, with the result checked against live TikTok API responses. The target is SDK version 5.3.2, build 1.0.0.417.
The audience is narrow and specific: a developer building an automated client for the web API in Python, who would otherwise have to drive a real browser to get a valid header. The library is not an API client. It signs; what you send afterwards is up to you.
The file layout is three modules with no package structure around them, which tells you how small this is: x_dynosaur.py for the X-Dynosaur generator, x_gnarly.py for X-Gnarly, and x_bogus.py, which the documentation describes as a placeholder for legacy compatibility rather than a working implementation.
One cipher, two payload layouts, and a shuffled field order
Both signature types are built on the same ChaCha-based cipher. The documented parameters are four constants, a list of 1196819126, 600974999, 3863347763 and 1451689750, twelve key words derived from a PRNG, a round count computed as the low nibble of the key sum plus five, and an insert position derived from the sum of the key bytes and the sum of the cipher modulo the cipher length plus one.
What differs is the payload and the ordering. X-Dynosaur uses 56 fields with tags from 0x20 to 0x38, carrying the timestamp, session value, canvas fingerprint and environment code, FNV-1a hashes of the query, the body and the user agent, the version strings, and a checksum field at 0x20. X-Gnarly uses 16 fields with indexes 0 to 16, carrying MD5 digests of the same three inputs along with the timestamp, session value, canvas and version strings, and it finishes with XOR checksum fields.
The field order in the X-Gnarly payload is not fixed. Fields are shuffled using a PRNG seeded from the f8 value before serialization, which is one reason two runs with similar inputs do not produce identical output.
The output is then encoded with a custom Base64 alphabet rather than the standard one, and that 64-character alphabet is printed in the README notes. The generated token is not a fixed length. The documentation says it varies between 230 and 420 characters depending on payload content, field values, PRNG randomness and Base64 padding, and states that this is expected rather than a defect.
The X-Bogus generator, by contrast, is listed only as a placeholder for legacy compatibility, so treat it as a stub rather than a working third signature.
Cloning it and producing a first signature
There is nothing to install in the usual sense. The author states that there are no dependencies beyond the Python standard library, and the installation step is a clone:
git clone https://github.com/n1tr00-10/tiktok-web-signature.git
cd tiktok-web-signatureGenerating an X-Dynosaur token takes a query string, a user agent and a request body:
from x_dynosaur import get_x_dynosaur
query = "aid=1988&app_name=tiktok_web&device_platform=web_pc"
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36"
body = ""
token = get_x_dynosaur(query, user_agent, body)
print(token)The X-Gnarly generator takes the same inputs, and note that its user agent and body are passed as keyword arguments:
from x_gnarly import get_x_gnarly
query = "aid=1988&app_name=tiktok_web&device_platform=web_pc"
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36"
body = ""
token = get_x_gnarly(query, user_agent=user_agent, body=body)
print(token)The two are meant to be combined, because the X-Gnarly call takes the X-Dynosaur token as one of its inputs. The full request example in the README builds both and puts them in the headers:
import requests
from x_dynosaur import get_x_dynosaur
from x_gnarly import get_x_gnarly
query = "aid=1988&app_name=tiktok_web&device_platform=web_pc"
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36"
body = ""
dynosaur = get_x_dynosaur(query, ua, body)
gnarly = get_x_gnarly(query, dynosaur, "", ua, body)
headers = {
"User-Agent": ua,
"X-Dynosaur": dynosaur,
"X-Gnarly": gnarly,
}The requests import in that example is the only thing outside the standard library, and it is not a dependency of the library itself.
The parameters you can change, and the ones that break it
The generators expose a set of optional parameters, and the defaults are the ones that matter. The timestamp defaults to the current Unix time, the f8 field to a 32-bit session value, the canvas fingerprint to 2316120563, the environment code to 65, the version to 5.3.2 and the SCM version to 1.0.0.417. A security flag and two width flags, one 32-bit and one 125-bit, default to zero, and the page URL and referer default to www.tiktok.com/. The proof-of-work result defaults to the string 0, and the twelve ChaCha key words can be supplied as a custom random value.
One of these has a direct consequence for how you use the library. TikTok validates the timestamp embedded in the signature, according to the author, so signatures expire, and fresh ones should be generated for each request. This is the difference between a signature generator and a session: there is no long-lived token to cache here, because a cached one goes stale.
No session identifier is required. The documentation answers that question directly: signatures are generated locally and do not require authentication. A request signed this way is signed, but it is not logged in, and the difference matters for anything behind a login.
The version pinning is the other constraint worth internalising. The library targets one SDK version and one build, and the version string it emits is part of the signed payload. When TikTok ships a new webmssdk.js, the constants, the field layout and the version strings baked into the algorithm may all change at once, and a stale library will start producing signatures the server rejects with no obvious signal that the cause is version drift rather than a bug in your request.
The version table in the README lists the pieces the algorithm is tied to: SDK 5.3.2, SCM version 1.0.0.417, SCM sub version 1.0.0.2858, release build 1.0.0.417, and a Slardar SDK version of 1.16.6. That table is the thing to re-check when something stops working.
Where this approach stops being the right answer
The first limitation is the version coupling, and it is structural rather than a missing feature. A signature algorithm is only correct for the client that implements it, so this library tracks one SDK build. There is no mechanism for detecting that TikTok has moved on, and the failure mode is silent rejection of your requests rather than a clear error. For a script that runs once, that is tolerable. For anything running on a schedule, it is a recurring maintenance item with an unpredictable trigger.
The second is scope. The library signs requests and does nothing else. It does not implement endpoints, manage sessions, handle the msToken that the documentation shows being updated from a response, or deal with rate limits and retries. Anything you build on top is your code to maintain.
The third is the legal and terms question, which the project itself raises. Its own FAQ asks whether the signatures can be used for automation and answers yes, but always respecting TikTok's terms of service and rate limits. Reverse engineering for interoperability and building a tool whose purpose is to defeat an anti-automation control are not the same activity, and the boundary between them is set by TikTok rather than by the code. Check where your use sits before shipping it in a product.
The fourth is verification. The author reports that signatures were verified against live TikTok API endpoints, with an HTTP 200 and a status_code of 0 response, and the verification section prints a captured token. That is a report of a check performed by the project, not a guarantee that the algorithm is correct for the version you are running today, and the token lengths in the documentation are the clearest sign that the output is sensitive to inputs in ways that are hard to reason about. A library with no dependencies and no test suite in the repository listing has little to catch a regression.
Editorial conclusion
tiktok-web-signature suits a developer who needs to sign TikTok web API requests from Python without shipping a browser, and the fact that it computes everything offline with no external calls and no dependencies makes it easy to drop into an existing service. It is the wrong choice if you need endpoints the library does not cover, if you cannot accept that a signature scheme tied to one SDK build breaks without warning, or if your use of the TikTok API falls outside its terms of service. Before relying on it, generate a signature for a request you already make through a browser and compare the headers, check that the pinned SDK version 5.3.2 and build 1.0.0.417 still match what TikTok serves, and confirm the last push was recent enough for your needs, since the repository was last pushed on 2026-10-09 and ships no tagged releases.
Frequently asked questions
How do I install tiktok-web-signature?
Clone the repository with git clone https://github.com/n1tr00-10/tiktok-web-signature.git and change into the directory. There is nothing to install, because the library has no dependencies beyond the Python standard library.
Which TikTok signature formats does the library generate?
It generates X-Dynosaur using ChaCha20 encryption with FNV-1a hashing, X-Gnarly using ChaCha20 encryption with MD5 digests and a PRNG shuffle, and an X-Bogus placeholder kept for legacy compatibility.
Do the generated TikTok signatures expire?
Yes. TikTok validates the timestamp embedded in the signature, so fresh signatures should be generated for each request rather than cached.
Do I need a session ID to sign TikTok requests?
No. The documentation states that signatures are generated locally and do not require authentication, which also means a signed request is not the same as an authenticated one.
Which TikTok SDK version does this support?
SDK 5.3.2, build 1.0.0.417, with an SCM sub version of 1.0.0.2858 and a Slardar SDK version of 1.16.6 listed in the version table.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/n1tr00-10-tiktok-web-signature)Was this useful?