XTwitter Community APIX Community Info APITwitter Community Details APICommunity Metadata

How to Get Twitter/X Community Details with an API

Build a Twitter/X community profile table with SocQ. Export names, rules and counts with source links and capture times, then connect posts for research.

SocQUpdated October 16, 20265 min read

Use SocQ to organize Twitter/X community names, descriptions, rules, and member and moderator counts in a profile table. Save the sources and capture times, then connect posts to the recorded community context for review.

The SocQ X Community API queries metadata by public community URL. This guide covers requests, returned fields, and JSON and CSV exports with source links and collection times.

Quick answer: Put x.com/i/communities/{numeric_id} links in urls and submit them to POST /v1/x/community. After success, read names, descriptions, rules, member and moderator counts, and joining and invitation policies from data.results.items. Query posts separately with Community Posts.

Build a Profile Table from Community URLs

Put a community URL in urls to query its name, description, rules, member and moderator counts, and joining and invitation policies. This example uses the Build in Public community:

https://x.com/i/communities/1493446837214187523

The final numeric segment is the community ID. Supply the complete /i/communities/{numeric_id} URL in urls.

When starting with a name, find its community URL first. Match records by numeric community ID and keep communities with different IDs separate even when their names match.

QuestionUse
What metadata is available for this community?X Community
Which posts can I collect from the community?X Community Posts
How are the posts in one discussion related?X Thread Context

This endpoint queries topic-community metadata. Community Notes are annotations attached to posts and are a separate data type.

Request Community Details

Set SOCQ_API_KEY, then submit the URL:

curl -X POST "https://api.socq.ai/v1/x/community" \
  -H "Authorization: Bearer $SOCQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"urls":["https://x.com/i/communities/1493446837214187523"]}'

For a batch, add public community links to urls. Each returned record describes one community; count results from the records actually returned.

Save data.task_id as TASK_ID, then query the existing task:

curl "https://api.socq.ai/v1/tasks/$TASK_ID?limit=100" \
  -H "Authorization: Bearer $SOCQ_API_KEY"

Wait between checks while the status is queued, running or retrying. After succeeded, read data.results.items and any remaining stored result pages. If the task fails, inspect data.error_message. Task pagination reads saved data; it does not refresh community information.

Read Rules, Counts and Joining Policies

This metadata example shows selected fields and one rule from the rules array:

{
  "id": "1493446837214187523",
  "type": "community",
  "name": "Build in Public",
  "metrics": {"members_count": 268858, "moderators_count": 6},
  "join_policy": "Open",
  "invites_policy": "MemberInvitesAllowed",
  "rules": [
    {
      "id": "1493447542045958144",
      "name": "Share what you're working on",
      "description": "Don't be scared to share unfinished work"
    }
  ],
  "collected_at": "2026-10-15T08:12:58.252843Z"
}

text stores the description, rules the structured rule list, and metrics the counts. Keep rule names and descriptions separate, with null for source-omitted descriptions.

metrics.members_count records the member total and metrics.moderators_count the moderator total. Save their collection times to compare counts for the same community across captures.

join_policy and invites_policy store the original joining and invitation policy strings. Keep the original when labeling a known value, and display unfamiliar values as returned. Verify actual joining access in X's current product interface.

Export a Community Profile Table with Python

Save this standard-library task helper as socq_collect.py:

import json
import os
import time
from urllib.parse import urlencode
from urllib.request import Request, urlopen

BASE = "https://api.socq.ai/v1"
PENDING = {"queued", "running", "retrying"}

def api(method, path, payload=None):
    body = json.dumps(payload).encode("utf-8") if payload is not None else None
    request = Request(
        BASE + path, data=body, method=method,
        headers={
            "Authorization": "Bearer " + os.environ["SOCQ_API_KEY"],
            "Content-Type": "application/json",
        },
    )
    with urlopen(request, timeout=60) as response:
        result = json.load(response)
    if result.get("code") != 200:
        raise RuntimeError(result)
    return result["data"]

def collect(endpoint, payload):
    task_id = api("POST", "/" + endpoint, payload)["task_id"]
    print("Task:", task_id, flush=True)
    path = "/tasks/" + task_id
    deadline = time.monotonic() + 600
    data = api("GET", path + "?limit=100")
    while data["status"] in PENDING:
        if time.monotonic() >= deadline:
            raise TimeoutError("Resume GET " + path + "; do not resubmit automatically")
        time.sleep(2)
        data = api("GET", path + "?limit=100")
    if data["status"] != "succeeded":
        raise RuntimeError(data.get("error_message") or data["status"])

    items, seen_cursors = [], set()
    while True:
        if time.monotonic() >= deadline:
            raise TimeoutError("Resume pagination for " + task_id)
        page = data["results"]
        items.extend(page["items"])
        if not page["has_more"]:
            return task_id, items
        cursor = page.get("next_cursor")
        if not cursor or cursor in seen_cursors:
            raise RuntimeError("Missing or repeated result cursor")
        seen_cursors.add(cursor)
        data = api("GET", path + "?" + urlencode({"limit": 100, "cursor": cursor}))
        if data["status"] != "succeeded":
            raise RuntimeError("Task is not ready for result pagination")

Save the exporter as export_communities.py in the same directory:

import csv
import json
from socq_collect import collect

urls = ["https://x.com/i/communities/1493446837214187523"]
task_id, items = collect("x/community", {"urls": urls})
with open("communities.json", "w", encoding="utf-8") as f:
    json.dump({"task_id": task_id, "input": {"urls": urls}, "items": items},
              f, ensure_ascii=False, indent=2)

fields = ["community_id", "url", "name", "description", "members_count",
          "moderators_count", "join_policy", "invites_policy", "rules_json", "collected_at"]
def csv_cell(value):
    if value is None:
        return ""
    if isinstance(value, str) and value.lstrip().startswith(("=", "+", "-", "@")):
        return "'" + value
    return value

with open("communities.csv", "w", encoding="utf-8-sig", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=fields)
    writer.writeheader()
    for item in items:
        metrics = item.get("metrics") or {}
        row = {"community_id": item.get("id"), "url": item.get("url"),
               "name": item.get("name"), "description": item.get("text"),
               "members_count": metrics.get("members_count"),
               "moderators_count": metrics.get("moderators_count"),
               "join_policy": item.get("join_policy"),
               "invites_policy": item.get("invites_policy"),
               "rules_json": json.dumps(item.get("rules"), ensure_ascii=False),
               "collected_at": item.get("collected_at")}
        writer.writerow({k: csv_cell(v) for k, v in row.items()})
python3 export_communities.py

The JSON retains the raw standard records and submitted links. The CSV provides one review row per returned community, with the rules serialized as JSON so commas and line breaks do not destroy their structure. rules_json=null remains distinguishable from an empty list. Formula-like public text is escaped only in CSV, and identifiers should be imported as text.

When an input returns no metadata, record the empty result and its query time separately. Keep previously saved metadata under its original collection time for historical comparison.

Connect Community Metadata to Collected Posts

Use the same confirmed community URL with X Community Posts when you need discussions. That starts a separate task and has a separate result cap. The community-posts tutorial shows how to preserve the input-community source while exporting posts.

Save community ID, source URL, task ID and collection time with the metadata. Attach the input community to each collected post so the profile and post tables can be joined by community ID.

Review the description, rules and collected posts together, with their respective capture times. For a post's reply relationships, continue with the thread-context tutorial.

Make Community Metadata a Reusable Research Resource

SocQ organizes community metadata into standard fields. Use the code to save a profile table and structured rules, then join collected posts by community ID. Descriptions, rules and discussions share an explicit source for research files, sample reviews and dated updates.

Open X Community and query your source URL.

FAQ

What does the Twitter Community API return?

Community names, descriptions, rules, member and moderator counts, joining policies and invitation policies. See the X Community API page for field definitions and billing.

How do I query metadata after the community migration announcement?

X published a Communities-to-XChat migration announcement. Use the target community URL for the metadata lookup: read returned records after task success, save the query time for empty results, and inspect error details on failure. Check joining and participation features in X's current interface.

Can I search for a community by name?

The lookup takes community URLs. Confirm the link associated with the name, then submit it in urls.

Does the member count include a list of members or moderators?

The response contains aggregate member and moderator counts. Individual account directories are separate data and are not part of this metadata response.

Does an Open policy mean I can join now?

Open is the joining-policy value returned in the metadata. Verify current joining access in X's interface; this endpoint reads the metadata.

Are community posts or Community Notes included?

Query community posts with X Community Posts. Community Notes are separate post annotations. This endpoint returns community metadata.

Can I use these counts to rank community activity?

Member and moderator totals describe scale. To study activity, collect posts, select a period using published_at in your application, and count posts, authors or interactions within that sample.

X API

Test the workflow with a public X URL

Submit public inputs and receive normalized records with traceable source context.

Explore X APIs