Zernio
Zernio
Overview

Social Posting

XInstagramFacebookLinkedInTikTokYouTubePinterestRedditBlueskyThreadsGoogle Business ProfileSnapchat

Messaging

WhatsAppTelegramDiscordSlack

Telephony

Phone NumbersVoice & CallsSMS

Advertising

Meta AdsGoogle AdsLinkedIn AdsTikTok AdsPinterest AdsX AdsOpenAI Ads

Commerce

Shopify
Dashboard
llms.txtOpenAPI
OverviewPlatformsAPI ReferenceResources

Threads

Publish text, image, video and carousel posts and thread sequences to Threads with the Zernio API, with topic tags, first comments and reply management.


Publish text, image, video and carousel posts and thread sequences to Threads with POST /v1/posts and platform: "threads". The same account serves analytics and reply management in the inbox.

Quick reference

PropertyValue
Character limit500
Images per post10 (carousel)
Videos per post1
Image formatsJPEG, PNG
Image max size8 MB (auto-compressed)
Video formatMP4 (H.264/AAC)
Video max size1 GB
Video max duration5 minutes
Post typesText, Image, Video, Carousel, Thread sequence
SchedulingYes
Inbox (comments)Comment, reply, delete, hide and unhide
Inbox (DMs)No
AnalyticsYes (views, likes, comments, shares)

Before you start

Threads requires an Instagram Business or Creator account with Threads enabled. The account connects through Instagram authentication (the same Facebook app), so losing Instagram access means losing Threads, and a restricted Instagram account cannot publish to Threads either. An account can publish 250 API posts per 24 hours.

Threads posts are at most 500 characters. A caption cross-posted from LinkedIn (3,000), Facebook (63,206) or Instagram (2,200) fails with "Param text must be at most 500 characters long." Send a shorter Threads version in customContent.

Connect

Call GET /v1/connect/threads with profileId on Get OAuth connect URL. The user authorizes with the Instagram account that owns the Threads profile. The connecting accounts guide covers the OAuth flow and scopes in general; Account health reports what a connected account can do with the scopes the user granted.

OAuth scopes

ScopeWhat it enables
threads_basicAccount identity and basic profile data
threads_content_publishPublish threads and carousels
threads_read_repliesRead replies to your threads
threads_manage_repliesReply to, hide and manage replies
threads_manage_insightsPost and account analytics
threads_deleteDelete threads through the API

Publish

A plain post becomes a text post. Add mediaItems for an image, a video or a carousel, and threadItems in platformSpecificData for a chain of connected posts.

Text post

Threads accepts text-only posts of up to 500 characters, with no media required.

import Zernio from '@zernio/node';

const zernio = new Zernio();

const { data: published } = await zernio.posts.createPost({
  body: {
    content: 'Hot take: the best API is the one with the best docs.',
    platforms: [
      { platform: 'threads', accountId: '66b2e19d8c3f5a7e9d0b1c2d' }
    ],
    publishNow: true
  }
});

console.log(published.post.platforms[0].platformPostUrl);

Response (201):

{
  "post": {
    "_id": "65f1c0a9e2b5af0012ab34cd",
    "status": "published",
    "platforms": [
      {
        "platform": "threads",
        "status": "published",
        "platformPostUrl": "https://www.threads.net/@yourhandle/post/..."
      }
    ]
  }
}

Every sample below changes only the mediaItems or the platforms entry of this request.

Image post

A single image with an optional caption:

"mediaItems": [
  { "type": "image", "url": "https://cdn.example.com/office.jpg" }
]

Video post

A single video with an optional caption, at most 1 GB and 5 minutes:

"mediaItems": [
  { "type": "video", "url": "https://cdn.example.com/launch.mp4" }
]

Carousel

Up to 10 images in one swipeable post:

"mediaItems": [
  { "type": "image", "url": "https://cdn.example.com/feature1.jpg" },
  { "type": "image", "url": "https://cdn.example.com/feature2.jpg" },
  { "type": "image", "url": "https://cdn.example.com/feature3.jpg" }
]

Thread sequence

threadItems publishes a chain of connected posts. The first item is the root post and each later item is a reply to the one before it, in order; every item carries its own text and optional media. With threadItems set, the top-level content is stored for display and search only and is not published, so the first post must be threadItems[0].

{
  "platform": "threads",
  "accountId": "66b2e19d8c3f5a7e9d0b1c2d",
  "platformSpecificData": {
    "threadItems": [
      {
        "content": "Here is a thread about API design",
        "mediaItems": [{ "type": "image", "url": "https://cdn.example.com/cover.jpg" }]
      },
      { "content": "1/ First, REST principles." },
      {
        "content": "2/ Authentication. Here is what we recommend.",
        "mediaItems": [{ "type": "image", "url": "https://cdn.example.com/auth-diagram.jpg" }]
      },
      { "content": "3/ Finally, always version your API. /end" }
    ]
  }
}

Topic tags

topic_tag sets the post's topic tag for discoverability. It is 1 to 50 characters, cannot contain periods (.) or ampersands (&), and overrides the tag Threads would extract from hashtags in the content.

{
  "platform": "threads",
  "accountId": "66b2e19d8c3f5a7e9d0b1c2d",
  "platformSpecificData": { "topic_tag": "APIDesign" }
}

Platform fields

All fields go in platformSpecificData on the Threads entry.

FieldTypeDefaultDescription
topic_tagstring(from hashtags)Topic tag for categorisation and discoverability. 1 to 50 characters, no periods (.) or ampersands (&). Overrides auto-extraction from content hashtags.
firstCommentstringPosted right after publishing as a reply to the published post (with threadItems, a reply to the root post). Up to 500 characters. It is itself a Threads post, so it counts toward the 250 posts per 24 hours.
threadItemsArray<{content, mediaItems?}>The complete sequence of posts in a thread. The first item becomes the root post and must be threadItems[0]. When set, the top-level content is for display and search only and is not published.

Media requirements

Images above 8 MB are compressed automatically. Original files are preserved.

Images

PropertyRequirement
Max images10 per post (carousel)
FormatsJPEG, PNG
Max file size8 MB per image (auto-compressed)
Recommended1080 x 1350 px (4:5 portrait)
RatioDimensionsNotes
4:51080 x 1350 pxPortrait, recommended
1:11080 x 1080 pxSquare
16:91080 x 608 pxLandscape

Videos

PropertyRequirement
Max videos1 per post
FormatMP4 (H.264/AAC)
Max file size1 GB
Max duration5 minutes
Aspect ratio9:16 (vertical), 16:9 (landscape), 1:1 (square)
Resolution1080p recommended
CodecH.264
Frame rate30 fps recommended
AudioAAC, 128 kbps

Media URLs

Threads fetches media the same way Instagram does. A media URL must be publicly accessible with no authentication, return the media bytes with the correct Content-Type header, and not redirect to an HTML page; Google Drive, Dropbox, OneDrive and iCloud sharing links return a webpage and fail. WebP images may fail, so use JPEG or PNG. To host files instead, use the media endpoint.

Analytics

Call GET /v1/analytics?platform=threads (Analytics API).

MetricAvailable
Likes
Comments
Shares
Views

Threads' insights expose no impressions metric, so views is the reach figure to report. shares adds reposts and quotes together.

const { data: analytics } = await zernio.analytics.getAnalytics({
  query: { platform: 'threads', fromDate: '2026-08-01', toDate: '2026-08-31' }
});

console.log(analytics.posts);

Response (200), one entry per post:

{
  "posts": [
    {
      "_id": "65f1c0a9e2b5af0012ab34cd",
      "platform": "threads",
      "status": "published",
      "publishedAt": "2026-08-14T10:00:05Z",
      "platformPostUrl": "https://www.threads.net/@yourhandle/post/ABC123xyz",
      "analytics": {
        "likes": 164,
        "comments": 19,
        "shares": 12,
        "views": 8210,
        "engagementRate": 2.38
      }
    }
  ]
}

Inbox

Threads supports comments only: you can comment, reply, delete, hide and unhide, but not like a comment. A comment on Threads is a reply to the thread, so omitting commentId replies to the post itself. Threads has no DMs.

FeatureSupported
List comments on posts
Post a new top-level comment (omit commentId and the reply lands on the post)
Reply to comments
Delete comments
Like comments
Hide and unhide comments

Hide a reply with POST /v1/inbox/comments/{postId}/{commentId}/hide and unhide it with DELETE on the same path; the Comments API lists every endpoint.

What you cannot do

Threads' API does not expose:

  • Polls
  • GIF search
  • Editing a post after publishing
  • Who liked or reposted a post
  • Quote posts
  • Liking or unliking comments
  • DMs

Common errors

ErrorCauseFix
"Param text must be at most 500 characters long."The post exceeds 500 charactersShorten to 500 characters. Use customContent on cross-platform posts so each platform gets its own version.
"Media download has failed. The media URI doesn't meet our requirements." (2207052)Threads cannot fetch media from the URLThe URL must return media bytes, not an HTML page. WebP may fail; use JPEG or PNG.
"Instagram account is restricted." (2207050)The linked Instagram account is restrictedCheck the account status on Instagram and resolve any policy violation before retrying.
"Publishing failed due to max retries reached"Every publishing retry was exhaustedUsually temporary. Wait a few minutes and retry.

A publishNow: true post that Threads rejects returns 207 with post.status: "failed" and the message in platforms[].errorMessage:

{
  "message": "Post created but publishing failed",
  "error": "All platforms failed",
  "post": {
    "_id": "65f1c0a9e2b5af0012ab34cd",
    "status": "failed",
    "platforms": [
      {
        "platform": "threads",
        "status": "failed",
        "errorMessage": "Param text must be at most 500 characters long."
      }
    ]
  }
}

207 is a 2xx status, so fetch(...).ok is true; branch on the status code and on post.status. Error handling covers the envelope.

Related

  • Connecting accounts: the OAuth flow through Instagram.
  • Create post: every field of the request.
  • Media uploads: upload images and videos instead of hosting them.
  • Analytics: post performance metrics.
  • Comments: the inbox API for replies.
  • Pricing: what analytics, the inbox and outbound messages cost, and which replies count.
Was this page helpful?

Bluesky

Publish text, image, video and thread posts to Bluesky with the Zernio API, connected with an app password instead of OAuth.

Google Business Profile

Publish updates, events and offers to a Google Business Profile location with the Zernio API, then manage its reviews, listing details and performance metrics.

On this page

Quick referenceBefore you startConnectOAuth scopesPublishText postImage postVideo postCarouselThread sequenceTopic tagsPlatform fieldsMedia requirementsImagesVideosMedia URLsAnalyticsInboxWhat you cannot doCommon errorsRelated