Skip to main content

1. Overview

Threads publishing uses three distinct flows depending on content type. Text-only posts use a single atomic API call (no container polling). Image and video posts use a two-step flow: container creation then publish, with polling added for video containers until they reach FINISHED. Carousel posts use a three-step flow: one container per item, then a parent carousel container, then publish.

2. Supported media

SocialAPI auto-detects the media type from the URL file extension. Video detection inspects the URL path, ignoring query parameters (safe for presigned S3 URLs). Text limit: 500 characters. Carousel limit: Maximum 20 items per post.

3. Create post

Use POST /v1/posts with targets targeting a Threads account. The text field becomes the post body.

Platform data fields

Pass these inside platform_data.threads: SocialAPI forwards any additional keys in platform_data.threads directly to the underlying platform API. These fields are not validated by SocialAPI and may break if the platform changes its API. See Threads API reference for the full list of supported parameters.

Scheduling

Set scheduled_at to an ISO 8601 timestamp (UTC) to defer publishing:

4. Update post

Threads does not support editing a published post via the API. PATCH /v1/posts/:pid for a Threads target returns 501 Not Implemented. If you need to correct a post, delete it and recreate it.

5. Delete post

Or, to delete only the Threads target of a cross-platform post:
Deletion calls DELETE /{media-id} on the Threads Graph API. If the media ID no longer exists on Threads, the API returns success.

6. Retrieve posts

Use GET /v1/posts to list posts. Filter by platform or account:
Each post includes a targets array with per-platform status and engagement metrics:
Metrics notes: SocialAPI fetches likes and replies via the Threads /insights endpoint (requires the threads_manage_insights scope). However, that scope is not requested by default, so like and reply counts remain 0 for most connected accounts. Shares and saves are not available from the Threads API at all. To enable metric collection, contact us about the threads_manage_insights beta scope.

7. Quirks, errors, and recovery

Container polling for video

After creating a video container, SocialAPI polls the container status (once per minute, up to 5 attempts) before publishing. If the container reaches FINISHED or PUBLISHED, the post is immediately sent to threads_publish. If the container returns ERROR or EXPIRED, the publish fails. If the container does not finish within 5 minutes, SocialAPI returns 504 Gateway Timeout and marks the post target as failed. Image posts proceed to publish directly after container creation, without polling. Text posts use a single atomic call and skip both container creation and polling entirely.

No post editing

Threads has no API for editing a post’s text or media after publication. Attempting PATCH /v1/posts/:pid targeting Threads always returns 501 Not Implemented. Delete and recreate the post if a correction is needed.

Text-only posts

Unlike Instagram, Threads supports text-only posts natively. Omit media_ids entirely to create a post with just a text body. The container is created with media_type: TEXT.

reply_control defaults to “everyone”

If reply_control is not set in platform_data.threads, the Threads API defaults to "everyone". You must explicitly pass "accounts_you_follow" or "mentioned_only" to restrict who can reply.

Token expiry

Threads long-lived user access tokens expire after approximately 60 days. SocialAPI stores the token and its expiry. When a token expires, publish calls will fail with an auth error. Reconnect the account via the OAuth flow to obtain a fresh token.

Error shapes

When a publish fails, the post target’s error field contains a structured error:

Recovery

  • Auth error: Disconnect and reconnect the Threads account through the OAuth flow to obtain a fresh token.
  • Container timeout: Usually caused by a large video file or a slow upstream URL. Re-upload the media and retry.
  • API error: Retry the post via POST /v1/posts/:pid/retry after reviewing the message field for platform guidance.

8. Full worked example

The following example publishes a video post with restricted reply control, then checks its status. Step 1: Upload media
Response:
Upload the file directly to the presigned URL, then verify:
Step 2: Publish the post
Response (container polling starts in background):
Step 3: Check status
Response once published:

9. Required OAuth scopes

SocialAPI’s managed Meta Threads App requests the following scopes on your behalf during the OAuth flow. This is informational — you do not need to configure anything. To verify which scopes your connected account has granted, call GET /v1/accounts/:id/limits.