Threads Publishing
Learn how to connect Threads accounts and publish text posts, photos, carousels, videos, and long-form threads.
Connecting Threads Account
Prerequisites
- A Threads account (by Instagram/Meta)
- Signed in to Boring Dashboard
Connection Steps
- Click the "Connect Threads" button on the dashboard
- Log in to Threads (if not already logged in)
- Authorize Boring to access your Threads account
- Grant the required permissions:
threads_basic- Basic account informationthreads_content_publish- Publish contentthreads_manage_replies- Create and manage thread replies (required for long-form threads)threads_manage_insights- Access analytics and insightsthreads_read_replies- Read replies to posts
- Click "Authorize"
Your Threads account will appear in the Authorized Accounts list with:
- Threads username
- Profile picture
- Platform badge (Threads)
- Unique Account ID (click "Copy ID")
- Disconnect option
Token Information
- Token Type: Long-lived User Access Token
- Initial token: 1 hour (short-lived)
- Converted to: 60 days (long-lived) automatically
- Expiration: 60 days from authorization
- Auto-refresh: Automatic refresh 5 days before expiry
Note: Unlike Instagram, Threads tokens auto-refresh! You shouldn't need to manually reconnect.
Supported Content Types
Threads supports the most diverse content types:
| Type | Description | Media Count | Text Format | Example |
|---|---|---|---|---|
| Text | Text-only post | 0 | String | Quick thoughts, updates |
| Photo | Single image | 1 | String | Image with caption |
| Carousel | Multiple images | 2-20 | String | Photo series, guides |
| Video | Video content | 1 | String | Short videos, clips |
| Thread | Long-form thread | 0-1 | Array | Multi-post stories |
Key Feature: Threads is the only platform that supports:
- Text-only posts (no media required)
- Carousels up to 20 images
- Long-form multi-post threads
Publishing Examples
1. Text-Only Post
{
"post": {
"accountId": "your-threads-account-id",
"content": {
"text": "Just launched our new feature! Check it out π",
"mediaUrls": [],
"platform": "threads"
},
"target": {
"targetType": "threads"
}
}
}
Result: Simple text post on Threads.
Text Requirements:
- Max length: 500 characters
- Emojis supported
- URLs automatically linkified
- @mentions supported
2. Single Photo Post
{
"post": {
"accountId": "your-threads-account-id",
"content": {
"text": "Beautiful morning view π
",
"mediaUrls": ["https://example.com/morning.jpg"],
"platform": "threads"
},
"target": {
"targetType": "threads"
}
}
}
Result: Image post with caption on Threads.
Photo Requirements:
- Format: JPG, PNG, WEBP
- Max file size: 8MB
- Aspect ratio: Any (1:1 recommended)
- Min resolution: 320x320
3. Carousel Post
{
"post": {
"accountId": "your-threads-account-id",
"content": {
"text": "Our journey in photos πΈ",
"mediaUrls": [
"https://example.com/photo1.jpg",
"https://example.com/photo2.jpg",
"https://example.com/photo3.jpg",
"https://example.com/photo4.jpg",
"https://example.com/photo5.jpg"
],
"platform": "threads"
},
"target": {
"targetType": "threads"
}
}
}
Result: Carousel post with multiple swipeable images.
Carousel Requirements:
- Min images: 2
- Max images: 20 (higher than Instagram/Facebook!)
- Formats: JPG, PNG, WEBP
- All images must be valid URLs
4. Video Post
{
"post": {
"accountId": "your-threads-account-id",
"content": {
"text": "Quick demo of our new app feature π₯",
"mediaUrls": ["https://example.com/demo.mp4"],
"platform": "threads"
},
"target": {
"targetType": "threads"
}
}
}
Result: Video post on Threads.
Video Requirements:
- Format: MP4, MOV
- Max file size: 512MB
- Max duration: 5 minutes
- Aspect ratio: Any (9:16 recommended)
Note: Video processing is asynchronous and may take a few minutes.
5. Long-Form Thread (Multi-Post)
This is the most powerful feature of Threads!
{
"post": {
"accountId": "your-threads-account-id",
"content": {
"text": [
"Let me tell you a story about building our product π§΅",
"It all started with a simple idea: make social media publishing easier for developers.",
"We researched the pain points: token management, platform differences, complex APIs.",
"So we built Boring: one API to rule them all. Simple, secure, and reliable.",
"Today we're proud to support Facebook, Instagram, and Threads. More platforms coming soon!",
"Thank you for being part of our journey π"
],
"mediaUrls": [],
"platform": "threads"
},
"target": {
"targetType": "threads"
}
}
}
Result: A connected thread with 6 posts, each replying to the previous one.
Thread Requirements:
- Text must be an array of strings
- Each string becomes a separate post
- Posts are connected as replies
- Max posts: Limited by API rate limits
- Each post max: 500 characters
Note: Requires threads_manage_replies permission!
Text Format Detection
Boring API automatically detects the post type based on the text field:
| Text Format | Result |
|---|---|
"text": "string" |
Single post (text, photo, carousel, or video) |
"text": ["s1", "s2"] |
Long-form thread (multi-post) |
Examples:
# Single post
{"text": "Hello world", "mediaUrls": []}
# Single post with photo
{"text": "Check this out", "mediaUrls": ["image.jpg"]}
# Carousel
{"text": "Photo series", "mediaUrls": ["img1.jpg", "img2.jpg"]}
# Long-form thread (6 posts)
{"text": ["Post 1", "Post 2", "Post 3", "Post 4", "Post 5", "Post 6"], "mediaUrls": []}
API Request Format
Full Example (Python) - Long-Form Thread
import requests
API_URL = "https://boring.aiagent-me.com/v2/posts"
API_KEY = "boring_xxxxxxxxxxxxx"
ACCOUNT_ID = "your-threads-account-id"
# Create a long-form thread
thread_content = [
"π¨ Product Launch Alert! π¨",
"We're excited to announce Boring API v3.0 with Threads integration!",
"What's new:\nβ
Text-only posts\nβ
Carousels up to 20 images\nβ
Long-form threads\nβ
Auto token refresh",
"Why Threads?\n\nThreads is perfect for storytelling, updates, and engaging with your audience in a conversational way.",
"Getting started is easy:\n1. Sign in\n2. Connect Threads\n3. Generate API key\n4. Start publishing",
"Check out our docs at boring-doc.aiagent-me.com for examples and guides!",
"What would you like to see next? Reply and let us know! π¬"
]
post_data = {
"post": {
"accountId": ACCOUNT_ID,
"content": {
"text": thread_content, # Array of strings = thread
"mediaUrls": [],
"platform": "threads"
},
"target": {
"targetType": "threads"
}
}
}
headers = {
"boring-api-key": API_KEY,
"Content-Type": "application/json"
}
response = requests.post(API_URL, headers=headers, json=post_data)
result = response.json()
if result["success"]:
print(f"Thread published! Main post ID: {result['data']['post_id']}")
print(f"Total posts: {result['data']['thread_count']}")
else:
print(f"Error: {result['message']}")
Success Response (Thread)
{
"success": true,
"message": "Post published successfully",
"data": {
"post_id": "17885748657253466",
"post_type": "thread",
"platform": "threads",
"page_name": "your_username",
"thread_count": 7,
"post_ids": [
"17885748657253466",
"17885748657253467",
"17885748657253468",
"17885748657253469",
"17885748657253470",
"17885748657253471",
"17885748657253472"
],
"published_at": "2025-01-20T10:30:00Z"
}
}
Media URL Requirements
Same as other platforms:
- Publicly accessible
- Direct file URLs
- HTTPS protocol
- Valid content-type headers
Supported formats:
- Images: JPG, PNG, WEBP
- Videos: MP4, MOV
Best Practices
1. Long-Form Threads
Structure your thread:
- Start with a hook (attention-grabbing first post)
- Break down complex topics into digestible chunks
- Use 3-7 posts for optimal engagement
- End with a call-to-action
Example thread structure:
thread = [
"π§΅ Why [topic] matters (thread)", # Hook
"First, let's define [topic]...", # Context
"The main problem is...", # Problem
"Here's how we solve it...", # Solution
"Real example: [case study]", # Evidence
"Key takeaway: [summary]", # Summary
"What do you think? [CTA]" # Engagement
]
2. Text-Only Posts
Perfect for:
- Quick updates
- Announcements
- Questions to audience
- Thoughts and opinions
Tips:
- Keep it concise (under 280 chars ideal)
- Use emojis strategically
- Ask questions to drive engagement
- Use line breaks for readability
3. Carousels
Threads supports up to 20 images!
Use cases:
- Step-by-step tutorials (10+ steps)
- Product catalogs
- Before/after comparisons
- Event photo dumps
- Monthly recaps
4. Video Content
Best practices:
- Keep videos under 2 minutes
- Use vertical format (9:16)
- Add captions for accessibility
- Optimize for mobile viewing
5. Engagement
Threads is built for conversation:
- Reply to comments promptly
- Ask questions in your posts
- Use @mentions strategically
- Cross-reference your other threads
Troubleshooting
Common Errors
Error: "Invalid text format for thread"
- Cause: Text is array but contains invalid items
- Solution: Ensure all array items are non-empty strings
Error: "Missing threads_manage_replies permission"
- Cause: Trying to create thread without required permission
- Solution: Reconnect Threads account and grant all permissions
Error: "Token expired"
- Cause: 60-day token expired (auto-refresh failed)
- Solution: Reconnect Threads account from dashboard
Error: "Carousel size exceeds limit"
- Cause: More than 20 images in carousel
- Solution: Reduce to 20 or fewer images
Error: "Text exceeds maximum length"
- Cause: Single post text over 500 characters
- Solution: Split into multiple posts (use array format)
Publishing Delays
Threads posts may take time to process:
- Text posts: Instant
- Photo posts: 1-5 seconds
- Carousel posts: 5-15 seconds
- Video posts: 30 seconds - 3 minutes
- Long threads: 10-30 seconds per post
The API handles retries automatically.
Advanced Features
Dynamic Thread Generation
Generate threads from long text:
def split_into_thread(long_text, max_chars=450):
"""Split long text into thread posts"""
sentences = long_text.split('. ')
posts = []
current_post = ""
for sentence in sentences:
if len(current_post) + len(sentence) < max_chars:
current_post += sentence + '. '
else:
posts.append(current_post.strip())
current_post = sentence + '. '
if current_post:
posts.append(current_post.strip())
return posts
# Usage
article = "Your very long article text here..."
thread_posts = split_into_thread(article)
post_data = {
"post": {
"accountId": ACCOUNT_ID,
"content": {
"text": thread_posts, # Automatically becomes a thread
"mediaUrls": [],
"platform": "threads"
},
"target": {"targetType": "threads"}
}
}
Thread with Images
Add an image to the first post of a thread:
post_data = {
"post": {
"accountId": ACCOUNT_ID,
"content": {
"text": [
"Here's our announcement π",
"This feature has been requested by many users.",
"We're rolling it out today!"
],
"mediaUrls": ["https://example.com/announcement.jpg"], # Only first post gets image
"platform": "threads"
},
"target": {"targetType": "threads"}
}
}
Note: Currently, only the first post in a thread can have media attached.
Cross-Platform Publishing
Adapt content for Threads from other platforms:
def adapt_for_threads(content):
text = content['text']
# If text is very long, split into thread
if len(text) > 450:
return {
"text": split_into_thread(text),
"mediaUrls": content['mediaUrls'][:1], # Only first image
"platform": "threads"
}
else:
return {
"text": text,
"mediaUrls": content['mediaUrls'][:20], # Up to 20 images
"platform": "threads"
}
Rate Limits
Threads API rate limits:
- Per user: 250 calls/hour
- Per app: 5000 calls/hour
Thread publishing: Each post in a thread counts as 1 API call.
Publishing History
View your Threads posts in the dashboard:
- Sign in to Boring Dashboard
- Scroll to "Recent Posts" section
- Filter by Threads platform
For thread posts, you'll see:
- Post type: "thread"
- Thread count (number of posts)
- All post IDs
- Main post preview
Feature Comparison
| Feature | Threads | ||
|---|---|---|---|
| Text-only | β | β | β |
| Single photo | β | β | β |
| Carousel | β (2-10) | β (2-10) | β (2-20) |
| Video | β | β (Reels) | β |
| Long-form thread | β | β | β |
| Max text | Unlimited | 2,200 | 500/post |
| Token expiry | Never | 60 days | 60 days |
| Auto-refresh | N/A | β | β |
Next Steps
- Facebook Publishing - Learn about Facebook
- Instagram Publishing - Learn about Instagram
- API Reference - Complete API documentation
- Examples - Real-world thread examples