Skip to content

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:

  1. Under its Settings, note the Threads app ID and Threads app secret. platforms.threads.app_id (config, non-secret) and THREADS_APP_SECRET (environment, never committed).
  2. Add the loopback redirects keryx uses, the same six as Instagram: https://localhost:3764/https://localhost:3769/.
  3. Under its Permissions, make threads_basic and threads_content_publish available.
  4. 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

keryx auth threads

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, with the hashtags on a new line, held to 500 characters together.
  • Without an image: a text post with the link as a link attachment, which Threads renders as a card; the URL does not count against the 500.
  • 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_url set. A link attachment is not allowed with media, so the link is written into the text and counts.
  • 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.