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:
POST /{user-id}/threadsto create a media container.POST /{user-id}/threads_publishwithcreation_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:
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
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
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:
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.
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:
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:
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.