Publishing to Threads via API: A technical guide
Understanding permissions, the container model, carousels, topic tags, and API endpoints for Threads content publishing.
Before you start: Verification and app review
Before your app can publish to Threads in production, you must complete two steps:
- Tech Provider Verification - Meta requires verification of your identity as a tech provider before you can access Advanced Access permissions. This process can take up to a week.
- App Review - Each permission requires a separate app review submission with a screencast demonstrating how your app uses that specific permission. If your app has not been approved for Advanced Access for
threads_content_publish, you can only post to your own account and your app’s tester accounts.
The app review process takes 2-4 weeks per Meta’s documentation. Each screencast must show the complete user journey for that permission in your app.
Required permissions
To publish content and access insights on a Threads account, your app needs these permissions approved:
threads_basic- Required for all Threads API endpointsthreads_content_publish- Create and publish poststhreads_manage_insights- Access account and post analytics
Each of these permissions needs its own app review submission with a screencast.
The container model
Threads publishing uses the same two-step container model as Instagram:
- Create a container — POST to
/{threads-user-id}/threadsto create the media container - Publish the container — POST to
/{threads-user-id}/threads_publishwith the container ID to make it live
All requests go to the Threads-specific base URL: https://graph.threads.net/v1.0/. This is different from the graph.facebook.com base URL used by Facebook and Instagram.
All media must be hosted on a publicly accessible URL at the time of the create request — Meta will cURL your media directly from that URL. Wait at least 30 seconds between creating and publishing a container to allow processing time.
Publishing text, image, and video posts
POST to /{threads-user-id}/threads:
{ "media_type": "IMAGE", "image_url": "https://example.com/photo.jpg", "text": "Your caption text"}Set media_type to TEXT, IMAGE, or VIDEO. For video posts, use video_url instead of image_url. Text posts are limited to 500 characters — emojis count as their UTF-8 byte length.
Publish with a POST to /{threads-user-id}/threads_publish:
{ "creation_id": "<THREADS_MEDIA_CONTAINER_ID>"}Publishing carousels
Carousels support up to 20 images and/or videos per post (minimum 2 items). This is a three-step process:
Step 1: Create item containers
Create a container for each image or video with is_carousel_item set to true:
{ "media_type": "IMAGE", "image_url": "https://example.com/photo1.jpg", "is_carousel_item": true}Repeat for each item, up to 20.
Step 2: Create the carousel container
POST to /{threads-user-id}/threads:
{ "media_type": "CAROUSEL", "children": "<CONTAINER_1>,<CONTAINER_2>,<CONTAINER_3>", "text": "Carousel caption"}Step 3: Publish
POST to /{threads-user-id}/threads_publish with the carousel container ID. Carousels count as a single post against the rate limit.
Topic tags, links, and GIFs
These extras are available when creating a media container:
Topic tags make posts discoverable. Use the topic_tag parameter (1–50 characters, no periods or ampersands):
{ "media_type": "TEXT", "text": "Discussing the latest in AI", "topic_tag": "artificial-intelligence"}Links attach a URL preview to text-only posts. Use the link_attachment parameter, or include a URL in the text field and it will automatically become the link preview. Posts are limited to 5 unique links total.
GIFs can be attached to text-only posts using the gif_attachment parameter. Tenor is the only supported provider:
{ "media_type": "TEXT", "text": "Nailed it", "gif_attachment": {"gif_id": "<TENOR_GIF_ID>", "provider": "TENOR"}}Media specifications
Images: JPEG or PNG, 8 MB max, aspect ratio up to 10:1, width between 320 and 1440 pixels, sRGB color space.
Videos: MOV or MP4 container, H264 or HEVC codec, 23–60 FPS, max 1920px width, 5 minutes max duration, 1 GB max file size. Audio must be AAC at up to 48 kHz, mono or stereo.
Rate limits
Threads profiles are limited to 250 posts per 24-hour period. Carousels count as a single post against this limit.
The same video, through Postproxy
Here’s how it’s done with Postproxy. One simple request with only what matters:
curl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "Quick demo of the feature we have been working on" }, "profiles": ["threads"], "media": ["https://example.com/video.mp4"] }'One request. Postproxy handles the container creation, the processing wait, the status check, and the publish step.
What Postproxy handles
Postproxy maintains approved permissions and handles the complexity:
- All required permissions approved through app review
- Threads access token exchange and refresh
- The two-step container creation and publishing flow
- Unified API for text, images, videos, and carousels
- Rate limit monitoring and request pacing
Your system sends content. Postproxy handles the Threads-specific implementation.
Connect your Threads account and start publishing through the Postproxy API.