Skip to content
Threads integration · v1

Threads API for text, image and video posts

Threads processes every post asynchronously, even plain text. PostMCP creates the container, polls it to FINISHED and publishes — one call from your side.

Endpoint
POST /api/tools/create_post
Platform value
"threads"
Auth
x-api-key or Bearer token
Upstream
graph.threads.net v1.0
Overview

What the Threads API gives you

The Threads API mirrors Instagram's container model, with one twist that catches people out: text posts are asynchronous too. Every post — TEXT, IMAGE or VIDEO — creates a container that must reach FINISHED before threads_publish will accept it.

PostMCP runs that loop against graph.threads.net/v1.0 with a window sized to the media type: roughly 30 seconds for text and images, 60 for video. Errors come back with the error_message Threads returned rather than a generic failure.

Text posts

Plain posts are submitted as media_type: TEXT and published once the container settles.

Image posts

A public image_url plus optional text becomes an IMAGE container.

Video posts

.mp4 and .mov URLs are detected and submitted as VIDEO with a longer processing window.

Adaptive polling

Text and image containers poll for ~30 seconds; video gets ~60. The first check fires after 1.5s to keep short posts fast.

Scheduled publication

Queue by date and time, then edit or cancel before the slot.

Cross-posting

Ship the same copy to Instagram, Facebook, X, LinkedIn and Bluesky in one call.

Common uses

  • Mirror your X timeline to Threads without writing a second integration.
  • Post short build-in-public updates straight from a CI hook.
  • Let an agent adapt a long LinkedIn post into a 500-character Threads version.
  • Queue a launch sequence across Threads and Instagram in one script.
Quickstart

Post to Threads in three steps

Connect the account once, grab an API key, then send a single request. The same body works from a shell, a server, or an AI agent.

  1. 1

    Connect your Threads account

    Open the dashboard, choose Threads and complete the hosted connect flow. Credentials are encrypted into the user vault and never returned to your client.

  2. 2

    Create an API key

    Generate a key from the dashboard. Send it as x-api-key, as an Authorization: Bearer header, or as an apikey query parameter on the MCP transport.

  3. 3

    Send your first post

    POST to /api/tools/create_post with platforms: ["threads"]. Set publishImmediately to broadcast now, or supply scheduleDate and scheduleTime to queue it.

POST /api/tools/create_post
curl -X POST "https://api.postmcpai.com/api/tools/create_post" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $POSTMCPAI_API_KEY" \
  -d '{"content":"Shipping something new today. Built with PostMCP AI.","platforms":["threads"],"publishImmediately":true}'
Response — 200 OK
{
  "success": true,
  "message": "Post created and queued successfully",
  "post": {
    "id": "66a50c89e4b019a2b72f",
    "content": "Shipping something new today. Built with PostMCP AI.",
    "platforms": [
      "threads"
    ],
    "status": "published"
  }
}
Reference

Threads API endpoints

Every endpoint is a POST against the base URL https://api.postmcpai.com. The same seven operations cover all connected networks — set the platform value to "threads" to target Threads.

OperationEndpointWhat it does
preflight_postPOST/api/tools/preflight_postDry-run copy against limits, targets and credits before publishing.
create_postPOST/api/tools/create_postSchedule a post or broadcast it immediately.
publish_post_nowPOST/api/tools/publish_post_nowForce a queued post out ahead of its slot, or retry the profiles that failed.
list_postsPOST/api/tools/list_postsRead the queue — scheduled, published, draft and failed — with counts.
get_postPOST/api/tools/get_postRead one post, with per-profile delivery state and live URLs.
get_post_analyticsPOST/api/tools/get_post_analyticsRead how a post did: views, likes, comments and shares per profile.
get_profile_analyticsPOST/api/tools/get_profile_analyticsRead a profile’s followers, post count and views from its network.
update_postPOST/api/tools/update_postEdit copy, targets, schedule or status before publication.
reschedule_postPOST/api/tools/reschedule_postMove a post to another slot, keeping its copy and targets.
reset_stuck_postPOST/api/tools/reset_stuck_postRelease a post left stuck mid-publish so it can be retried.
delete_postPOST/api/tools/delete_postRemove a scheduled or draft post from the queue.
get_connected_accountsPOST/api/tools/get_connected_accountsList connected profiles, handles and page IDs per platform.
get_account_healthPOST/api/tools/get_account_healthFind connections whose token expired or is about to.
generate_imagePOST/api/tools/generate_imageGenerate a post image and get back a hosted URL for mediaUrl.
list_workspacesPOST/api/tools/list_workspacesList the workspaces on this key, with the id to scope other calls to.
get_user_infoPOST/api/tools/get_user_infoRead plan tier and credit balance.

create_post parameters

FieldTypeRequiredDescription
contentstringYesText body of the post. Truncation rules are enforced by the destination network, not by PostMCP.
targetAccountsarray[object]YesThe profiles that receive the post. Each entry takes platform and profileId (from get_connected_accounts). Only the profiles listed here are posted to.
platformsarray[string]OptionalShorthand for whole networks — linkedin, twitter, facebook, instagram, threads, bluesky, youtube. Each one expands to every connected profile on it, so prefer targetAccounts unless you mean that fan-out. Optional when targetAccounts is given.
publishImmediatelybooleanOptionalWhen true the post is broadcast on receipt. Defaults to false, which queues it.
scheduleDatestringOptionalPublication date as YYYY-MM-DD. Required when publishImmediately is false.
scheduleTimestringOptionalPublication time as HH:MM on a 24-hour clock. Required when publishImmediately is false.
timezonestringOptionalIANA zone the schedule above is written in, e.g. Asia/Kolkata. Omit it and the wall-clock slot resolves as UTC, which is rarely what "10am" meant.
mediaUrlstringOptionalPublicly reachable image or video URL. PostMCP fetches it and re-uploads it in the format the network expects. Required, and must be a video, when the post targets YouTube.
workspaceIdstringOptionalWorkspace to post from, taken from list_workspaces. Omitted, the call resolves to the default workspace on the key.
Authentication

Threads OAuth and API keys

Two layers of auth sit under every request: the Threads credential you grant once during connect, and the PostMCP API key your code sends on each call.

Step 1

Open the connect URL

Send the user to /connect/threads. PostMCP builds a threads.net/oauth/authorize URL carrying a signed state JWT.

Step 2

Threads consent screen

The user approves basic profile access and content publishing.

Step 3

Token exchange

The callback code becomes a Threads access token bound to the Threads user ID.

Step 4

Encrypted storage

The token is encrypted into the user vault and used automatically on publish.

Scopes requested from Threads

ScopeWhy it is needed
threads_basicReads the connected Threads profile and its user ID.
threads_content_publishCreates containers and publishes posts to the account.

Sending your API key

Header (recommended)x-api-key: pmcp_sec_…
Bearer tokenAuthorization: Bearer pmcp_sec_…
Query (MCP SSE)/mcp?apikey=pmcp_sec_…
Under the hood

How PostMCP publishes to Threads

One request from you becomes this sequence server-side. Knowing the shape helps when you are debugging a failed broadcast.

  1. 1

    Choose the media type

    No media means TEXT; a .mp4 or .mov URL means VIDEO; anything else means IMAGE with the text carried alongside.

  2. 2

    Create the container

    The body is POSTed to /{threads-user-id}/threads, returning a creation ID.

  3. 3

    Poll with an adaptive window

    First check after 1.5s, then every 3s — up to 10 attempts for text and images, 20 for video.

  4. 4

    Surface real errors

    An ERROR status raises the error_message Threads returned instead of a generic failure.

  5. 5

    Publish the container

    The creation ID is posted to /threads_publish and the returned ID is stored.

Upstream Threads calls

MethodEndpointPurpose
POSThttps://graph.threads.net/v1.0/{threads-user-id}/threadsCreates a TEXT, IMAGE or VIDEO container and returns a creation ID.
GEThttps://graph.threads.net/v1.0/{creation-id}?fields=status,error_messagePolls the container until status reads FINISHED or ERROR.
POSThttps://graph.threads.net/v1.0/{threads-user-id}/threads_publishPublishes the finished container by `creation_id`.

Direct Threads API vs PostMCP

AspectCalling Threads directlyWith PostMCP
Text postsStill asynchronous — container plus pollOne call, poll handled for you
Media typeSet TEXT, IMAGE or VIDEO yourselfInferred from the media URL
CarouselsOne container per item, then a CAROUSEL container with `children`One `mediaUrls` array of 2–20 URLs
Polling windowFixed retry loop you tune by handAdaptive to the media type
Error detailParse status and error_message manuallyThreads' own message surfaced verbatim
SchedulingNot offered by the APIBuilt in and editable
Constraints

Threads limits and supported media

These ceilings are set by Threads, not by PostMCP. Your content field is forwarded unchanged, so the network enforces them rather than silently truncating.

Text length500 characters per post
Media per post1 image or 1 video, or a carousel of 2–20 via mediaUrls
Image sourcePublic HTTP(S) URL
Video formatsMP4 and MOV
Processing window~30s text and image, ~60s video
API versiongraph.threads.net v1.0
Troubleshooting

Common Threads API errors

Failures are recorded per platform on the post record, so a multi-network broadcast that partially succeeds tells you exactly which leg failed and why.

CodeMessageLikely causeFix
400Threads Container creation failedA missing text body on a TEXT container, or a media URL Threads could not fetch.Send non-empty `content` for text posts and host media on a public URL.
ERRORThreads container processing failedThe container reported ERROR during processing, commonly an unsupported video encode.Re-encode video as H.264 MP4 and retry.
TIMEOUTThreads container processing timed outFINISHED was not reached inside the polling window.Use a shorter or smaller video asset.
190Access token for threads is missing or invalidThe Threads token expired or was revoked.Reconnect Threads from the dashboard.
Model Context Protocol

Post to Threads from an AI agent

The same seven operations are exposed as MCP tools. Point Claude Desktop, Cursor, or any MCP client at the server and your agent can publish to Threads directly.

claude_desktop_config.json
{
  "mcpServers": {
    "postmcpai": {
      "command": "npx",
      "args": ["-y", "@postmcpai/server"],
      "env": {
        "POSTMCPAI_API_KEY": "pmcp_sec_YOUR_SECRET_KEY",
        "POSTMCPAI_API_URL": "https://api.postmcpai.com"
      }
    }
  }
}

Prompt the agent directly

With the server connected, natural language is enough — the agent picks the tool and fills the arguments:

“Draft a Threads post about today’s release and schedule it for 9:30am tomorrow.”
FAQ

Threads API questions

How do I post to Threads with the API?

POST to https://api.postmcpai.com/api/tools/create_post with platforms: ["threads"] and your content. PostMCP creates the container on graph.threads.net, polls it to FINISHED and calls threads_publish.

Why do Threads text posts need a container?

The Threads API processes every post asynchronously, including plain text. The container must report FINISHED before threads_publish accepts it, which is why a naive two-call implementation intermittently fails.

Can I attach images or video to a Threads post?

Yes. Pass a public mediaUrl. A .mp4 or .mov URL is submitted as VIDEO; anything else is submitted as IMAGE with your text alongside.

Can I post a Threads carousel?

Yes. Pass mediaUrls with 2–20 public image or video URLs. Each becomes its own item container flagged is_carousel_item, is polled to FINISHED, and a CAROUSEL container listing them is created and published. Images and video can be mixed; order is kept as given.

What is the Threads character limit?

500 characters per post. Longer copy is rejected by Threads, so trim before sending or let an agent adapt it.

How long does Threads take to publish?

Text and image containers usually settle in a few seconds; PostMCP polls for about 30 seconds before giving up. Video gets a 60-second window.

Which permissions does the Threads API need?

threads_basic to read the profile and threads_content_publish to create and publish posts. Both are requested during the connect flow.

Other social media APIs

Start posting to Threads today

Connect the account, take an API key and send your first request in under five minutes — from a shell, your backend, or an AI agent.