Threads API

Read public Threads posts and replies without a Threads login

The Threads API returns public Threads data as clean JSON.

no credit card1,000 free credits · instant API key · pay by card or crypto
Missing a Threads endpoint, or need a source we don't have yet?Contact us real people · same-day reply.
T
/threads/v1

11 active endpoints, on 1 and 2 credit tiers.

  • POST/threads/v1/profile
  • POST/threads/v1/posts
  • POST/threads/v1/replies
  • POST/threads/v1/reposts
  • POST/threads/v1/post
  • POST/threads/v1/post_replies
  • POST/threads/v1/search
  • +4 more

What Threads endpoints does ReefAPI ship?

11 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.

11 endpoints

profile

1 cr

Public Threads profile by username.

required
username
optional

posts

1 cr

Public posts from a Threads profile (most-recent first).

required
username
optional
limit

replies

1 cr

Public replies from a Threads profile (the Replies tab).

required
username
optional
limit

reposts

1 cr

Posts a Threads user has reposted.

required
username
optional
limit

post

1 cr

Maximally-complete public post detail.

required
optional
url, username, code, post_id

post_replies

1 cr

The reply conversation for a public post (thread_items).

required
optional
post_id, url, username, code, limit

search

2 cr

Search public Threads posts by keyword.

required
q
optional
query, limit

user_search

1 cr

Look up the public Threads account whose handle matches a query (exact / near-exact).

required
q
optional
query

followers

1 cr

Account-gated.

required
optional
username

following

1 cr

Account-gated.

required
optional
username

likes

1 cr

Account-gated.

required
optional
url, username, code, post_id

Every parameter, every allowed value →

Threads API

3 of 11 endpoints, ready to run

View docs ↗

A public profile's own posts, newest first, with the full text, media, engagement counts and an epoch timestamp on every row.

1 credit1 required · 1 optional
POST/threads/v1/posts
ok4789 ms · 25 records · sample
{
  "ok": true,
  "meta": {
    "api": "threads",
    "endpoint": "posts",
    "mode": "live",
    "latency_ms": 4788.9,
    "record_count": 25,
    "cache_hit": false
  },
  "data": {
    "posts": [
      {
        "id": "3973700216319662010_63269174602",
        "code": "Dcla0sNoFe6",
        "url": "https://www.threads.com/@natgeo/post/Dcla0sNoFe6",
        "text": "Who doesn't love a dramatic landscape? Share yours below. 👇",
        "media_type": "image",
        "width": 612,
        "height": 612,
        "like_count": 274,
        "taken_at": 1787922019
      },
      {
        "id": "3972976735905715440_63269174602",
        "code": "Dci2UqkjRTw",
        "url": "https://www.threads.com/@natgeo/post/Dci2UqkjRTw",
        "text": "We're always thriving and always looking for answers. 😌",
        "media_type": "image",
        "width": 612,
        "height": 612,
        "like_count": 43,
        "taken_at": 1787835755
      },
      {
        "id": "3971737290786552475_63252977324",
        "code": "DcecgXWgTqb",
        "url": "https://www.threads.com/@natgeotv/post/DcecgXWgTqb",
        "text": "Don't lie, you know you're on here. \n\nAll titles now streaming on @DisneyPlus.",
        "media_type": "image",
        "image_url": "https://scontent-fra5-2.cdninstagram.com/v/t51.82787-15/783486002_17985092508105325_9100778026343163303_n.jpg?stp=dst-jpg_e35_tt6&_nc_cat=109&ig_cache_key=Mzk3MTczNzI5MDc4NjU1MjQ3NQ%3D%3D.3-ccb7-5&ccb=7-5&_nc_sid=58cdad&efg=eyJ2ZW5jb2RlX3RhZyI6IkZFRUQueHBpZHMuMTA4MC5zZHIucmVndWxhcl9waG90by5DMyJ9&_nc_ohc=iYKhnj98aYQQ7kNvwHoJyQn&_nc_oc=Adp_5CLYkWJqOG0_73LC62OeRTxOumAH8g87XMkWeN_vQPHsIviIMP_0FnevkoSLpnA&_nc_ad=z-m&_nc_cid=0&_nc_zt=23&_nc_ht=scontent-fra5-2.cdninstagram.com&_nc_gid=2xLaXgkOrY-sHiPRsjBvRw&_nc_ss=7a22e&oh=00_AQEFVsdvYcgDIK0SwpCuR2xmUdfMl0h6Fo43_iWrIPqmWQ&oe=6A97A600",
        "width": 1080,
        "height": 1350,
        "like_count": 27,
        "reply_count": 1,
        "taken_at": 1787688021
      }
    ]
  }
}
Real response, fetched from the live endpoint with the parameters on the left — trimmed to the first few rows, with seller names left out. Press Try it for the untrimmed response.

How the Threads API works

Threads is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.

01
Authenticate
x-api-key header

No OAuth app, no request signing, no per-site account. One key covers all 184 engines.

02
Call
POST /threads/v1/…

Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.

03
Pay
1 or 2 credits per call

Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.

04
Read
{ ok, data, meta, error }

One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.

Handle to post to conversation, three calls

Threads gives a logged-out reader a profile, its posts and the replies under any one of them. That is the chain, and none of it asks anything of you but a key.

01posts
POST/threads/v1/posts
{"username": "natgeo", "limit": 25}

The profile's posts newest-first, each with url, code, text, media, like count and taken_at as a unix timestamp.

02post
POST/threads/v1/post
{"url": "<the url from any row>"}

The same post in full — like, reply, repost, quote and reshare counts, media dimensions, tagged accounts and language.

03post_replies
POST/threads/v1/post_replies
{"url": "<the same url>", "limit": 25}

The conversation, as a list of posts. Twenty-six replies came back for the post we tested, each a complete record with its own url and timestamp.

A profile's output and the discussion underneath any part of it, without a Threads session and without a scraped HTML string on your side.

request
curl -X POST https://api.reefapi.com/threads/v1/posts \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"username":"natgeo","limit":10}'
response envelope
{
  "ok": true,
  "data": { … },
  "meta": {
    "api": "threads",
    "endpoint": "posts",
    "mode": "live",
    "latency_ms": …,
    "record_count": …
  },
  "error": null
}

Threads id shapes, and what logged-out access cannot reach

Threads reuses Instagram's id conventions, and the same post is addressable three different ways depending on which action you call. The shapes below are from live responses. The gated rows are the ones that answer with an error no matter what you pass.

Field or actionMeasured behaviorNotes
post idNumeric post key, underscore, the author's numeric user id: 3971525888530486450_63269174602The suffix equals that author's profile.user_id. zuck's own posts end in _63055343223, which matches his profile exactly.
code11 characters, Instagram-style shortcode: DcdscDqIJSyThe /post/<code> segment. Pass code together with username, or pass the full url instead.
taken_atUnix epoch in SECONDS: 1787662820Not ISO-8601 and not milliseconds. Multiply by 1000 before feeding a JS Date.
search rowsid equals the code, not the numeric key, and rows carry username, text, url and timestamp_label onlyNo counts and no taken_at in search output. Re-fetch a hit with the post action if you need either.
followers, following, likesok false, error code DISABLED, retryable false — a refusal in under a second, and not chargedLogged-out Threads does not serve these lists at all. The aggregate follower_count and like_count are still available.
user_searchExact or near-exact handle resolve. NOT_FOUND with 'no public Threads account resolves for ...' when nothing matchesFuzzy people search is login-gated by Threads, so this resolves a handle rather than searching people.

profile returns username, full_name, biography, follower_count, profile_pic_url, user_id, is_verified, is_private and, when the account has any, bio_links. There is no post count and no following count on a logged-out profile.

What a logged-out reader gets, and what Threads keeps for itself

Measured on 2026-08-28 against two large accounts and one keyword search. The gated endpoints were measured too — the refusal is the finding.

No Threads account, and the gated endpoints say so out loud

You send a ReefAPI key and a handle. There is no Threads login of yours and no session cookie of yours in the path, so nothing of yours can be rate-limited or suspended. Where Threads itself requires a logged-in session — the followers list, the following list and the who-liked list — asking returns an immediate, explicit refusal naming the reason, in under a second, and is not charged. It does not hand back an empty array and let you assume, and it does not invent rows.

A profile's own posts reach back most of a year in one call

One account returned 39 posts spanning 2025-09-30 to 2026-08-10 — eleven months in a single call — with taken_at, text and like_count filled on 39 of 39. A second account returned 31 posts covering three weeks. The limit parameter is a ceiling rather than a promise: the profile serves one batch and we return what is in it.

Post detail carries the whole engagement set

Not only likes: reply, repost, quote and reshare counts all come back on a single post, alongside media type and dimensions, location, music, tagged accounts, link preview, language and the paid-partnership flag. Under four seconds.

Replies come back as posts, not as a second schema

The reply conversation is returned as full post records — id, code, url, text, media, counts and taken_at — so the code that walks a feed walks a thread. Twenty-six replies for one post and fifteen for another, both in about five seconds.

🔴 Keyword search finds posts but does not return clean ones

Against us. A search for one phrase returned 29 matching public posts and every row's url and code were correct — but the text field had the post's own engagement labels concatenated onto it, and the only time signal was a relative label rather than a timestamp, itself run together with other page text. Use search to discover URLs, then call post on each one for the clean record with its epoch timestamp. That is exactly the two-step in this page's recipe, and it is why search is not one of the examples above.

user_search resolves a handle; it does not browse people

Threads gates fuzzy people-search behind a login. Logged out, the action returns the single account whose handle matches the query — one row, in under two seconds. The engine's own description says so, and the measurement agreed.

What comes back, and what does not

Public profiles, public posts, public replies and public reposts. Not the followers list, not the following list, not who liked a post, not anything a private account has posted. Those are the platform's line rather than ours, and the API returns that line instead of working around it.

What people build with Threads

The jobs this data is most often used for.

11

endpoints

1/2

credits per call

01

Social analytics call profile and posts to measure a handle's reach.

02

Brand monitoring uses search and replies to track mentions.

03

Research uses reposts to gauge what spreads.

What Threads data costs

The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.

Full pricing →
$0.67–$1.50 / 1,000 credits
  • 1,000 free credits on signup, no card
  • One key, all 184 APIs, one credit pool
  • Failed and blocked calls are never charged
  • Credits roll over and never expire

Call it in two lines

Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.

curl
curl -X POST https://api.reefapi.com/threads/v1/posts \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"username":"natgeo","limit":10}'
python
import requests

r = requests.post(
    "https://api.reefapi.com/threads/v1/posts",
    headers={"x-api-key": REEF_KEY},
    json={
  "username": "natgeo",
  "limit": 10
},
)
print(r.json()["data"])
FAQ

Have a question? We got answers.

The questions people actually ask before wiring up Threads.

Get a free key →
Why does the replies action return posts written by other accounts?

Because the Threads Replies tab renders the conversation rather than the reply alone, so the parent post travels with it. A measured replies call for zuck with limit 25 returned 25 rows, of which 12 were authored by zuck and 13 by other handles. There are two clean ways to filter: compare the row's username, or read the numeric suffix of id, which is always the author's user id.

Should I check for null or for a missing key?

For a missing key. This engine omits what it did not find rather than emitting null. Measured: zuck's profile has no bio_links key at all while natgeo's and instagram's do; a text-only post carries neither image_url nor video_url; and some posts arrive with no reshare_count key even though quote_count is present and set to 0. Code that reads post.reshare_count directly will throw on perfectly valid posts.

The like count changed between two calls. Which one is right?

Both. These are live counters read at request time. The same natgeo post returned like_count 9413 and repost_count 244 from the posts action, then 9414 and 245 from the post action seconds later. The full set is like_count, reply_count, repost_count, quote_count, plus reshare_count where Threads exposes it. Treat them as a sample with a timestamp, not as a stable key.

What comes back for a video post versus an image post?

media_type tells you which, and the media fields follow from it. A video post returns media_type 'video' with video_url (the mp4) and image_url (the poster frame) plus width and height; an image post returns media_type 'image' with image_url only. Carousels arrive in carousel_media[]. All media points at Meta's CDN with query parameters attached, so download the bytes if you need them later rather than storing the URL.

Why does search return posts in languages I did not ask for?

Because search hands back Threads' own default results page and there is no language parameter. A measured q=reef returned Japanese, Indonesian and English posts inside the same five rows. Search rows are also thinner than profile rows: no counts, no taken_at, and timestamp_label is a display string like '4d' or '03/24/25' which on one row arrived with the post header text glued onto it. Use search to find codes, then call post for anything you plan to store.

What do I get for a handle that does not exist?

user_search answers cleanly: ok false, NOT_FOUND, retryable false. profile is less tidy on the same input and answers PARSE_ERROR with retryable true, because it cannot distinguish 'no such user' from 'the page shape changed'. Treat a repeated PARSE_ERROR on one specific handle as 'no such account' and stop retrying. A PARSE_ERROR that hits every handle at once is the other case.

Can I see who follows an account or who liked a post?

No. followers, following and likes all return DISABLED with retryable false, because Threads serves those lists only to a logged-in session and this engine is public-content-only. The aggregate numbers are unrestricted: profile returned follower_count 5720868 for zuck and 18281334 for natgeo, and every post carries its own like_count.

What is the Threads API?

Threads API is a ReefAPI endpoint group for threads It returns live JSON through POST requests under /threads/v1.

Is the Threads API free to try?

Yes. ReefAPI starts with 1,000 free credits, no card required. Threads calls use the same shared credit balance as every other ReefAPI engine.

Do I need a Threads login or account?

No login to Threads is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.

How fresh is the Threads data?

The page example is captured from a live profile call, and production requests fetch live data through ReefAPI rather than a static sample.

How many credits does the Threads API use?

Threads actions currently cost 1-2 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.

Can I call Threads from an AI assistant or MCP client?

Yes. Connect ReefAPI once through MCP and your assistant can call threads actions with the same key, credit pool and JSON envelope used by normal REST requests.

Is the Threads API a Threads scraper?

It is the managed alternative to a DIY Threads scraper. Instead of building and maintaining your own scraper — proxies, headless browsers, captcha and constant breakage — you call one ReefAPI endpoint and get the same threads back as clean JSON.

10 Social Media APIs on the same key

One key, one credit pool, one response envelope. If you are pulling Threads, you are one call away from the rest of the category — no second contract, no second integration.

Already paying for something else?Threads vs Apify

Need something this API does not do?

Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.

0/4000

No account needed · we reply from [email protected]

Try it on your own data before you pay anything

The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 183 APIs, and the same envelope everywhere.

Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-08-28.