TL;DR, Quick Answer
7 min readMeta caps Threads text posts at 500 characters and counts emoji as UTF-8 bytes. A topic can be attached two ways: the topic_tag parameter, which sits outside the text field and is capped at 1 to 50 characters, or an in-text tag starting with a hash sign, which lives inside text and therefore spends the 500. Meta does not state whether a topic_tag value counts against the post limit.
What does the Threads API 500 character limit apply to?
Meta scopes the Threads API 500 character limit to the text parameter of a media container, and keeps topic_tag as a separate parameter with its own 50-character ceiling. The cap appears as a one-line bullet under Limitations in the Single Thread Posts section: "Text posts are limited to 500 characters." The Threads overview page repeats the same sentence word for word under Other Limitations.
Neither page attaches a field name to that sentence. The container endpoint accepts text on TEXT, IMAGE, VIDEO and CAROUSEL media types, and the 500 bullet sits under a heading about text posts, so Meta leaves open whether a caption on an image post gets the same ceiling. No second number appears anywhere in the Threads documentation, which makes 500 the only cap an integration can plan against for any text value.
The counting rule attached to that bullet is the part most character counters get wrong: "Emojis are counted as the number of UTF-8 bytes." A four-person family emoji costs 25 against the 500 rather than 1, which is covered in full in why the Threads character limit counts emoji as UTF-8 bytes.
Does topic_tag count against the 500?
Meta does not say. The topic_tag parameter is documented in its own subsection with its own constraint, "Topic tags must be at least 1 character and no more than 50 characters long", and nothing on either the posts guide or the publishing reference ties that value to the post character limit.
What the docs do establish is where each thing lives. topic_tag is a separate form field on POST /{threads-user-id}/threads, sent alongside text:
curl -i -X POST \
-d "media_type=TEXT" \
-d "text=<TEXT>" \
-d "access_token=<ACCESS_TOKEN>" \
-d "topic_tag=<TAG>" \
"https://graph.threads.net/v1.0/<THREADS_USER_ID>/threads"An in-text tag is the opposite case and needs no ruling from Meta, because the tag is part of the string you put in text. Every character of #socialmedia is a character of the post, so an in-text tag spends the 500 by construction. That asymmetry is the practical reason to prefer the parameter: the in-text route is a documented charge against the 500, and the parameter route is an open question.

What is the difference between topic_tag and an in-text tag?
Meta supports both and marks one of them legacy. The in-text method carries an explicit warning in the docs: "This method is not preferred but is kept for backwards compatability."
topic_tag parameter | In-text tag | |
|---|---|---|
| Where it lives | Its own form field | Inside text |
| Length rule | 1 to 50 characters | 1 to 50 characters |
| Hash sign | Not used | Required to start the tag |
| Spends the 500 | Meta does not say | Yes, every character |
| Status in Meta's docs | Current | "not preferred but is kept for backwards compatability" |
One rule applies to both routes: "Only one topic tag is allowed per post, so the first valid tag included in a post of any type (text-only, image, video, carousel) via the API is treated as the tag for that post." Extra hash-sign words in the body do not become extra topics, and they still cost characters.
The two documentation pages also disagree on how much they tell you. The posts guide states the 1 to 50 character range for topic tags. The POST /{threads-user-id}/threads reference lists topic_tag with only the banned characters and no length rule at all, so a developer reading the reference alone never sees the 50.
Which characters are banned in a Threads topic tag?
The two routes have different banned lists, and the in-text list is far longer. For the parameter, Meta bans two characters: periods and ampersands. For an in-text tag, Meta says "any in-text tag that starts with a hash sign will end just before these characters" and then gives the full set.
| Route | Characters that are not allowed |
|---|---|
topic_tag parameter | Periods (.), ampersands (&) |
| In-text tag | Spaces, tabs, new line characters, periods (.), ampersands (&), at signs (@), exclamation marks (!), question marks (?), commas (,), semi-colons (;), colons (:) |
A separate rule kills numeric tags: "Whole numbers that are preceded by a hash sign (i.e., #1) will not be converted into a tag. This is because it is assumed that # is signifying a number sign in this scenario." Meta also notes that "The text is also configured in the app without the hash sign", so the hash is markup for the API rather than part of the topic.
The practical consequence is silent truncation. Writing #social media in text produces the topic "social" and leaves the word "media" as plain text, with no error and no warning. Sending social media as topic_tag keeps the whole phrase.
What other text fields does the Threads API cap?
Four different limits govern what goes into one Threads post, and only one of them is the 500. Confusing them is the usual cause of a container that fails at creation for reasons the character counter never predicted.
| Field | Limit | Where Meta states it |
|---|---|---|
text | 500 characters, emoji counted as UTF-8 bytes | Posts guide, Limitations under Single Thread Posts |
topic_tag | 1 to 50 characters | Posts guide, Topic Tags |
alt_text | 1,000 characters | Publishing reference, POST /{threads-user-id}/threads |
| Links in a post | 5 or fewer | Posts guide, Links |
The link rule is the only one with a documented failure string. From December 22, 2025, Meta states that "Threads posts containing more than 5 links will fail to post during the media creation step (POST /{threads-user-id}/threads) with the error code: THREADS_API__LINK_LIMIT_EXCEEDED." Links are counted after deduplication: a URL repeated in text counts once, and a link_attachment that matches a URL already in text "is only counted once, rather than twice".
AdaptlyPost
Start Your 7-Day Free Trial
All-platform analytics
Social Inbox
AI-powered assistant
Nothing comparable exists for the 500. The Threads API Reference index carries no error codes page, and the troubleshooting page documents only container status values and video error_message values, so an over-length text has no published error constant to catch.
What happens if text runs past 500?
Meta documents the limit and not the response, so the only reliable move is to measure before sending. Because emoji are counted as UTF-8 bytes rather than characters, the measurement has to be done on the encoded string. A JavaScript String.length of 475 can be 517 bytes once a few emoji are in it, which is exactly the failure mode described on the Threads character limit page.
The same byte-counting question shows up on every network that stores post text as UTF-8, including the way Bluesky facets index links by byteStart and byteEnd rather than by character position. Any integration that publishes to more than one network needs one byte-accurate counter, not one per platform.

What does this mean for scheduled Threads posts?
A scheduler composes the container long before the publish call, so the 500 has to be enforced at draft time rather than at send time. Two checks cover most of it: count text in UTF-8 bytes, and move topics into topic_tag instead of into the body when the post is close to the ceiling.
The publish-side constraint is separate, since Threads also caps a profile at 250 API-published posts within a 24-hour moving period. Character limits reject a container at creation, and quota limits reject it at publish, which are two different failures to design around. For teams planning Threads alongside other networks, the Threads scheduling tool page covers how AdaptlyPost connects through the official API.
Frequently asked questions
Is the Threads API 500 character limit the same as the one in the Threads app?
The 500 figure Meta publishes for the API matches the number Threads shows in its own composer, and Meta documents the byte-counted emoji rule only in the API documentation. The API pages are the ones that state the rule precisely, so treat them as the specification for anything you build.
Can a Threads post have more than one topic tag?
No. Meta states that "Only one topic tag is allowed per post", and that the first valid tag in a post of any type is the one that gets used. Additional hash-sign words remain plain text inside text and still count toward the 500.
Does the hash sign count as a character in an in-text tag?
An in-text tag lives inside the text value, so every character of it counts, hash sign included. Meta notes that the topic itself is stored without the hash: "The text is also configured in the app without the hash sign."
Why does my topic tag get cut off in the middle?
An in-text tag ends at the first character on Meta's banned list, which includes spaces, periods, ampersands, at signs, exclamation marks, question marks, commas, semi-colons and colons. A multi-word topic written in the body therefore becomes a one-word tag. Send it through the topic_tag parameter instead, where spaces are not on the banned list.
How long can Threads alt text be?
1,000 characters. Meta states the number in the POST /{threads-user-id}/threads reference: "The maximum length of alt_text is 1,000 characters." That budget is separate from the 500 on text.
Where does Meta document the 500-character limit?
In two places, with identical wording. The posts guide at developers.facebook.com/documentation/threads/posts carries "Text posts are limited to 500 characters." under Limitations in the Single Thread Posts section, and the overview page at developers.facebook.com/documentation/threads/overview repeats it under Other Limitations. The emoji byte-counting rule appears next to it on the posts guide.
Is topic_tag counted in UTF-8 bytes like text?
Meta states the UTF-8 byte rule only for the text field, tied to the 500 limit. The topic_tag subsection gives a 1 to 50 character range with no mention of bytes, so whether an emoji-heavy tag counts as bytes or characters is not documented. Treat the 50 as characters until Meta says otherwise, since that is the unit the docs actually use.
What happens if a Threads post has more than 5 links?
The container fails at creation. Meta states the error arrives during the media creation step, POST /{threads-user-id}/threads, with the code THREADS_API__LINK_LIMIT_EXCEEDED. It is the only limit on the page with a documented error string, unlike the 500 on text.
Does a repeated link count twice toward the 5-link cap?
It counts once. Meta counts links after deduplication, so the same URL appearing twice in text is one link, and a link_attachment that matches a URL already in text is "only counted once, rather than twice." Five unique links remain the ceiling.
AdaptlyPost
Start Your 7-Day Free Trial
All-platform analytics
Social Inbox
AI-powered assistant
Can topic_tag be used on an image or video post, not just text-only?
Yes, the rule covers every media type. Meta says the first valid tag in "a post of any type (text-only, image, video, carousel)" becomes the tag for that post, so topic_tag works the same way whether the container carries an image, a video, or a carousel.
Put this into practice with AdaptlyPost
Was This Article Helpful?
Let us know what you think!
See us more often in Google
One click marks AdaptlyPost as a preferred source, so our articles sit higher in your Top Stories, AI Mode, and AI Overviews.
Before you go...
AdaptlyPost
Schedule your content across all platforms
Manage all your social media accounts in one place with AdaptlyPost.
All-platform analytics
Social Inbox
AI-powered assistant
Related Glossary Terms


How the Threads API Carousel Maximum Items Cap Works
Meta sets the Threads API carousel maximum items cap at 20 children and a minimum of 2. Here is the per-item container flow and what a bad carousel returns.


How the Threads API 250 Posts Per Day Limit Works
Meta's Threads API 250 posts per day limit is a 24-hour moving window on publishes. Carousels count once, and one endpoint reports what a profile has left.


What Happens to a Threads Ghost Post After 24 Hours
A Threads ghost post is a text-only post Meta archives after 24 hours. Replies can route to your inbox, and the API creates one with is_ghost_post=true.
Related Articles


Why the Threads Character Limit Counts Emoji as UTF-8 Bytes
The Threads character limit is 500, but Meta counts each emoji as its UTF-8 byte length, so one family emoji costs 25. Here is how to count a post correctly.


Why TikTok API pull_from_url Domain Verification Rejects Your Host
TikTok API pull_from_url domain verification is a DNS check on the host you send. Fail it and every init call returns url_ownership_unverified.


The TikTok AI Generated Label Is Two Different Labels
The TikTok AI generated label comes two ways: a creator label you apply with is_aigc, and an auto label from AI effects or C2PA that you cannot remove.

