One handle in. Clean JSON out.
Give this endpoint a Threads handle and it returns that account's recent public posts as a JSON array — text, engagement counts, timestamps, and whether each item is an original, a reply or a repost. Billing is 3 credits per post returned, so a 20-post pull costs 60 credits. One thing to know up front: Threads does not publish view counts on most posts, so there is no views field in the response.
Availability: Threads does not publish view counts for most posts, so `views` is omitted from responses. Reply threads and post transcripts are planned for v2.
The difference
On the left, what a headless browser hands you. On the right, what the endpoint hands you.
<div class="x1a2b3c x9k2m1 xdt5ytf" data-pressable-container="true"><div class="x78zum5 xdt5ytf"><div class="x9f619 x1n2onr6"><span class="x1lliihq x1plvlek"><span dir="auto" class="x1lliihq xjkvuk6">Everyone building ai agents keeps rediscovering the same three problems.</span></span></div><div class="x6s0dn4 x78zum5 xl56j7k"><div role="button" tabindex="0" class="x1i10hfl x1qjc9v5"><svg aria-label="Like" role="img" viewBox="0 0 24 24"><path d="M16.792 3.904..."></path></svg><span class="x17qophe">88.4K</span></div><div role="button" tabindex="0" class="x1i10hfl"><svg aria-label="Reply"></svg><span>2,314</span></div></div><time datetime="2026-07-07T09:40:00.000Z" class="x1rg5ohu">2h</time></div><script>requireLazy(["ServerJS"],function(f){f().handle({"__bbox":{"complete":true,"require":[["ScheduledServerJS"... {"data": [{"id": "C2isac0P7c7","url": "https://www.threads.com/@zuck/post/C2isac0P7c7","text": "Shipping notes: response times are down 40% after this week's cache work.","posted_at": "2026-07-07T09:40:00Z","metrics": {"likes": 88410,"replies": 2314,"reposts": 1290,"quotes": 214}}],"meta": {"count": 2,"limit": 20,"item": "post"},"request_id": "req_01JZX4M8Q2TE9W"}
The payload
An array of post objects for the handle you passed, newest first. Each object carries the post body text, the four public counters Threads does expose (likes, replies, reposts, quotes), the publish timestamp, and two booleans that tell you what kind of item you are looking at.
Those two booleans matter more than they look. A Threads feed mixes original posts, replies the account left on other people's threads, and straight reposts of other accounts. All three land in your array. If you are measuring what an account publishes, filter on is_reply === false && is_repost === false before you compute anything, or your averages will be dragged around by replies that were never meant to stand alone.
There is no numeric post id from the listing source, so id falls back to the shortcode when nothing else is present. shortcode is always the more reliable join key — it is the segment at the end of the post URL and it never changes.
Handle of the account that wrote the post. On reposts this is the original author, not the handle you queried.
Pricing
Billing is per post returned at 3 credits, about 1.5¢ on the monthly plan, so a 20-post pull costs 60 credits or roughly 30¢; an empty result still costs 1 credit.
Estimate only, on a full-year basis. 3 credits per returned post. Monthly: $5 per 1,000 credits with $4/1,000 top-ups. Annual: $54 per 12,000 credits with $3/1,000 top-ups. We show whichever plan is cheaper for your annual volume, divided by 12. Failed calls are never charged; cache hits cost the same as fresh calls.
Entry price, side by side
Credits are not equivalent units across vendors — each meters differently. Price your own workload on both before deciding on entry price alone. At high volume, several of these are cheaper per credit than we are.
Engineering notes
We document exactly how every endpoint behaves — nulls, caching, billing — so what you ship on day one is still running in month six. No surprises, no support tickets.
Threads does not surface view counts publicly on most posts. Since we only read what is publicly visible, views is omitted from the response entirely rather than returned as null on every row. If your model needs impressions, this endpoint cannot supply them and no amount of retrying will change that.
Use likes plus replies plus reposts plus quotes as your engagement proxy instead. It is a ratio you can compute consistently across every post in the array, which matters more than the absolute number.
You get replies as an integer. You do not get who replied, what they said, or the tree beneath a post. Reply threads and post transcripts are on the roadmap for v2 and are not in the current response. We would rather say that plainly than let you discover it after you have wired up a parser.
The 3-credit price is per post in the array. Ask for 50 posts and the call costs 150 credits; ask for 10 and it costs 30. Set your limit to what you will actually use rather than pulling the maximum by habit — this is the single easiest way to overspend on a list endpoint.
If a handle has fewer public posts than your limit, you are charged for what came back, not what you asked for.
When is_repost is true, the likes, replies, reposts and quotes describe the original post by the original author, and the author field holds that original handle. Summing engagement across an unfiltered array therefore credits the queried account with reach it did not generate.
Repeat calls for the same handle inside the cache window return from cache in milliseconds and set x-cache: hit. A cache hit is billed the same as a fresh one. Pass fresh=true when you are specifically checking for new posts and the window has not expired yet.
Questions
Send a GET to /v1/threads/posts with the handle and your API key. There is no OAuth step, no Meta app review, and no business verification. The endpoint reads the same public profile page anyone can open logged out and returns the posts as JSON. Meta's own Threads API only reaches posts belonging to the authenticating account, which rules it out for competitor or research work.
Because Threads does not publish them. View counts are visible to the post author inside their own insights, and are not shown on the public post for other viewers. We only return what is publicly readable, so views is absent from the response rather than present and permanently null. If impressions are essential to your analysis, Threads is not a platform where public data can give them to you.
3 credits per post, so 100 posts is 300 credits. At $0.005 per credit on the monthly plan that is $1.50, or $1.35 on annual pricing at $0.0045. Because billing is per item, the limit you set is the lever that controls cost. Failed calls are not charged.
Not yet. The response includes a replies count for each post but not the reply text, the repliers, or the thread structure below it. Reply threads and post transcripts are planned for a future version. If you need conversation data today, this endpoint will not give it to you, and we would rather tell you now than take the credits.
Yes, all three appear in the array, which is why every item carries is_reply and is_repost. Filter both to false when you want only what the account originally published. On reposts the author field and the engagement counters belong to the original poster, so leaving them in will inflate any per-account total you compute.
It reads the public profile feed from the newest post backwards and returns up to limit posts in that one call. There is no pagination — no cursor, no page token, no offset — so whatever a single call returns is as far back as you can go, and how deep that reaches depends on what the profile exposes. Very old posts on high-volume accounts will fall outside it. Deep historical backfill is not something this endpoint can do. For an ongoing archive, poll regularly and store by shortcode.
No. Only public profiles are readable. A private account returns an error and the call is not billed. We read logged out, the same way an anonymous visitor would, and we do not attempt to reach anything behind a follow approval or a login wall.
Next
100 trial credits on signup — no card, key on screen immediately.