Reelspan publishes to Threads with Meta's Threads API. You send the post once; Reelspan creates the Threads media, waits for Threads to process it, publishes it and returns the permalink.
What you can post
| Post | How | Notes |
|---|---|---|
| Text post | POST /v1/posts/text |
Up to 500 characters |
| Video post | POST /v1/posts/video |
|
| Photo post | POST /v1/posts/photos with one photo |
|
| Carousel | POST /v1/posts/photos with 2 to 20 items |
Photos and videos can be mixed |
Reelspan handles for you:
- Media by link. Threads fetches each photo and video itself from a signed link that stays valid for 6 hours.
- Mixed carousels. Videos sent in
photos[]become video items of the carousel. - Processing. Reelspan waits until Threads has processed the post (up to 10 minutes), then publishes it.
- Token refresh. Threads sign-ins last 60 days; Reelspan renews them while they are still valid, so you don't have to reconnect.
Connect the account
Threads connects with a Threads sign-in: in the dashboard go to Accounts → Threads, or send a white-label connect link. It is separate from the Instagram connection.
Example
A carousel with a topic tag, where only mentioned profiles can reply:
curl -X POST https://api.reelspan.com/v1/posts/photos \
-H "Authorization: Bearer $REELSPAN_API_KEY" \
-F "user=my-brand" \
-F "platform[]=threads" \
-F "threads_title=Two shots from this morning's walk" \
-F "threads_topic_tag=Photography" \
-F "threads_reply_control=mentioned_only" \
-F "photos[][email protected]" \
-F "photos[][email protected]" \
-F "alt_text[]=Fog over the harbour" \
-F "alt_text[]=A heron on the pier"import { Reelspan } from 'reelspan';
import { readFile } from 'node:fs/promises';
const reelspan = new Reelspan();
const post = await reelspan.posts.photos({
user: 'my-brand',
platforms: ['threads'],
photos: [
{ data: await readFile('photo1.jpg'), name: 'photo1.jpg', type: 'image/jpeg' },
{ data: await readFile('photo2.jpg'), name: 'photo2.jpg', type: 'image/jpeg' },
],
altTexts: ['Fog over the harbour', 'A heron on the pier'],
extra: {
threads_title: "Two shots from this morning's walk",
threads_topic_tag: 'Photography',
threads_reply_control: 'mentioned_only',
},
});from reelspan import Reelspan
reelspan = Reelspan()
post = reelspan.posts.photos(
"my-brand", ["threads"], ["photo1.jpg", "photo2.jpg"],
alt_texts=["Fog over the harbour", "A heron on the pier"],
extra={
"threads_title": "Two shots from this morning's walk",
"threads_topic_tag": "Photography",
"threads_reply_control": "mentioned_only",
},
)Fields
| Field | Type | Values | What it does |
|---|---|---|---|
threads_title |
string | up to 500 characters | The post text. Falls back to title. Longer text is cut. |
threads_topic_tag |
string | A topic for the post, shown as its tag. | |
threads_reply_control |
string | everyone, accounts_you_follow, mentioned_only |
Who can reply. Leave it out for everyone. |
threads_is_made_with_ai |
boolean | default false |
Adds Threads' AI label. is_ai_generated works too. |
threads_alt_text |
string or list | up to 1,000 characters each | Photo alt text: one for every photo, or one per photo in order. Falls back to alt_text. |
threads_first_comment |
string | up to 500 characters | A reply posted under the new post. Falls back to first_comment. |
threads_reply_to_id |
string | a Threads post id | Posts this as a reply to that post. |
threads_quote_post_id |
string | a Threads post id | Quotes that post. |
threads_link_attachment |
string | a URL | Text posts: shows the link as a preview card. Ignored on posts with media. |
threads_poll_options |
list | 2 to 4 options | Text posts: adds a poll. Each option is cut to 25 characters. Send repeated fields, a JSON array or one comma-separated string. |
A poll on a video or photo post is left out with a warning, since Threads takes polls on text posts only. Fewer than 2 or more than 4 options fails the post with invalid_poll.
curl -X POST https://api.reelspan.com/v1/posts/text \
-H "Authorization: Bearer $REELSPAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"user": "my-brand",
"platform": ["threads"],
"title": "Coffee or tea while you work?",
"threads_poll_options": ["Coffee", "Tea", "Neither"]
}'Limits
- Text: 500 characters. Longer text is cut, not threaded.
- Carousel: up to 20 items; with more, the first 20 are used and the result says so.
- Video size: your plan's upload limit (see Plans and limits).
- Shapes: 4:5 and 9:16 work best.
Good to know
- Result extras:
container_id(the Threads media container). - First comment: posted as a reply to the new post.
- Analytics: when your Reelspan workspace has Threads statistics turned on, the account's views, likes, replies, reposts and quotes over the last 30 days, and followers (Threads shares the follower count only for profiles with at least 100 followers); per post, views, likes, replies, reposts, quotes and shares. An account connected before statistics were turned on has to be reconnected.
After posting
- Repost a post (yours or any public one) from the account with Repost.
- Threads posts can't be deleted or edited through Reelspan: the Threads API doesn't allow edits, and deleting needs a permission Reelspan doesn't hold.
- Threads lets an account publish 250 posts and 1,000 replies in 24 hours. Publishing limits shows how much is left.
Errors
error_code |
What happened | What to do |
|---|---|---|
threads_processing_failed |
Threads couldn't process the media | Read error; check the file and post again. |
threads_processing_timeout |
Threads took more than 10 minutes | Reelspan retries it; check Threads before posting again. |
threads_error |
Threads refused the request | Read error for Threads' message. |
invalid_poll |
threads_poll_options has fewer than 2 or more than 4 options |
Send 2 to 4 options. |
media_required |
A video or photo post arrived without media | Send the media, or post with POST /v1/posts/text. |
reauth_required |
The sign-in expired or was revoked | Reconnect Threads. |