X Community Moderators API | List Community Mods
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.
GET community/moderators returns an X Community's moderators and admins, cursor-paginated, in the same { user, role } row shape Community Members uses. It is served by its own upstream operation, not by filtering the member roster, because moderators sit at arbitrary positions inside that roster and filtering one page would return the moderators among the first 20 members while looking complete. Paging is a bare next_cursor string. $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.
Comma-separated list of dotted field paths to keep in the response (one parameter, never repeated), applied to every object in the returned lists and to nested objects (for example fields=id,text,author.username; the list's own name may prefix a path, fields=tweets.id). A path prefix that lands on an array applies to each element (media.media_url_https). Pagination and envelope keys (next_cursor, cursor, has_more, count, partial, error, message, reason) are always kept. Unknown paths are ignored; up to 50 paths of up to 6 segments. Projection never changes status codes or billing, and applies to data reads only: account, feedback, session status, monitor (other than deliveries), webhook and stream-compat reads return their bodies unchanged.
Set to 1 (or true) to apply the built-in compact preset: ids, url, text, created_at, lang, the engagement counts, the is_retweet/is_reply/is_quote flags, conversation ids, the author's id/username/name/followers_count/verification, and the quoted or retweeted tweet's id/url/author username. The preset trims what it recognises and leaves alone what it would empty, so it never turns a body into {}. Combine with fields to add paths on top of the preset. Typically cuts a tweet page by 70 to 90 percent for LLM tool callers.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/community/moderators?community_id=1493446837214187523&count=20&fields=id%2Ctext%2Ccreated_at%2Cauthor.username&compact=1"{ "members": [ { "user": { "id": "1281109705495130113", "username": "pizzaboy", "name": "Dan Holdsworth", "profile_image_url": "https://pbs.twimg.com/profile_images/..._normal.png", "is_blue_verified": true, "verified": false, "is_protected": false }, "role": "Admin" }, { "user": { "id": "3310215544", "username": "buildlogs", "name": "Build Logs", "profile_image_url": "https://pbs.twimg.com/profile_images/..._normal.png", "is_blue_verified": true, "verified": false, "is_protected": false }, "role": "Moderator" } ], "next_cursor": null, "has_more": false}{ "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": "forbidden", "message": "X refused this resource for the acting account: on a read, the account is not a participant in the DM thread, the target is protected or has blocked it, or the session was attestation-blocked for calling from a datacenter or rotating IP; on a write, the account is not authorized for the action or has no logged-in session. The credentials are still valid, so do not re-register."}{ "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 when you need to know who can moderate a community, for example before pitching a post or reporting content. Use Community Members when you want the whole roster, which includes these accounts tagged by role.
Notes
- This is a SEPARATE upstream operation, not a filter over Community Members, and the difference is correctness rather than efficiency: moderators are interleaved through the member roster at arbitrary positions, so filtering page one of that roster would return the moderators among the first 20 members while looking like a complete answer.
- The collection key is members, matching Community Members exactly. Both endpoints return the same row type so they cannot drift apart, and so a mixed role set on this endpoint surfaces rather than being flattened away.
- Same paging contract as Community Members: a bare next_cursor string, no total, no has_more from X. has_more is computed for you.
- The user objects are the same REDUCED profile Community Members returns. Call User Info on an id for the full profile.
- If X returns a response shape this API does not recognise, you get a 502 parse_failed rather than a 200 with an empty list, and the call is not billed to you. Telling you a community has no moderators when we simply failed to parse the answer would be the one failure you could not detect.
Pagination
Same contract as Community Members: a bare next_cursor string, no total count and no has_more from X, so has_more is computed for you. Pass next_cursor back as ?cursor= and stop when members comes back empty or has_more is false. An empty FIRST page is a 404; an empty page WITH a cursor is a normal end-of-list.
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 Tweets: Page through a community's post timeline, with the pinned post returned separately.
- Community Memberships: List every community a given account belongs to.
FAQ
Why not just filter Community Members for role Moderator?
Because moderators are not grouped in that roster. In the captured community the admin was at index 0 and moderators at indexes 1 and 13, so filtering the first page returns the moderators among the first 20 members and reads as a complete moderator list. Doing it correctly would mean paging the entire roster, which costs a call per page.
Why is the array called members rather than moderators?
Because it is the same row type Community Members returns, deliberately. One shape for both endpoints means they cannot drift, and it means a moderator roster that comes back with an unexpected role mix is visible in the data rather than hidden by a type that assumed the role was constant.
Does this include admins as well as moderators?
Yes. Admins carry role Admin and moderators carry role Moderator, so read the role field rather than assuming every row is a moderator.
What does an empty response mean?
An empty FIRST page is returned as a 404, meaning the id did not resolve or the roster is not visible. An empty page reached with a cursor is a normal end of list. A response X sent that this API could not parse is a 502, never a 200 with an empty array.
Community Members GET
Fetch the member roster of an X Community, cursor-paginated, with each row carrying that member's own role in the community: Admin, Moderator or Member. Admins and moderators appear in this list alongside ordinary members and are not grouped, so do not derive a moderator list by filtering the first page. Billed at $0.0008 per call. Cost: $0.0008 per call.
Community Tweets GET
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.