Get Threads posting credentials¶
Let keryx auth threads capture a token so keryx publish can post a
text-and-image announcement to a Threads account (spec 0060 D15). Threads
lives on the same Meta app as Instagram and Facebook but, like Instagram
Login, its use case mints an app id and secret of its own; the Meta app's
id and the Instagram pair are both rejected. Ten minutes.
1. Add the Threads use case¶
In the app dashboard: Use cases → Add use cases → Access the Threads API (the name varies slightly). Once added, open it and:
- Under its Settings, note the Threads app ID and Threads app
secret.
platforms.threads.app_id(config, non-secret) andTHREADS_APP_SECRET(environment, never committed). - Add the loopback redirects keryx uses for Threads. Not
localhost: Threads' token endpoint refuses that hostname at the code exchange (error 191, "Invalid redirect_uri") even though the consent page accepts it, so keryx useskeryx.localhost, which every current browser resolves to 127.0.0.1 without a hosts entry:https://keryx.localhost:3764/…https://keryx.localhost:3769/. A project can name any host it points at the loopback instead withplatforms.threads.redirect_host. - Under its Permissions, make
threads_basicandthreads_content_publishavailable. - Under Roles, add the Threads account as a Threads Tester while the app is in development, and accept the invitation in the Threads app (Settings → Account → Website permissions → Invites).
2. Sign keryx in¶
It opens the consent window (or prints the URL), captures the code on the
https loopback, swaps it for a short-lived token, that for a 60-day one,
and stores the token (keychain, else the accounts file) with its expiry and
platforms.threads.{user_id,enabled,redirect_uri}. In CI,
THREADS_ACCESS_TOKEN in the environment is the token.
3. What a post looks like there¶
- Text, held to 500 characters. Threads has no in-text hashtags, only
one topic tag per post, so the first hashtag is sent as the topic and
none go in the text (a
#tagin the text would become the topic and leave a bare word behind). - Without an image: a text post with the link as a link attachment, which Threads renders as a card.
- With an image: an image post. Threads fetches the JPEG or PNG (under 8
MB) from its public URL, so the article must be live and
announce.public_base_urlset. A link attachment is not allowed with media, so the link is written into the text. keryx counts the link against the 500 either way, so an approval never turns into a refusal at send time. - Alt text is sent when the post has it. No video.
Refresh¶
The 60-day token refreshes in place: keryx auth refresh exchanges it once
it is within 20 days of expiry and records the new expiry; a token under 24
hours old cannot be refreshed, which is why it waits.