How to Post to Threads via API

Threads API is new and uses a Reels-style container flow. Here's the working pattern with Postproxy — text, image, video, multi-image, and reply chains.

What the Threads API actually exposes

The official endpoints (under graph.threads.net) cover:

  • Single text post
  • Single media post (image or video)
  • Multi-image post (up to 20 children)
  • Reply to an existing thread
  • Read user threads, replies, and insights

There’s no scheduled_publish_time, no draft mode, no Stories-equivalent, no edit.

The publish flow is two steps:

  1. POST /{user-id}/threads to create a media container.
  2. POST /{user-id}/threads_publish with creation_id={id} to publish.

Containers go stale after 24 hours. Video containers may take 30+ seconds to finish processing.

The minimum text post

Postproxy collapses container creation, processing wait, and publish into a single request:

Terminal window
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": { "body": "First post from the API. Hello, Threads." },
"profiles": ["threads"]
}'

The response includes a post ID and, after publishing, a permalink to the live thread on each platform record.

Posting an image

Terminal window
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": { "body": "Built this dashboard over the weekend. Feedback welcome." },
"profiles": ["threads"],
"media": ["https://yourcdn.com/dashboard-screenshot.png"]
}'

Image specs: JPG, PNG, GIF, or WebP, max 8MB, min 200×200, up to 20 images per post.

Posting a video

Terminal window
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": { "body": "30-second walkthrough of the new flow." },
"profiles": ["threads"],
"media": ["https://yourcdn.com/walkthrough.mp4"]
}'

Video specs: MP4 or MOV, max 1 GB, max 5 minutes, aspect ratio 0.01:1 to 10:1. Postproxy waits for container processing before publishing.

Multi-image post

Threads supports up to 20 children. Pass them in the media array:

Terminal window
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": { "body": "Five things we learned shipping our SDK this week ↓" },
"profiles": ["threads"],
"media": [
"https://yourcdn.com/lesson-1.png",
"https://yourcdn.com/lesson-2.png",
"https://yourcdn.com/lesson-3.png",
"https://yourcdn.com/lesson-4.png",
"https://yourcdn.com/lesson-5.png"
]
}'

Threads allows mixed images and video in the same post — pass URLs in any order.

Reply chains (threads on Threads)

A “thread” — root post with a sequence of replies — is published with the thread array. The first item in thread is the first reply, the second is the next, and so on.

Terminal window
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": { "body": "1/ Here is what we learned shipping our SDK this week" },
"profiles": ["threads"],
"thread": [
{ "body": "2/ The auth model was wrong from day one." },
{ "body": "3/ We rewrote it in two days using a single token rotation table." },
{ "body": "4/ Result: 0 reauth incidents in 30 days." }
]
}'

Each chain is independent per platform — running the same call with profiles: ["threads", "twitter", "bluesky"] publishes three parallel reply chains. If one platform fails mid-chain, that chain stops; the others keep going. See the Threads section in the Posts API docs for the full semantics.

Cross-posting Threads with X and LinkedIn

Threads, X, and LinkedIn share text-first format and broadly compatible character limits (Threads: 500, X: 280 free / 25k paid, LinkedIn: 3,000). One call, three platforms:

Terminal window
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": { "body": "Shipping notes: we cut our publish latency in half this week." },
"profiles": ["threads", "twitter", "linkedin"]
}'

If a single platform fails (rate limit, expired token), the others still publish. Per-platform status and error are on the response. See partial success.

Scheduling

Threads has no native scheduling. Pass scheduled_at to Postproxy:

Terminal window
curl -X POST "https://api.postproxy.dev/api/posts" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"post": {
"body": "Coffee chats are open this Friday — DM if you want a slot.",
"scheduled_at": "2026-05-08T14:00:00Z"
},
"profiles": ["threads"]
}'

Going further

For the deeper version — error codes, OAuth scopes (threads_basic, threads_content_publish), insights polling, app review checklist — see How to post to Threads via API and the Threads integration guide.

Ready to get started?

Start with our free plan and scale as your needs grow. No credit card required.