X Community Tweets API | Read Community Posts
Fetch the post timeline of an X Community, cursor-paginated as full tweet objects, with optional ordering control. The community's pinned post is returned as its own field rather than mixed into the feed, because X delivers it under a different timeline instruction and does not repeat it in the feed. Billed at $0.0008 per call. Cost: $0.0008 per call.
GET community/tweets returns an X Community's own post timeline, cursor-paginated as full tweet objects, plus the community's PINNED post as its own separate pinned field rather than an item inside tweets. X delivers the pinned post under a different timeline instruction and does not repeat it in the feed, so a client that reads only tweets silently misses it, and it is often the community's rules post. ranking_mode is a real upstream parameter, not a local sort. $0.0008 per call.
Authorization
bearerAuth Pass your API key as a bearer token on every request: Authorization: Bearer <API_KEY>.
In: header
Query Parameters
The numeric community id, the digits in a x.com/i/communities/ URL.
Pagination cursor from a previous response's next_cursor. Omit on the first call.
Page size. Defaults to 20 and is clamped to 1-100. A non-numeric value is a 400.
Ordering, sent to X as a real upstream parameter rather than applied as a local sort. Recency is the default and the only value confirmed against a live capture. Relevance is accepted because X's own community tab offers exactly two orderings, but it has not been confirmed live, so do not depend on it. Any other value is a 400.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/community/tweets?community_id=1493446837214187523&count=20&ranking_mode=Recency"{ "pinned": { "id": "1926022758195921145", "text": "Community rules: be useful, no unsolicited DMs, no engagement bait.", "created_at": "Fri May 23 09:14:02 +0000 2026", "author": { "id": "1281109705495130113", "username": "pizzaboy", "name": "Dan Holdsworth" }, "favorite_count": 118 }, "tweets": [ { "id": "1926104411223344556", "text": "Shipped the billing rewrite this morning. Numbers in the thread.", "created_at": "Fri May 23 14:41:19 +0000 2026", "author": { "id": "44196397", "username": "devjane", "name": "Jane" }, "favorite_count": 26, "reply_count": 4 } ], "next_cursor": "DAABCgABF...", "has_more": true}{ "error": "bad_request", "message": "Missing or malformed parameter. Fix the request before retrying."}{ "error": "unauthorized", "message": "The API key is missing, malformed, or revoked. Check the Authorization header."}{ "error": "insufficient_credits", "message": "Your balance is exhausted. Top up your credits to continue."}{ "error": "not_found", "message": "The resource does not exist, for example a deleted tweet or a private account."}{ "error": "rate_limited", "message": "Too many requests. Back off and retry with exponential backoff."}{ "error": "server_error", "message": "Something failed on our side. Retry with backoff; if it persists, contact support."}Pricing
| Unit | Price |
|---|---|
| Per call | $0.0008 |
| Per 1,000 calls | $0.80 |
| Per 1,000 records (~20 per call) | ~$0.04 |
When to use
Use this to read what is being posted inside a community, for monitoring or for analysis. Use Advanced Tweet Search when you want posts across all of X rather than inside one community, and Community Info when you want the community itself rather than its posts.
Notes
- THE PINNED POST IS ITS OWN FIELD AND IS NOT IN tweets. X delivers it under a different timeline instruction from the feed and does not duplicate it there, so a client that iterates only tweets loses it silently. It is usually the community's rules post. Read pinned first, then tweets, if you want one flat list.
- ranking_mode is a REAL upstream parameter, not a local re-sort. Recency is the default and the only value confirmed against a live capture. Relevance is accepted on the strength of X's own community tab offering two orderings, and is deliberately not advertised as confirmed until a capture shows it.
- This endpoint is cached for a shorter window than the other community reads, because it is the one surface callers poll for new posts. The rest of the community family is cached longer, since a community's metadata and roster change slowly.
- Every tweet on this timeline carries a caller-relative moderation state upstream. It is never extracted, so it does not reach you: like the nulled community fields, it would describe our pool account rather than yours.
- A 404 is returned only on an empty FIRST page, meaning the id did not resolve or the timeline is not visible. If X returns a shape this API does not recognise, you get a 502 parse_failed rather than a 200 with an empty feed, and that call is not billed to you.
Pagination
Pass the returned next_cursor straight back as ?cursor= for the next page. Stop when tweets comes back empty or has_more is false. Note that the pinned post is NOT part of the paged feed: it comes back on the page you ask for and is not an item you will meet again while paging.
Related endpoints
- Community Info: Metadata, rules and banners for one X Community.
- Community Members: Page through a community's member roster, each row carrying that member's role.
- Community Moderators: Page through a community's moderators and admins.
- Community Memberships: List every community a given account belongs to.
FAQ
Why is the pinned post not in the tweets array?
Because X does not put it there. It arrives under a separate timeline instruction and is not repeated in the feed, so merging it in would place an item at a position X never gave it, and a client paging the feed would meet it on no page and at no stable offset. Returning it as its own field is the only way to hand it over without inventing an ordering.
Is ranking_mode a real X parameter or your own sorting?
It is a real upstream parameter sent to X. Recency is the default and is the only value confirmed against a live capture; Relevance is accepted because X's own community tab offers two orderings, but treat it as unconfirmed until it is documented as observed here.
How do I build one flat list of community posts?
Read pinned first if it is non-null, then iterate tweets. The pinned post is excluded from tweets, so this produces no duplicate.
How fresh is the data?
This endpoint is cached for a much shorter window than the other community reads, precisely because it is the one people poll for new posts. Community info and the rosters are cached longer, since they change slowly.
Community Moderators GET
Fetch the moderators and admins of an X Community, cursor-paginated, in the same row shape Community Members returns. This is a separate upstream operation rather than a filter over the member roster, because moderators are interleaved through that roster at arbitrary positions. Billed at $0.0008 per call. Cost: $0.0008 per call.
Community Memberships GET
The inverse relation: given a numeric X user id, list the communities that account belongs to, cursor-paginated. Each row is the FULL community object, and it is the most populated form of it this API returns: admin, invites_policy, question, search_tags, members_facepile_ids and a real moderator_count all arrive here and do not on Community Info. Profiling an account's community footprint takes one call per page rather than a follow-up lookup per community. Billed at $0.0008 per call. Cost: $0.0008 per call.