How to Schedule & Auto-Post to Threads via API

Schedule and auto-post to Threads through Postproxy — one request handles the container/publish flow, retries, rate limits, and reply chains. Working code with Node, Python, and curl.

Looking for the API reference, not the scheduling task? See Post to Threads via API: Developer Guide (2026) for the full container model, OAuth scopes, and rate-limit reference.

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.

Ready to get started?

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