Threads API tutorial: publishing posts and carousels programmatically
A practical guide to the Threads API in 2026 — the separate app setup, tester invites, the container publish flow, carousels, reply-based first comments, and the rate limits nobody mentions until they hit them.
The Threads API is younger than its Instagram sibling and the documentation ecosystem around it is still thin — which means most of what goes wrong during an integration goes wrong silently. This tutorial covers the full path: app setup, OAuth, text posts, media, carousels, and the reply-based trick for first comments.
App setup: Threads is its own thing
Threads lives inside the Meta developer ecosystem but behaves like a separate platform:
At developers.facebook.com, create an app with the Threads use case (or add the use case to an existing app).
The Threads App ID is not your main Meta App ID. The use-case settings expose a separate Threads App ID and Secret — using the main app's credentials is the most common first failure, and it fails with unhelpful OAuth errors.
Register your redirect URI in the Threads use-case settings, not the general app settings. HTTPS is required in live mode.
In development mode, only invited Threads Testers can connect. Invite them in the app dashboard; each tester must then accept the invite inside the Threads app under Settings → Website permissions. Missing that acceptance step produces an "Insecure Login Blocked" style error that looks like a configuration bug but isn't. Going public requires App Review.
Publishing: containers, again
Threads uses the same container model as Instagram: create a media container, then publish it.
# 1. Create a container (text-only post)
curl -X POST "https://graph.threads.net/v1.0/{threads-user-id}/threads" \
-d "media_type=TEXT" \
-d "text=Hello from the API" \
-d "access_token={token}"
# → { "id": "{container-id}" }
# 2. Publish it
curl -X POST "https://graph.threads.net/v1.0/{threads-user-id}/threads_publish" \
-d "creation_id={container-id}" \
-d "access_token={token}"
The constraints to design around:
Text is capped at 500 characters. If you're cross-posting from platforms with bigger limits, truncation strategy is your problem, and it needs to happen before the API call.
Media must live at publicly accessible URLs — Meta fetches it at publish time.
Each profile is capped at 250 API-published posts per 24 hours.
Tokens are long-lived (60 days) and need a refresh schedule, same as Instagram.
Carousels
Threads supports up to 20 media items, with 2+ items publishing as a carousel. The flow mirrors Instagram's: create one child container per item, wait for each to finish processing, then create a parent carousel container — the post text rides on the parent, not the children — and publish the parent.
Everything that makes Instagram carousels operationally tricky applies here too: child processing is asynchronous, a failed child should fail the whole carousel (no partial publishes), and multi-minute publish times mean client retries are a real double-posting risk without idempotency.
First comments via reply chains
Threads has no separate comment API — a "comment" is just a thread posted with reply_to_id pointing at the parent post. That makes the link-in-first-comment pattern possible: publish the main post, take its ID, then create and publish a second container carrying the URL with reply_to_id set.
Design it to fail softly. If the main post publishes and the reply fails, you have live content — report the comment failure separately instead of failing the whole publish.
The one-call alternative
Chirio handles the whole flow — hosted OAuth with the right app plumbing, container orchestration, carousels, reply-based first comments, token refresh, idempotent retries — behind a single call:
Two or more mediaItems publish as a carousel in order; the first comment posts as a reply after the main post lands and never fails a published post. The 500-character limit is validated up front with a clear error instead of a platform rejection mid-flow.
Worth knowing before you commit
The Threads API is the least stable target of the major platforms — it's newest, and Meta is still filling in gaps (carousel limits, insights, reply management have all evolved recently). Whatever you build, isolate the Threads-specific logic behind your own interface so the next platform change is a one-file fix. Or let a publishing API absorb that churn for you — that's the trade in one sentence.