> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xquik.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get community moderators

> Retrieve moderators of an X community with profile details and follower counts

<blockquote className="agent-llms-directive">
  For the complete documentation index, see <a href="/llms.txt">llms.txt</a>.
</blockquote>

<Note>
  Requested result counts are upper bounds for paid authenticated calls. When remaining credits cannot cover the full page or ID list, Xquik returns fewer results. If zero paid results are affordable, it returns `402 insufficient_credits`.
</Note>

<Callout icon="coins" color="#5c3327">
  **1 credit per result returned** · [All plans](https://xquik.com/#pricing) from \$0.00012/credit
</Callout>

<CodeGroup>
  ```bash cURL theme={null}
  curl https://xquik.com/api/v1/x/communities/1234567890/moderators \
    -H "x-api-key: xq_YOUR_KEY_HERE" | jq
  ```

  ```javascript Node.js theme={null}
  const communityId = "1234567890";
  const response = await fetch(`https://xquik.com/api/v1/x/communities/${communityId}/moderators`, {
    headers: { "x-api-key": "xq_YOUR_KEY_HERE" },
  });
  const data = await response.json();
  const nextCursor = data.has_next_page ? data.next_cursor : null;
  const moderatorRows = data.users.map((user) => ({
    community_id: communityId,
    moderator_id: user.id,
    username: user.username,
    display_name: user.name,
    bio: user.description ?? null,
    follower_count: user.followers ?? null,
    verified: user.verified ?? false,
    profile_image_url: user.profilePicture ?? null,
    page_size: data.users.length,
    has_next_page: data.has_next_page,
    next_cursor: nextCursor,
  }));

  process.stdout.write(JSON.stringify(moderatorRows, null, 2));
  ```

  ```python Python theme={null}
  import json
  import requests

  community_id = "1234567890"
  response = requests.get(
      f"https://xquik.com/api/v1/x/communities/{community_id}/moderators",
      headers={"x-api-key": "xq_YOUR_KEY_HERE"},
  )
  data = response.json()
  next_cursor = data["next_cursor"] if data["has_next_page"] else None
  moderator_rows = [
      {
          "community_id": community_id,
          "moderator_id": user["id"],
          "username": user["username"],
          "display_name": user["name"],
          "bio": user.get("description"),
          "follower_count": user.get("followers"),
          "verified": user.get("verified", False),
          "profile_image_url": user.get("profilePicture"),
          "page_size": len(data["users"]),
          "has_next_page": data["has_next_page"],
          "next_cursor": next_cursor,
      }
      for user in data["users"]
  ]

  print(json.dumps(moderator_rows, indent=2))
  ```
</CodeGroup>

Use `GET /x/communities/{id}/moderators` for moderator audits, governance
review, trust and safety queues, or CRM enrichment. It creates one row per
community moderator. Store `community_id`, `moderator_id`, `username`,
`display_name`, `bio`, `follower_count`, `verified`, `profile_image_url`, and
`next_cursor`. Store `page_size` and `has_next_page` with the checkpoint when
you paginate moderator audits or saved review queues.

## Direct moderator handoff

Use the first page with no `cursor`, then pass `next_cursor` back as `cursor`
while `has_next_page` is true. Requested result counts are upper bounds, so use
`page_size` to record how many moderators were returned on the current page.

<CardGroup cols={2}>
  <Card title="Moderator rows" icon="shield-check">
    Store one row per moderator with community ID, user ID, username, profile
    fields, verification, and follower count.
  </Card>

  <Card title="Next page" icon="arrow-right">
    Store `has_next_page` and `next_cursor` before requesting the following
    page.
  </Card>

  <Card title="Default page" icon="rows-3">
    Expect up to the default page size per call, reduced when the caller cannot
    cover every paid result.
  </Card>

  <Card title="Saved export" icon="file-spreadsheet">
    Use `community_moderator_explorer` when the workflow needs an extraction
    job or CSV, JSON, or XLSX output.
  </Card>
</CardGroup>

## Path parameters

<ParamField path="id" type="string" required>
  Community ID (numeric string).
</ParamField>

## Query parameters

<ParamField query="cursor" type="string">
  Pagination cursor from a previous response. Omit for the first page.
</ParamField>

## Which community endpoint?

<CardGroup cols={2}>
  <Card title="Community moderators" icon="shield-check">
    Use `GET /x/communities/{id}/moderators` for governance audits, moderator
    review queues, and profile enrichment.
  </Card>

  <Card title="Community members" icon="users">
    Use [`GET /x/communities/{id}/members`](/api-reference/x/community-members)
    for the broader member list.
  </Card>

  <Card title="Community info" icon="badge-info">
    Use [`GET /x/communities/{id}/info`](/api-reference/x/community-info) for
    member count, moderator count, rules, and join policy.
  </Card>

  <Card title="Community tweets" icon="message-square-text">
    Use [`GET /x/communities/{id}/tweets`](/api-reference/x/community-tweets)
    for posts inside one community.
  </Card>

  <Card title="Community search" icon="search">
    Use [`GET /x/communities/tweets`](/api-reference/x/search-community-tweets)
    for keyword search across community tweets.
  </Card>

  <Card title="Saved exports" icon="file-spreadsheet">
    Use [`Create extraction`](/api-reference/extractions/create) with
    `community_moderator_explorer`, `community_extractor`, or
    `community_post_extractor` for queued file exports.
  </Card>
</CardGroup>

## Headers

<ParamField header="x-api-key" type="string" required>
  Your API key. Session cookie authentication is also supported.
</ParamField>

## Response

<Tabs>
  <Tab title="200 OK">
    <ResponseField name="users" type="object[]">
      Array of community moderators.

      <Expandable title="User object fields">
        <ResponseField name="id" type="string">User ID.</ResponseField>
        <ResponseField name="username" type="string">X username.</ResponseField>
        <ResponseField name="name" type="string">Display name.</ResponseField>
        <ResponseField name="description" type="string">Profile bio.</ResponseField>
        <ResponseField name="followers" type="number">Follower count.</ResponseField>
        <ResponseField name="following" type="number">Following count.</ResponseField>
        <ResponseField name="verified" type="boolean">Verified status.</ResponseField>
        <ResponseField name="profilePicture" type="string">Profile image URL.</ResponseField>
        <ResponseField name="location" type="string">Profile location.</ResponseField>
        <ResponseField name="createdAt" type="string">Account creation date (ISO 8601).</ResponseField>
        <ResponseField name="statusesCount" type="number">Total number of tweets posted. Omitted if unavailable.</ResponseField>
        <ResponseField name="coverPicture" type="string">Cover/banner image URL. Omitted if unavailable.</ResponseField>
        <ResponseField name="mediaCount" type="number">Total number of media tweets posted. Omitted if unavailable.</ResponseField>
        <ResponseField name="canDm" type="boolean">Whether the user accepts direct messages. Omitted if unavailable.</ResponseField>
        <ResponseField name="url" type="string">Website URL from profile. Omitted if empty.</ResponseField>
        <ResponseField name="favouritesCount" type="number">Total number of tweets liked. Omitted if unavailable.</ResponseField>
        <ResponseField name="hasCustomTimelines" type="boolean">Whether the user has custom timelines. Omitted if unavailable.</ResponseField>
        <ResponseField name="isTranslator" type="boolean">Whether the user is an X translator. Omitted if unavailable.</ResponseField>
        <ResponseField name="withheldInCountries" type="string[]">Country codes where the account is withheld. Omitted if empty.</ResponseField>
        <ResponseField name="possiblySensitive" type="boolean">Whether the account is flagged as possibly sensitive. Omitted if unavailable.</ResponseField>
        <ResponseField name="pinnedTweetIds" type="string[]">IDs of pinned tweets. Omitted if none.</ResponseField>
        <ResponseField name="isAutomated" type="boolean">Whether the account is marked as automated. Omitted if unavailable.</ResponseField>
        <ResponseField name="automatedBy" type="string">Username of the account operator if automated. Omitted if not automated.</ResponseField>
        <ResponseField name="unavailable" type="boolean">Whether the account is unavailable. Omitted if available.</ResponseField>
        <ResponseField name="unavailableReason" type="string">Reason the account is unavailable. Omitted if available.</ResponseField>
        <ResponseField name="verifiedType" type="string">Verification type (e.g. `Business`, `Government`). Omitted if not verified or standard blue check.</ResponseField>
        <ResponseField name="profile_bio" type="object">Structured profile bio with entity annotations. Omitted if unavailable.</ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="has_next_page" type="boolean">Whether more results are available.</ResponseField>
    <ResponseField name="next_cursor" type="string">Cursor for the next page. Pass as the `cursor` query parameter.</ResponseField>

    ```json theme={null}
    {
      "users": [
        {
          "id": "987654321",
          "username": "moduser",
          "name": "Moderator",
          "followers": 5000,
          "verified": true
        }
      ],
      "has_next_page": false,
      "next_cursor": ""
    }
    ```
  </Tab>

  <Tab title="400 Invalid community ID">
    ```json theme={null}
    { "error": "invalid_community_id" }
    ```

    The community ID is empty or invalid.
  </Tab>

  <Tab title="401 Unauthenticated">
    ```json theme={null}
    { "error": "unauthenticated" }
    ```

    Missing or invalid API key.
  </Tab>

  <Tab title="402 Subscription required">
    ```json theme={null}
    { "error": "no_subscription" }
    ```

    No active subscription or insufficient credits. Possible error values: `no_subscription`, `subscription_inactive`, `no_credits`, `insufficient_credits`.
    For [MPP](/mpp/overview) requests without a valid payment credential, 402 returns a `WWW-Authenticate: Payment` challenge header instead.
  </Tab>

  <Tab title="404 Community not found">
    ```json theme={null}
    { "error": "not_found" }
    ```

    The community could not be resolved. Check the community ID.
  </Tab>

  <Tab title="502 X API unavailable">
    ```json theme={null}
    { "error": "x_api_unavailable" }
    ```

    The read service returned an error. Retry after a short delay.
  </Tab>

  <Tab title="429 Rate Limit Exceeded">
    ```json theme={null}
    { "error": "rate_limit_exceeded", "retryAfter": 60 }
    ```

    Your tier rate limit was exceeded. Wait for the `Retry-After` header before retrying.
  </Tab>

  <Tab title="424 Dependency Failed">
    ```json theme={null}
    { "error": "x_api_unavailable" }
    ```

    The normalized v1 response contract can return 424 when the read service is unavailable.
  </Tab>
</Tabs>

<Note>
  **Next steps:** [Community Members](/api-reference/x/community-members) for the full member list, or [Community Info](/api-reference/x/community-info) for community details.
</Note>
