One URL in. Clean JSON out.
Give this endpoint a public Facebook post URL and it returns the comments on that post as a JSON array. Each comment costs 3 credits, and you control how many you pull with the limit parameter, so a 20-comment fetch is 60 credits. No Graph API app, no page access token, no review process.
This fixed it for me, thank you
The difference
On the left, what a headless browser hands you. On the right, what the endpoint hands you.
<div class="x1yztbdb x1n2onr6 xh8yej3" data-visualcompletion="ignore"><div class="x78zum5 xdt5ytf"><div dir="auto" class="xdj266r x11i5rnm x1mh8g0r">Weekend build: three settings we changed after your feedback</div></div><div class="x9f619 x1ja2u2z x78zum5"><span class="xt0b8zv x1jx94hy" aria-label="5.2K reactions"><i data-visualcompletion="css-img"></i></span><span class="x193iq5w">331 comments</span><span class="x1s688f">128 shares</span></div><abbr data-utime="1751630400" class="x1i10hfl">3d</abbr><script>requireLazy(["CometResourceScheduler"],function(f){f().schedule({"__bbox":{"require":[["adp_Comet... {"data": [{"id": "c_9021","text": "This fixed it for me, thank you","author": {"handle": "dev.casey"},"likes": 412,"posted_at": "2026-07-01T09:12:00Z"}],"meta": {"count": 2,"limit": 50},"request_id": "req_01JZX4M8Q2TE9W"}
The payload
An array of comment objects. Every object carries the comment id, the comment text, the display name of whoever wrote it, a like count, and a publish timestamp. That is the whole shape — five keys, flat, no nesting.
Comments come back in the order the upstream reader walks the thread, which tracks Facebook's own default ordering on the post rather than strict recency. If you need chronological order, sort on posted_at yourself after the response lands. Do not assume index 0 is the newest comment.
What you get is one batch, sized by `limit`. There is no cursor, page token or offset in the response, so you cannot walk further down a thread with a follow-up call — a bigger `limit` on a single call is the only lever. On a post with thousands of comments, plan around that before you build.
Comments with no text body are dropped before you see them. A reaction-only or sticker-only comment has nothing to return, so it never appears in the array and you are never billed for it. This means the array length can be smaller than the comment count Facebook displays on the post.
ISO 8601 UTC timestamp for the comment. Null when Facebook only shows a relative age we cannot resolve to a date.
Pricing
Each comment returned is 3 credits — about 1.5¢ on the monthly plan, so the default 20-comment fetch runs 60 credits or roughly 30¢. Billing is per comment, and an empty result still costs 1 credit.
Estimate only, on a full-year basis. 3 credits per returned comment. 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.
Billing is 3 credits per comment returned, not per call. Leaving limit at its default of 20 costs 60 credits; asking for 200 costs 600. On a post with thousands of comments the bill scales linearly, and there is no volume discount hiding in the pricing.
For most sentiment work a sample of the first 50 comments tells you what the first 500 would. Start small, look at the data, then decide whether the extra depth is worth the credits.
If a post has fewer comments than your limit, you are billed for what actually came back. Requesting 100 on a post with 12 comments costs 36 credits, not 300.
The response is a flat list. There is no parent id, no depth marker, and no thread structure, so a reply to a comment looks identical to a comment on the post. If your analysis depends on knowing what replied to what, this endpoint cannot give you that and you should not try to infer it from ordering.
Facebook shows commenters by name on public posts, so a name is what we return. Names are not unique, users change them, and two rows with the same author string are not necessarily the same person. Treat it as a label, not a key.
Because these are real people's names, the response is personal data under GDPR and similar regimes. Have a lawful basis before you store it, and set a retention period. We read only what any logged-out visitor sees, but that does not make the storage question go away.
Facebook often renders comment age as "2 h" or "Yesterday" rather than a date. When we can resolve that to a real timestamp we do; when we cannot, posted_at is null rather than a guess. Handle the null instead of assuming every row sorts.
Responses sit in the fast cache class, so a repeat call for the same post URL inside the window returns in milliseconds with x-cache: hit. A cache hit is billed the same as a fresh pull. Pass fresh=true when you are polling an active thread and need comments posted in the last few minutes.
Questions
Send a GET to /v1/facebook/comments with the public post URL and your API key. There is no app to register, no page access token, and no App Review. The Graph API only returns comments on pages you administer and have been granted permissions for, which rules it out for competitor research or any post you do not own. This endpoint reads the public post the same way a logged-out browser does.
300 credits — 3 credits per comment. Credits are $0.005 each on monthly billing and $0.0045 on annual, so 100 comments runs about $1.50, or $1.35 annual. You are charged for comments actually returned, so a post with only 30 comments costs 90 credits even if you asked for 100. Failed calls are not billed.
Replies may appear in the array, but they are not labelled as replies. The response has no parent id and no nesting, so you cannot reliably tell a reply from a top-level comment or reconstruct a thread. If threading matters to your analysis, this endpoint is not the right shape for it.
No. Only public posts are reachable. Private groups, friends-only posts and anything behind a login return an error rather than partial data, and the call is not charged. We do not authenticate, do not use member sessions, and do not attempt to reach content that is not publicly visible.
Two reasons. Comments with no text — stickers, images, bare reactions — are dropped, because there is nothing useful to return, and Facebook's displayed count includes them. Second, deeply buried and collapsed comments on very large threads are not always reachable from the public rendering. Set limit to what you need and treat the array length as the ground truth for billing.
No. The only identity field is author, a display name string. There is no profile URL, user id, follower count or location in the response. If you need account-level data you would have to identify the account another way first, and this endpoint will not help you do that.
As often as you like, subject to your plan's rate limit. Repeat calls inside the fast cache window return the cached array in milliseconds at the same credit cost; add fresh=true to force a new read. For an active thread, hourly with fresh=true and deduping on id is a sane pattern. Polling every minute mostly buys you duplicate rows.
Next
100 trial credits on signup — no card, key on screen immediately.