Publishing to Threads via API: A technical guide

Understanding permissions, the container model, carousels, topic tags, and API endpoints for Threads content publishing.

Publishing to Threads via API: A technical guide

Before you start: Verification and app review

Before your app can publish to Threads in production, you must complete two steps:

  1. 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.
  2. 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 endpoints
  • threads_content_publish - Create and publish posts
  • threads_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:

  1. Create a container — POST to /{threads-user-id}/threads to create the media container
  2. Publish the container — POST to /{threads-user-id}/threads_publish with 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.

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.

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:

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": "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.

Ready to get started?

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