$39 once · self-hosted · no subscription

Set it up once. Your Threads account posts every day without you.

A small Python kit that runs on GitHub Actions: every day it writes one post in your voice, reviews its own draft before anything goes out, and publishes through the official Threads API. No server to run, no monthly fee, and the code is yours to read and change.

Runs on the GitHub Actions free tier. You bring your own Threads token and OpenAI key.
Defaults to 00:00 UTC — change one cron line for your timezone.

Skeptical? Fair. @hyoj.unlim is run by this exact kit, in public, right now — every post on it was written, self-reviewed and published by the pipeline below.

One daily run
cron: 0 0 * * *  ·  yours to change
01
generate_content.py
Writes today's post
02
self-review
Second model pass, approve or reject
03 · optional
generate_image.py
Illustration, only if it fits
04
post_to_threads.py
Official API, container then publish
05
post_history.json
Logged so tomorrow differs
Live proof

Don't take a landing page's word for it. The demo account is public.

@hyoj.unlim on Threads is not a mockup and not cherry-picked screenshots — it is a real account whose daily posts are written, self-reviewed and published by this exact kit, on the GitHub Actions free tier, with no human touching the keyboard. Open it, read the posts, judge the quality yourself. If the writing on that account wouldn't be good enough for yours, don't buy this.

How it works

Five steps, one file each. Nothing hidden behind an API you can't see.

A scheduled GitHub Actions workflow (daily_post.yml) checks out your private repo, installs two dependencies, and runs auto_post.py. That script is the whole orchestrator — about 70 lines. Here is what happens inside it.

01 · GENERATE

It writes today's post in your voice

Your account concept and two real example posts go into the prompt, along with the topics from your last 10 posts so it picks something new. The house rules are baked in: plain conversational English, under 500 characters, short scannable paragraphs, at most two hashtags, no hype words, no invented numbers.

02 · SELF-REVIEW

A second pass has to approve it

The draft goes back to the model as a reviewer with explicit criteria — length, natural English, fits the account concept, no exaggerated or invented claims, not a repeat of a recent topic. It answers in JSON: approved, a one-line reason, and the topic.

Rejected? It writes a new draft and reviews again, up to three attempts. If nothing passes, the run stops and posts nothing. A silent day beats a bad post.

03 · IMAGE (OPTIONAL)

An illustration, only when one earns its place

The model first decides whether an image would actually help this specific post — explaining a concept or a process, yes; a short reflection or a list of numbers, no. When in doubt it says no, because a feed of filler illustrations looks worse than plain text.

If yes, it generates a 1024×1024 illustration in the style you described and commits it to a public GitHub repo, because Meta fetches images from a public URL rather than accepting an upload. Skip this whole feature and everything still runs text-only.

04 · PUBLISH

Through the official Threads API

The documented two-step publish: create a media container at graph.threads.net, wait for Meta to process it, then publish. Text-only or text plus image, same path. On failure the script prints the full response body into your Actions log, so you see the actual reason instead of a bare status code.

05 · LOG

It remembers what it already said

The topic, text, image URL, timestamp and returned post ID get appended to post_history.json, and the workflow commits that back to your repo. Tomorrow's prompt reads it so the account doesn't circle the same three subjects all month.

ALSO INCLUDED

A legacy manual publisher, for drafts you write yourself

review_and_post.py is an older, standalone script kept as a fallback. It reads drafts you hand-write into content_queue.json and shows you one at a time in the terminal — approve, edit, skip, or quit — then publishes through the same Threads code. To be clear: it is not a review layer on the AI pipeline, and nothing fills that queue for you.

What you get · what you need

A zip of readable Python, a written guide, and an honest list of what it asks of you.

IN THE DOWNLOAD
  • Setup & Owner's GuideThe full written walkthrough — token, repo, secrets, first run, images, troubleshooting
  • auto_post.pyThe daily orchestrator
  • generate_content.pyWriting plus the self-review pass
  • generate_image.pyImage decision, generation, upload
  • post_to_threads.pyTwo-step Threads API publish, also runnable by hand
  • review_and_post.pyLegacy manual publisher for drafts you write yourself
  • .github/workflows/daily_post.ymlThe schedule, plus a manual Run workflow button
  • account_config.example.jsonThe one file you fill in
  • test_models.pyCheck which models your OpenAI key can reach
WHAT YOU NEED
  • A Meta developer app and a long-lived Threads tokenFree · 60-day expiry, you refresh it yourself
  • Your numeric Threads user IDFree · comes from the same setup
  • An OpenAI API keyPay-as-you-go · a text post costs well under $0.01/day
  • A GitHub accountFree · Actions free tier covers one short run a day
  • A public GitHub repo for images, plus a fine-grained access token with write access to itOptional · only if you want illustrations
  • Python, locallyOptional · only to test before you push. The daily run happens on GitHub

Personalization is one file. Copy account_config.example.json to account_config.json, fill in three fields, done — there is no code to edit to make it sound like you. Then commit it: the workflow reads the file straight from your repo, and it holds no secrets.

{
  "account_concept": "A solo developer documenting a small SaaS build,
                        plain English, real numbers, no hype.",
  "style_examples": [
    "Two posts you actually wrote. Rough ones work better than polished ones —",
    "the model copies the roughness, and that is the part that reads as human."
  ],
  "image_style": "flat minimal line art, muted colors, no text"
}

image_style is optional — drop the line and the built-in style is used. (No comments in the sample: JSON doesn't allow them.)

Setup time: about 90 minutes, following the guide end to end — so don't start it twenty minutes before you have to be somewhere. Most of it is waiting on other people's dashboards: creating the Meta developer app and getting a long-lived token is the slowest part, and OpenAI's billing page takes a few minutes of its own. Creating the repo, pasting three secrets — five if you turn illustrations on — and running the first test takes ten minutes or so.
Before you buy

What this is — and what it isn't.

This is a kit, not a service. You get a zip of Python that you put in your own repo and run with your own keys. Nothing routes through me, there is no dashboard, and there is no account to log into. That is the point — your Threads token and OpenAI key stay in your repo's secrets — but it also means the setup is on you, and so is fixing it if Meta changes something.

The 60-day token is a real chore

Threads long-lived access tokens expire after 60 days. This kit does not refresh them for you. Roughly every two months you go get a fresh token and paste it into your repo secrets — a five-minute job, but a recurring one. If you forget, the daily run fails, GitHub emails you, and no post goes out until you fix it. I would rather you know that now than discover it in December.

The output is only as good as your config

Two vague sentences of account concept and two generic example posts produce vague, generic posts — forever, every day, automatically. The self-review pass catches length problems, repeats, and invented claims. It cannot catch "this is boring". Spend twenty minutes writing the config honestly and the difference is not subtle.

It is not a growth guarantee

Posting daily removes one specific excuse: that you didn't have time to write today. It does not make people follow you. If your account concept isn't interesting to anyone, automating it just makes that visible faster.

Things that can break, honestly

Model names change and OpenAI billing runs dry (the kit tries a list of models in order and logs what it tried). Meta rate-limits or blocks API access. A review pass rejects three drafts and the day is skipped. All of it lands in your Actions log with the real error message, and you can run the workflow by hand any time to retry.

Still sounds worth it? Get the kit — $39

Pricing

$39 once. No subscription, because there is nothing for me to host.

You are buying the code, the Setup & Owner's Guide, and the hours of Threads API trial and error that went into getting a container to actually publish. After that it runs on your infrastructure, at your cost, which is pennies.

Threads Autopilot

$39 once · the kit
  • Full source, no obfuscation, yours to modify
  • Daily automated posting via GitHub Actions
  • Self-review pass before anything publishes
  • Optional AI illustrations
  • Legacy manual publisher included
  • Setup & Owner's Guide — setup, customization, troubleshooting
Get the kit — $39

Instant download on Gumroad. Not useful? Reply to your receipt email for a refund.

Different job: Grounded is for writing with review, Autopilot is for not writing at all. See Grounded ($39 once, hosted, nothing to set up).

Honest answers

Questions worth asking before you spend $39.

Is this against Threads' rules?

No. It publishes through the official Threads API — the same documented endpoints Meta built for scheduling tools and social media managers, using a token you generate from your own Meta developer app for your own account. There is no browser automation, no scraping, no unofficial endpoint.

What you still own is the content policy side: one post a day in your own voice is normal use, and the review pass is instructed to reject anything that would violate platform policy. Point it at spam and no API is going to save you.

What happens after 60 days?

Your Threads long-lived access token expires, and this kit does not refresh it for you. When it expires the daily run fails, GitHub emails you that the workflow failed, and no post goes out until you deal with it. Nothing else breaks — no data is lost, and the history file is untouched.

Dealing with it means generating a fresh long-lived token in your Meta developer app and pasting it over the old THREADS_ACCESS_TOKEN secret. About five minutes, roughly six times a year. If that sounds like a chore you won't do, this is the honest moment to not buy.

Do I need to know Python?

To run it, no. You copy one example file, fill in three fields of JSON — your account concept and two example posts — commit it, paste three values into GitHub's secrets screen (five if you turn illustrations on), and click Run workflow once to test. No code editing at any point.

To change it, yes, some. Want a different posting time? That is one cron line. Different tone rules, two posts a day, a different review standard? That is editing readable Python with comments — an afternoon if you are comfortable, and honestly a good use of an LLM if you are not.

What does it cost to run?

Practically nothing. GitHub Actions gives free accounts 2,000 minutes a month on private repos; this run takes one to two minutes a day, so about 60 minutes total. Public repos are free without a minute cap.

OpenAI is pay-as-you-go and the only real cost. Each day is two short calls on a clean day — write and review — three if illustrations are on, and up to six if the reviewer rejects drafts. Still well under a cent per day for text. Turn illustrations on and each generated image is roughly $0.01–0.04; since the model only asks for one when it fits, expect well under a dollar a month. There is no charge from me after the $39.

Why self-hosted instead of a service?

Because a posting service needs your Threads access token, and a token that can publish to your account is not something to hand over to a one-person product for convenience. Here it lives in your repo's secrets and is read by a workflow you control.

The other reason is that a service would mean charging you monthly forever for a cron job. This is $39 once. If I disappear, your bot keeps posting, because nothing in the loop depends on me.

What about the Grounded web app — do I need both?

No, they solve different problems. Grounded is hosted and manual: paste your rough notes or a news topic, get three drafts, and every draft comes with a grounding audit flagging anything it can't trace back to the material you gave it. You review and post yourself. It is hosted, so there is nothing to set up, and it is $39 once for a lifetime license.

Autopilot is the opposite trade: nothing to review, nothing to paste, but you write the config carefully up front and then trust the self-review pass. Plenty of people start with Grounded to find their voice, then automate it here.

What happens the day it breaks?

GitHub emails you when a scheduled workflow fails, and the Actions tab keeps the full log. The failure modes are boring and readable: expired token, OpenAI billing, three rejected drafts in a row. Fix the cause, hit Run workflow, and you are back — no data to migrate, nothing to reinstall.

What if my OpenAI key can't reach the model?

It happens — model names change, and new accounts don't always have access to the newest ones. The kit doesn't pin a single model: it walks an ordered list of candidates and uses the first one your key can actually call, logging what it tried along the way. To pin or reorder the list, set a repository variable named OPENAI_MODELS — no code or YAML editing, the workflow passes it through. The guide shows the exact clicks.

test_models.py ships in the zip so you can check this before the first scheduled run, rather than finding out from a failed workflow at midnight.

Can I run two accounts?

Yes, but as two separate copies: two repos, each with its own account_config.json, its own history file, and its own set of secrets — a different Threads token and user ID per account. There is no multi-account mode inside one repo, and honestly two repos is the simpler shape anyway. The OpenAI key can be the same one in both.

What's the support policy?

Reply to your receipt email. I am one person, so treat it as best-effort rather than an SLA — but setup problems and genuine bugs are worth writing to me about, and I read all of it. If the kit doesn't do what this page says it does, ask for a refund and you will get one.

Write the config once. Read your feed instead of feeding it.

About ninety minutes of setup, then one post a day in your voice — reviewed before it goes out, logged after, running on infrastructure you own.

Not useful? Reply to your receipt email for a refund.