autotok turns a TikTok login and a video path into one command
Automatically Edits Videos and Uploads to Tiktok with CLI, Requests not Selenium.
At a glance
- What is it?
- autotok is an AGPL-3.0 licensed Python CLI that logs into TikTok once per account, saves the session, and then uploads or schedules videos from the command line, with a proxy bound to each account at login time. The interesting engineering is in the browser handling, because the login needs a visible browser while the upload only needs to sign, and the project offers local Chromium or two cloud browser services for that.
- Who is it for?
- autotok fits a creator or agency that already holds the accounts and wants to post and schedule from a script or a CI job rather than by hand, and that is prepared to manage a per-account browser session as a credential. It does not fit a first-time user with no accounts, and it does not fit a machine with no browser, since the login step needs one.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 7 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
One login per account, then one command per upload
The pitch at the top of the README is compact: upload and schedule TikTok videos from the command line or Python, with a proxy per account, and one login and one command per upload. The project is called autotok on PyPI even though the repository is TiktokAutoUploader.
The install is a single command, and the extra in the brackets is what pulls in the YouTube support.
uv tool install "autotok[youtube]"The README notes that uv keeps autotok separate from other Python packages and downloads Python if you do not have it, and that pipx install "autotok[youtube]" or pip install "autotok[youtube]" work too. The [youtube] extra adds YouTube-link support, and the README says you can leave it out if you do not need it. There is also a try-it-without-installing route with uvx, and for using the tool from your own code, uv add "autotok[youtube]".
The day-to-day loop is two commands.
autotok login -n my_account # log in on the page that opens; the QR code is quickest
autotok upload -u my_account -v clip.mp4 -t "Hello #fyp"The login opens a browser window on TikTok's login page, you log in however you like, the window closes by itself, and the session is saved under the name you gave it. The upload then takes the account name, a video path and a caption.
The upload options cover the cases a scheduler needs. A flag makes the post private, another schedules publication in a given number of seconds, and another takes a YouTube Shorts URL instead of a local file. The video argument is a path to any video, or just a file name if the video is in ~/.autotok/videos.
For a scripted workflow there is also an autotok setup command, which checks the browser, asks for a proxy, tests it, and then logs you in, so the whole flow can be walked through without reading the manual.
The browser is the dependency, and containers need a cloud one
The design decision that shapes everything is that autotok uses a browser twice, for two different jobs. It uses a browser for the one-time login, and it uses a browser to sign each upload.
The login is the hard case, because it may involve a QR code or a challenge that a human has to see. So the project offers two options for where the browser runs.
| Option | Best for | Setup | | Local (default) | Your own computer | autotok install-browser, about 300 MB | | Cloud, Browserbase or Steel | Servers, Docker, or keeping your computer free | Add an API key to a settings file |
For a fresh Linux server the README says to run autotok install-browser --with-deps as root, which also installs Chromium's system libraries.
The Dockerfile documents the container problem directly. Logging in needs a browser you can see, which a container does not have, and the suggested solution is a cloud browser and logging in through the link it prints, with the environment variables AUTOTOK_BROWSER=browserbase and BROWSERBASE_API_KEY set on the run. The alternative documented in the same file is to skip the interactive login entirely by saving a session cookie with autotok login -n my_account --sessionid ... --datacenter ..., which is the route for a headless machine that already has credentials.
The Docker image is python:3.12-slim-bookworm, it installs ffmpeg, which the README explains is there because ffmpeg merges YouTube audio and video streams, and it installs Playwright's Chromium with its dependencies unless the build argument says otherwise.
docker build --build-arg INSTALL_BROWSER=false -t autotok:slim .With that flag the local browser is skipped, which the Dockerfile says makes the image around 500 MB smaller. The image also runs as an unprivileged user with uid 1000, and data lives in /data, which the header comments say should be a volume or a bind mount.
A proxy has to be chosen at login, not at upload
The per-account proxy is the feature that distinguishes this from a plain uploader, and the README is precise about when it has to be set.
Going to use a proxy for this account? Pass it now, so the login and later uploads share one IP. The command takes the proxy in the login step.
autotok login -n my_account -p http://user:pass@host:portThat ordering is a design decision with a practical reason behind it. If the login happens from your home IP and the uploads happen from a proxy IP, the two halves of the session do not look like the same client, and a session bound to one address is a session that may not be accepted later. Setting the proxy once, at login, means the saved session and every subsequent upload share an address, and the account can be managed as a unit.
The proxy configuration also lives in the settings file, and the .env.example file spells out the shape of it. AUTOTOK_BROWSER selects where the login and signing browser runs, with local, browserbase and steel as the values, and you can also choose per command with autotok --browser browserbase. The Browserbase block carries BROWSERBASE_API_KEY, an optional BROWSERBASE_PROJECT_ID that is inferred from the key, an optional BROWSERBASE_REGION, and an optional BROWSERBASE_PROXY_COUNTRY for logging in through a home IP in a given country on paid plans. The Steel block carries STEEL_API_KEY for the hosted service, or STEEL_BASE_URL and an empty key if you run steel-browser yourself, and the file notes that the self-hosted server needs DOMAIN=localhost:3000 or its live view cannot connect.
The README also says autotok reads .env from the folder you run it in and then from ~/.autotok/.env, that variables already set in the environment win over the file, and that .env must never be committed because it holds API keys, with a note that it is already in .gitignore.
Saved sessions are credentials and the README says so
The account state lives in ~/.autotok/accounts, and the instruction about it is short: treat them like passwords.
That is the right instruction and it is worth expanding slightly, because a TikTok session is a bearer credential. Whoever holds the saved session can act as the account until it is revoked, and unlike a password there is no rotation ceremony and no obvious moment of expiry. The .env file holds API keys for the browser services, and the compose file makes the same point by setting AUTOTOK_HOME to a volume so that the saved accounts survive container rebuilds.
The tool does give you a way to check a session rather than assume it works.
autotok accounts check my_account # confirms TikTok accepts the saved sessionThat check is worth running in any pipeline, because a session that has been invalidated by a password change, a device unlink or a platform-side revocation fails at upload time otherwise, and the failure will look like an upload error rather than an authentication one.
The repository also carries a THIRD_PARTY_NOTICES.md file, listed in the license-files of the package metadata alongside the LICENSE, which is the right arrangement for an AGPL project that vendors a Chromium download and talks to third-party services. The .gitignore already excludes .env, and the .env.example file is a template rather than a configuration, so the repository itself does not carry anyone's keys.
The compose file is a small service stack, not a single container
The docker-compose.yml in the repository is worth reading as an architecture description, because the header comment explains what each service is for.
The tiktok-base service exists only to build the shared base image that api, scheduler and novnc derive from, and it is referenced through additional_contexts so Compose builds it first. The api service is a FastAPI REST API with OpenAPI docs at /docs on port 8000. The scheduler is the polling worker for scheduled uploads. The novnc service is the virtual browser used for the TikTok login, described as stateless because the API saves the accounts. The webapp is a React UI served by nginx that proxies /api and /novnc on port 3000.
The security posture in that file is deliberate. The ports are bound to 127.0.0.1 so nothing is exposed outside the host, and only the webapp and API ports are bound, while the scheduler and the noVNC control port stay on the internal compose network. The environment block wires the pieces together with TIKTOK_API_DB_PATH pointing at a SQLite file under /data, AUTOTOK_HOME and AUTOTOK_VIDEOS_DIR set to the same volume, NOVNC_CONTROL_URL and NOVNC_PUBLIC_URL linking noVNC to the API, and the browser selection variables passed through from the .env file.
So there are two deployment shapes in this project, and they serve different purposes. The CLI is the single-operator tool, one login and one command, and the compose stack is the multi-account service with an API, a scheduler and a web interface. The Python package metadata shows the second shape in the dependencies, with the dev extra pulling in FastAPI, uvicorn, sqlmodel and a stack of HTTP test tooling, and there is a separate mcp extra for exposing the tool through the Model Context Protocol.
AGPL-3.0, a 2.0 rewrite, and a package built with hatchling
The licence is AGPL-3.0, and the pyproject.toml is explicit about it with license = "AGPL-3.0-only" and the badge in the README matching. The package metadata lists both LICENSE and THIRD_PARTY_NOTICES.md as license files, which is the correct arrangement for a project that vendors a browser download and calls out to hosted services. This is a licensing fact rather than legal advice, and the practical point is that an AGPL tool that runs on your own infrastructure, talking to your own accounts, is a different licensing situation from one you redistribute as a service.
The build system is hatchling, with hatchling at 1.27 or above, and the version is dynamic. The runtime dependencies are deliberately few: requests with the socks extra, requests-auth-aws-sigv4 for signed requests, Playwright, and prompt_toolkit for the interactive shell. The optional extras are the YouTube support through yt-dlp, the shell extra, and the mcp extra.
The package is a console entry point named autotok, mapped to autotok.cli:run, and the repository has both an autotok/ package directory and a cli.py at the root, with the web/ directory holding the front end and the Docker files.
On maintenance, the project is moving quickly and has just changed shape. The recent releases are v2.0.0 and v2.0.1, both on 2026-10-03, and the last push was on 2026-10-04. A 2.0 with two releases one day apart is a rewrite rather than an incremental update, so the changelog in the repository and the version history in the README are the places to check what changed in the API, the CLI flags and the settings file, since a scheduler that stops parsing its old configuration after an upgrade is a real operational risk with a tool like this.
Editorial conclusion
autotok fits a creator or agency that already holds the accounts and wants to post and schedule from a script or a CI job rather than by hand, and that is prepared to manage a per-account browser session as a credential. It does not fit a first-time user with no accounts, and it does not fit a machine with no browser, since the login step needs one. Before deploying it, log in one account with the proxy you intend to use, run autotok accounts check on the saved session, and read the .env.example file, because the browser choice and the proxy configuration are set there and the accounts directory is described as something to treat like passwords.
Frequently asked questions
How do I install autotok?
Run uv tool install "autotok[youtube]", which also downloads Python if you do not have it, or use pipx install "autotok[youtube]" or pip install "autotok[youtube]". The [youtube] extra adds YouTube-link support and can be left out if you do not need it, and there is also uvx for trying it without installing.
How does the TikTok login work in autotok?
You run autotok login -n my_account, a browser window opens on the TikTok login page, you log in however you like with the QR code being quickest, and the window closes by itself with the session saved under that name. Sessions are stored in ~/.autotok/accounts and the README says to treat them like passwords.
When do I set the proxy for an autotok account?
At login time. The README says to pass the proxy when logging in, so the login and later uploads share one IP, with the form autotok login -n my_account -p http://user:pass@host:port. Proxy and browser settings live in the .env file, which autotok reads from the working directory and then from ~/.autotok/.env.
Can autotok run on a server without a display?
Yes, with a cloud browser, either Browserbase or Steel, which the README suggests for servers and Docker. The Dockerfile explains that logging in needs a browser you can see, so the alternative is to save a session cookie with autotok login -n my_account --sessionid ... --datacenter ..., and building with INSTALL_BROWSER=false skips the local Chromium and saves about 500 MB.
What does the autotok docker compose stack include?
The compose file defines a base image builder, a FastAPI API with OpenAPI docs on port 8000, a scheduler worker for scheduled uploads, a noVNC virtual browser used for the login, and a React web app served by nginx on port 3000 that proxies the API and noVNC. Ports are bound to 127.0.0.1 so nothing is exposed outside the host.
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/makiisthenes-tiktokautouploader)Was this useful?