Skip to main content

autotok — TikTok Auto Uploader

TiktokAutoUploader logo

Upload and schedule TikTok videos from the command line or Python, with a proxy per account.

uv tool install autotok · one login · one command per upload

PyPI CI License: AGPL-3.0 LinkedIn Stars Forks


Sponsors

Swiftproxy — 90M+ residential proxies

Swiftproxy provides 90M+ clean residential and static residential proxies designed for social media automation, multi-account management, and web automation workflows. With stable connections, global IP coverage, and reliable proxy infrastructure, Swiftproxy helps users manage multiple accounts securely, reduce IP-related restrictions, and scale their automation tasks. Residential proxy traffic never expires until used, and free testing is available.

Get 10% off with code PROXY90 — Get proxies from Swiftproxy →


Termius

Termius provides a secure, reliable, and collaborative SSH client.

Get Termius →


Features

  • One-command uploads through TikTok's web upload API. No clicking through the TikTok website.
  • Proxy per account: login, request signing and every upload go through the same proxy, so each account always appears from one IP. HTTP(S) and SOCKS5 are supported.
  • Multiple accounts: log in once per account and upload by name.
  • Scheduling: TikTok-side scheduling from 15 minutes to 10 days ahead. The self-hosted web app adds a scheduler with no time limit.
  • Post settings: public or private, and comments, duets, stitches and the AI-generated label on or off.
  • Clickable hashtags and @mentions, emoji-safe.
  • YouTube links download automatically with yt-dlp.
  • Python SDK, CLI, and an optional web app (Docker) with a browser-based login.
  • Cloud browsers: run the login and signing browser on Browserbase or Steel (cloud or self-hosted) instead of your computer.
  • Docker image for running the CLI on servers.
  • No Node.js: TikTok's request signatures are computed in headless Chromium.

Getting started

Setup takes about five minutes.

1. Install autotok

uv tool install "autotok[youtube]"

That's it: autotok is now a command you can run from any terminal (check with autotok --version). uv keeps autotok separate from your other Python packages, and downloads Python for you if you don't have it.

Don't have uv? Install it with one line from docs.astral.sh/uv, or use pipx: pipx install "autotok[youtube]".

  • Update later: uv tool upgrade autotok.
  • Try it without installing: uvx --from "autotok[youtube]" autotok --version.
  • Using autotok from Python code? Add it to your project: uv add "autotok[youtube]" or pip install "autotok[youtube]".
  • [youtube] adds YouTube-link support. Leave it out if you don't need it.
  • autotok "not recognized" or "command not found"? Run uv tool update-shell once and open a new terminal.

2. Choose where the browser runs

autotok uses a browser for the one-time login and to sign each upload. Pick one:

Option Best for Setup
Local (default) Your own computer autotok install-browser, a one-time download of about 300 MB
Cloud (Browserbase or Steel) Servers, Docker, or keeping your computer free Add an API key to a settings file. See Cloud browsers

For the local browser on a fresh Linux server, run autotok install-browser --with-deps as root, which also installs Chromium's system libraries.

3. Log in to TikTok (once per account)

autotok login -n my_account

A browser window opens on TikTok's login page. Log in however you like; the QR code with the TikTok app on your phone is quickest. The window closes by itself and the session is saved as my_account. With a cloud browser you get a link to open instead.

autotok accounts check my_account     # confirms TikTok accepts the saved session
  • Going to use a proxy for this account? Pass it now, so the login and later uploads share one IP: autotok login -n my_account -p http://user:pass@host:port (see Proxies).
  • Repeat with a different -n name for each account.
  • Sessions are saved in ~/.autotok/accounts. Treat them like passwords.

4. Upload

autotok upload -u my_account -v "C:\Videos\clip.mp4" -t "My caption #fyp"

That's it. More examples:

autotok upload -u my_account -v clip.mp4 -t "Just for me" -vi 1                 # private
autotok upload -u my_account -v clip.mp4 -t "Later #fyp" -sc 3600               # publish in 1 hour
autotok upload -u my_account -yt "https://www.youtube.com/shorts/xxxxxxxxxxx" -t "Caption"

-v takes a path to any video, or just a file name if the video is in ~/.autotok/videos. See the CLI reference for every option.

5. Optional: save your settings in a file

Settings such as a cloud browser or its API key go in a .env file. autotok looks in the folder you run it from, then in ~/.autotok/.env; the second location works from any folder. Copy .env.example (from this repository) or start with just what you need:

# ~/.autotok/.env   (Windows: C:\Users\<you>\.autotok\.env)
AUTOTOK_BROWSER=browserbase
BROWSERBASE_API_KEY=bb_live_...

Where next?

I want to... See
Run several accounts, each with its own IP Proxies
Avoid running a browser on my computer Cloud browsers
Upload from Python code Python SDK
Run on a server or in a container Docker
Use a web dashboard with a scheduler Web app
Fix an error Troubleshooting

Proxies

Running several accounts from one IP is the quickest way to get them flagged. autotok lets you give every account its own proxy, and uses it everywhere that account talks to TikTok:

Step Goes through the account's proxy
Login browser (autotok login, web app login) ✅
Signature page fetch ✅ (the signing browser itself makes no network requests)
Upload API calls and video transfer ✅
YouTube downloads ❌ (not TikTok traffic; saves proxy bandwidth)

Set, change and test proxies

autotok login -n alice -p http://user:pass@gate.example.com:7000   # set at login
autotok proxy set alice socks5://user:pass@gate.example.com:1080     # set or change later
autotok proxy test -u alice                                          # shows the IP TikTok will see
autotok proxy clear alice                                            # go direct
autotok accounts list                                                # every account and its proxy (passwords hidden)

autotok upload -u alice -v clip.mp4 -t "hi" -p http://other:pass@host:8000   # one-off override
autotok upload -u alice -v clip.mp4 -t "hi" --no-proxy                       # ignore the saved proxy once

Accepted formats (scheme defaults to http)

http://user:pass@host:port      https://user:pass@host:port
socks5://user:pass@host:port    host:port
user:pass@host:port             host:port:user:pass      ← the export format most providers use

Tips

  • Use residential or mobile proxies, one per account, with a sticky session (same IP for hours). A proxy that rotates the IP on every request makes a logged-in session look hijacked.
  • Log in through the proxy you will upload with (autotok login -p ...). Logging in from home and uploading from a proxy is a mismatch TikTok can see.
  • Chromium can't use SOCKS5 proxies that need a username and password. For the login step, use your provider's HTTP endpoint (uploads work with either).
  • Passwords are never printed: the CLI and web app show http://user:****@host:port.

Need proxies? See our sponsors.


Cloud browsers (Browserbase, Steel)

autotok needs a browser in two places: the one-time login, and signing each upload (TikTok's anti-bot signatures are computed in a browser page). By default that's Chromium on your machine. Set AUTOTOK_BROWSER to run it in the cloud instead. Nothing then needs to be installed or opened locally, which makes it a good fit for servers and Docker.

AUTOTOK_BROWSER Where the browser runs Settings
local (default) Chromium on this machine autotok install-browser once
browserbase Browserbase BROWSERBASE_API_KEY (optional BROWSERBASE_PROJECT_ID, BROWSERBASE_REGION)
steel Steel Cloud, or your own steel-browser server Cloud: STEEL_API_KEY. Self-hosted: STEEL_BASE_URL, e.g. http://localhost:3000

Put the settings in your .env file (copy .env.example):

AUTOTOK_BROWSER=browserbase
BROWSERBASE_API_KEY=bb_live_...

Then use autotok as usual:

autotok browser check                 # starts a session and shows the IP it browses from
autotok login -n alice -p http://user:pass@gate.example.com:7000
autotok upload -u alice -v clip.mp4 -t "Hello #fyp"

Or pick per command: autotok --browser steel login -n alice.

Logging in: autotok login prints a live-view link and opens it in your normal browser. Log in to TikTok in that page; the session is saved as soon as you're in and the cloud browser is closed.

Self-hosted Steel is free and open source:

docker run -p 3000:3000 -e DOMAIN=localhost:3000 ghcr.io/steel-dev/steel-browser

and in .env:

AUTOTOK_BROWSER=steel
STEEL_BASE_URL=http://localhost:3000

Set DOMAIN to the address you reach the server at. Without it, steel-browser tells browsers to connect to 0.0.0.0 and its live view stays blank, so you can't log in. autotok warns when it sees this. A self-hosted steel-browser runs one session at a time.

Good to know:

  • Use an account proxy with cloud logins. The account's proxy is applied to the cloud login session, so TikTok sees the same IP at login and upload. Without one, TikTok sees the login come from the provider's IP and uploads come from yours.
  • "Verify it's really you" after logging in means TikTok saw an unfamiliar device on a datacenter IP. You can complete it in the live view, but it's better to avoid it: use an account proxy, or on a paid Browserbase plan set BROWSERBASE_PROXY_COUNTRY=GB (your country) to log in through a home IP there. On the free plan, BROWSERBASE_REGION set to the region nearest you (e.g. eu-central-1) at least avoids a US login.
  • The live view shows only the TikTok tab, so autotok closes popups such as "Continue with Google" during cloud logins. Use the QR code, email/username or phone instead.
  • Browserbase only takes HTTP/HTTPS proxies, and custom proxies need its Developer plan or higher. Custom proxies on Steel Cloud may need a paid plan too.
  • Only the browser runs in the cloud. The video file still goes from your machine (through the account proxy) straight to TikTok, so cloud usage stays small: one short session per login and per upload.
  • Want another provider? Subclass autotok.browsers.CloudProvider and call autotok.browsers.register_provider("name", YourProvider).

Python SDK

import autotok

autotok.login("alice", proxy="http://user:pass@gate.example.com:7000")   # once; opens a browser

result = autotok.upload_video("alice", "clip.mp4", "Hello #fyp")
print(result.video_id)

# More control: reuse a client, set post options, schedule
from datetime import datetime, timedelta, timezone

client = autotok.Client.from_account("alice")          # uses alice's saved proxy
client.upload(
    "clip.mp4",
    "Going live tomorrow #fyp @friend",
    schedule=datetime.now(timezone.utc) + timedelta(days=1),   # or seconds, or a timedelta
    visibility="public",            # or "private"
    allow_comment=True,
    allow_duet=False,
    allow_stitch=False,
    ai_label=False,
)

# Errors are typed; `retryable` is True only when nothing reached TikTok's publish step.
try:
    client.upload("clip.mp4", "caption")
except autotok.PublishError as e:          # TikTok rejected the post (e.g. guidelines)
    print(e.status_code, e.status_msg)
except autotok.AutotokError as e:
    print("failed:", e, "safe to retry:", e.retryable)

Already have a sessionid cookie from your browser? Skip the login window:

autotok.import_session("alice", "<sessionid value>", datacenter="<tt-target-idc value>")

CLI reference

autotok login     -n NAME [-p PROXY] [--force] [--sessionid ID --datacenter DC]
autotok upload    -u NAME (-v FILE | -yt URL) -t CAPTION [options]
autotok accounts  list | check NAME | remove NAME
autotok proxy     set NAME PROXY | clear NAME | test [PROXY | -u NAME]
autotok show      -u (accounts) | -v (videos)
autotok browser check [-u NAME]       # test the local or cloud browser
autotok install-browser [--with-deps]
autotok shell                         # interactive prompt

autotok --browser {local,browserbase,steel} <command> ...   # choose where the browser runs

Upload options:

Flag Description Default
-u / --user Saved account name required
-v / --video Video file (path or name in your videos folder) —
-yt / --youtube YouTube URL to download and upload —
-t / --title Caption, up to 2200 characters required
-sc / --schedule Publish this many seconds from now (900–864000) now
-vi / --visibility 0 public, 1 private 0
-ct / --comment Allow comments (0/1) 1
-d / --duet Allow duets (0/1) 0
-st / --stitch Allow stitches (0/1) 0
-ai / --ailabel Label as AI-generated (0/1) 0
-p / --proxy Proxy for this upload only account's proxy
--no-proxy Ignore the account's saved proxy —

python cli.py ... in this repository still works and is the same as autotok ....


Docker

The Dockerfile in the repository builds the CLI with Chromium included:

docker build -t autotok .

docker run --rm -it -v autotok-data:/data autotok accounts list
docker run --rm -it -v autotok-data:/data -v "$PWD/videos:/data/videos" \
  autotok upload -u alice -v clip.mp4 -t "Hello #fyp"

Saved accounts live in /data, so keep it in a volume. Containers have no screen, so log in with a cloud browser and open the link it prints:

docker run --rm -it -v autotok-data:/data \
  -e AUTOTOK_BROWSER=browserbase -e BROWSERBASE_API_KEY=bb_live_... \
  autotok login -n alice -p http://user:pass@gate.example.com:7000

You can also save a session cookie from your own browser with login --sessionid ... --datacenter ....

Using a cloud browser for everything? Build without the local Chromium for a much smaller image: docker build --build-arg INSTALL_BROWSER=false -t autotok:slim .


Web app (self-hosted)

A local control panel with accounts, proxies, a video library, uploads and a scheduler, plus a virtual browser for logging in. Requires Docker.

git clone https://github.com/makiisthenes/TiktokAutoUploader.git
cd TiktokAutoUploader
docker compose up --build

Open http://localhost:3000. The API docs are at http://localhost:8000/docs.

  • Accounts: add accounts by logging in through the built-in virtual browser (with an optional proxy), then set, change or test each account's proxy and check its session.
  • Upload: drop a file, pick one from the library, or paste a YouTube link. Publish now or schedule for any time.
  • Schedules: the scheduler retries only failures that happened before anything reached TikTok, so a job can't post twice.

Data lives in ./data. To use an account you logged in to with the CLI, copy its file into the app's store and click Import from disk on the Accounts page:

mkdir -p data/autotok/accounts && cp ~/.autotok/accounts/my_account.json data/autotok/accounts/

(Files the containers write are owned by root on Linux, so use the web app's own login for accounts you manage there.)

To sign uploads with a cloud browser, put AUTOTOK_BROWSER and its settings (see Cloud browsers) in a .env file next to docker-compose.yml. Logging in through the web app still uses its built-in virtual browser.

Scripts that call the API directly must send the header X-Requested-With: autotok on POST/PATCH/DELETE requests. This stops other web pages from using the local API.

The web app has no login of its own and only listens on 127.0.0.1. Don't expose it to the internet.


Configuration

Everything is optional. Put settings in a .env file: copy .env.example to .env and fill in what you use. autotok reads .env from the folder you run it in, then ~/.autotok/.env. Variables already set in your environment take priority, and docker compose reads the same file. .env holds API keys, so never commit it (it's in .gitignore).

Variable Purpose Default
AUTOTOK_HOME Saved accounts and settings ~/.autotok
AUTOTOK_VIDEOS_DIR Videos folder and YouTube downloads $AUTOTOK_HOME/videos
AUTOTOK_BROWSER Where login/signing browsers run: local, browserbase, steel local
AUTOTOK_BROWSER_CHANNEL Use an installed browser, e.g. chrome Playwright Chromium
AUTOTOK_BROWSER_PATH Full path to a Chrome/Chromium binary Playwright Chromium
BROWSERBASE_API_KEY, BROWSERBASE_PROJECT_ID, BROWSERBASE_REGION, BROWSERBASE_PROXY_COUNTRY Browserbase settings —
STEEL_API_KEY, STEEL_BASE_URL, STEEL_CONNECT_URL Steel settings (STEEL_BASE_URL for self-hosted) Steel Cloud

Account files contain your TikTok session (equivalent to your password). They are saved with owner-only permissions; keep them private.


Upgrading from TiktokAutoUploader 1.x

  • Install: follow Getting started (uv tool install "autotok[youtube]", then autotok install-browser). Node.js and npm install are no longer needed.
  • Sessions: saved sessions in CookiesDir/ are migrated automatically the first time you use them from the repository folder. The flags are the same, and python cli.py still works.
  • Scheduling: -sc schedules on TikTok's side again (15 minutes to 10 days). The 1.x local queue (cli.py schedule list|cancel) now lives in the web app's Schedules page.
  • Bug fixes: privacy, comment, duet and stitch settings are now actually applied. Earlier versions always posted publicly with everything allowed. Hashtags are clickable again.
  • Removed: config.txt and the unused ImageMagick video-editing helpers.

Troubleshooting

Problem Fix
'autotok' is not recognized / command not found Run uv tool update-shell once and open a new terminal. If you installed with pip instead, use python -m autotok ...
Chromium for Playwright is not installed autotok install-browser (Linux servers: add --with-deps)
TikTok rejected the session / session rejected autotok login -n NAME --force (check with autotok accounts check NAME)
Invalid parameters (status_code=5) TikTok changed its upload API. Please open an issue with the full error.
potential violation of our Community Guidelines TikTok blocked that video's content; it isn't a tool error.
Login page refuses to log in / shows a captcha loop Try your installed Chrome: add AUTOTOK_BROWSER_CHANNEL=chrome to your .env, or copy the sessionid cookie from your browser and use autotok login -n NAME --sessionid ...
"Verify it's really you" during a cloud login TikTok doesn't recognise the cloud browser's IP. Complete it in the live view (choose Email), or avoid it with a proxy; see the notes under Cloud browsers
Cloud login live view is blank (self-hosted Steel) Restart steel-browser with DOMAIN=localhost:3000 (its address)
Browserbase ... (HTTP 402): Proxies are not included in the free plan Remove BROWSERBASE_PROXY_COUNTRY, or the account's proxy for cloud logins, or upgrade the Browserbase plan
No TikTok datacenter cookie saved warning Log in again with autotok login, or pass --datacenter with --sessionid
may or may not have been posted The connection dropped while publishing. Check the account before retrying, to avoid a duplicate.

See also Common problems.


Demo

Video showcases main usage of the app, uploading a video to TikTok.


Professional Software (autotok Pro)

Fill waiting list form: https://forms.gle/M4KpdfruqCukQvj99

If you are looking for something more, which can get you faster to your goal, I offer software which can:

  • Handle more than 1000 accounts
  • Upload identical videos to multiple accounts automatically
  • Schedule videos for multiple accounts, 20 days to 2 years in advance
  • Automatically source videos from YouTube, X, Reddit, TikTok
  • Setup uploading pipelines, from source to uploading schedule
  • Metrics for viewing current performance of these different accounts
  • Personalised support from me for any issues you may face for up to 3 months
  • Proxy support, clean and modern UI

Available for purchase, if interested please email me at michaelperes562@gmail.com with subject line Tiktok Bot Software or else I might miss the email.


Licensing

autotok is dual-licensed:

  • Open source: GNU AGPL v3.0. Use, modify and share it freely. If you distribute a modified version, or run one as a service for others, you must publish your source code under the same licence.
  • Commercial: to build autotok into closed-source products or paid services without the AGPL obligations, or to use autotok Pro, contact michaelperes562@gmail.com.

Copyright © 2021–2026 Michael Peres. Releases before 2.0.0 remain under the licence they were published with. The bundled signing scripts are third-party code, see THIRD_PARTY_NOTICES.md. Contributions are welcome under the terms in CONTRIBUTING.md.


Support This Project

If you like the work provided, please consider supporting me through Patreon or Ko-Fi, or star the project.

  • Thanks @DelvinBa for updating to TikTok's new upload endpoint. (09/12/2024)

Bugs and Issues

Please report bugs in the issues tab rather than by email.

Notes and Terms

This project is not affiliated with TikTok. Automating uploads may break TikTok's terms of service and can get accounts restricted or banned. Only upload content you have the rights to. Use at your own risk.

Star History

Star History Chart

Metadata

Release files for autotok 2.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for autotok 2.0.1
File Size Uploaded
autotok-2.0.1.tar.gz 140.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for autotok 2.0.1
File Interpreter ABI Platform
autotok-2.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 279.7 kB

Release files / autotok-2.0.1.tar.gz

Download URL autotok-2.0.1.tar.gz
Size 140.3 kB
Tags Source
SHA-256 checksum
How to use checksums
b977203d5f1f3d0ae11a39c176eb64d064891bef866b6639a3745471d4992ff0
BLAKE2b-256 checksum
How to use checksums
1e27e3e0375c99e0a867480d8a38b54f02cd6a0536b9a32a66e7e27d554ffa57
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / autotok-2.0.1-py3-none-any.whl

Download URL autotok-2.0.1-py3-none-any.whl
Size 139.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
de0150dc3bd084e7b5ee8384c5c75d9c0af4592efd66d0dfa190c27d3b426b65
BLAKE2b-256 checksum
How to use checksums
d0f6d50e9ed8a95d6adfc8b07c948495d9fe4cd211558180cbfd00bfa057a1d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.0.1 This release

2 release files

2.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page