> ## 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.

# Twitter list members API & CSV profile export guide

> Retrieve Twitter List members with usernames, bios, verification, profile images, and follower counts. Export pages as CSV, JSON, or XLSX for roster analysis.

<Panel>
  <Tabs defaultTabIndex={0} sync={false}>
    <Tab title="200" id="response-x-list-members-200">
      ```json theme={null}
      {
        "users": [],
        "has_next_page": false,
        "next_cursor": ""
      }
      ```
    </Tab>

    <Tab title="400" id="response-x-list-members-400">
      ```json theme={null}
      {
        "error": "invalid_input",
        "message": "Invalid input. Check the request body."
      }
      ```
    </Tab>

    <Tab title="401" id="response-x-list-members-401">
      ```json theme={null}
      {
        "error": "unauthenticated",
        "message": "Authentication required."
      }
      ```
    </Tab>

    <Tab title="402" id="response-x-list-members-402">
      ```json theme={null}
      {
        "error": "insufficient_credits",
        "message": "Insufficient credits. Top up or subscribe to continue."
      }
      ```
    </Tab>

    <Tab title="404" id="response-x-list-members-404">
      ```json theme={null}
      {
        "error": "not_found",
        "message": "Resource not found."
      }
      ```
    </Tab>

    <Tab title="409" id="response-x-list-members-409">
      ```json theme={null}
      {
        "error": "coverage_cursor_unavailable",
        "message": "Cursor busy. Retry after the indicated delay."
      }
      ```
    </Tab>

    <Tab title="410" id="response-x-list-members-410">
      ```json theme={null}
      {
        "error": "coverage_cursor_gone",
        "message": "Cursor finished, expired, or superseded. Restart pagination without cursor."
      }
      ```
    </Tab>

    <Tab title="424" id="response-x-list-members-424">
      ```json theme={null}
      {
        "error": "x_api_unavailable",
        "message": "X data source temporarily unavailable. Try again later."
      }
      ```
    </Tab>

    <Tab title="429" id="response-x-list-members-429">
      ```json theme={null}
      {
        "error": "rate_limit_exceeded",
        "message": "Too many requests. Try again later.",
        "retryAfter": 60
      }
      ```
    </Tab>

    <Tab title="502" id="response-x-list-members-502">
      ```json theme={null}
      {
        "error": "x_api_unavailable",
        "message": "X data source temporarily unavailable. Try again later."
      }
      ```
    </Tab>

    <Tab title="503" id="response-x-list-members-503">
      ```json theme={null}
      {
        "error": "x_api_unavailable",
        "message": "Maximum coverage is busy. Retry shortly."
      }
      ```
    </Tab>
  </Tabs>
</Panel>

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

This route reads one X List. It returns the profiles the List owner added.
Keep user IDs, usernames, bios, verification, profile images, and public counts.

<Info>
  Omit `mode` for automatic maximum coverage. Xquik combines available views
  within a short request window. It keeps the existing response shape.
  Pass `next_cursor` back unchanged as `cursor`. Keep the same endpoint, target,
  query, and filters.
</Info>

Existing unprefixed cursors keep their legacy behavior. `after`, `limit`, and
`pageSize` aliases also keep working. Billing still counts only returned rows.
Use `mode=standard` only to force legacy single-view pagination.

A page can be empty or underfilled. Continue while `has_next_page` is `true`.
Stop only after the response reports `has_next_page=false`.

First-page requests do not support `Idempotency-Key` retries.
Repeating a cursorless request starts a separate extraction.
Results returned by that extraction incur their normal charges.
Save each response before requesting its next page.
You cannot replay earlier or terminal responses after their cursors become unavailable.

If automatic coverage is busy, an initial request returns a standard data page.
Live coverage cursors remain atomic. Concurrent use returns
`409 coverage_cursor_unavailable` with exact `Retry-After` seconds. Wait, then
retry the same cursor once.
Repeated busy responses never authorize restarting with another cursor.

Finished, expired, superseded, or identity-mismatched cursors return
`410 coverage_cursor_gone`. The response omits `Retry-After`. Restart without
a cursor. Keep received results. Deduplicate restarted results by `id`.
Malformed cursors return `400 invalid_coverage_cursor`. Restart without them.

## Twitter list members questions

### What is a Twitter list member?

A List member is an account selected by the List owner. Membership creates the
List's curated timeline. It does not mean the account follows that List. An
account follower follows one profile instead. X explains these roles in its
official [Lists guide](https://help.x.com/en/using-x/x-lists).

### How do I view members of a Twitter list?

Copy the numeric List ID from its X URL. Request the first page without a
cursor. Store every returned profile before requesting another page. Continue
only when `has_next_page` is true. Pass `next_cursor` unchanged as `cursor`.
X also documents a [Get List members](https://docs.x.com/x-api/lists/get-list-members)
route. Its response and pagination fields differ from Xquik's fields.

### How do I export Twitter list members?

The direct endpoint returns JSON pages. Convert each profile into one export
row. Store the List ID, member ID, username, bio, counts, and collection time.
Follow every cursor before treating the export as complete. Use
`list_member_extractor` for a saved job. It can produce CSV, JSON, or XLSX
files without custom spreadsheet code.

### Which profile fields can I analyze?

Analyze user IDs, usernames, display names, bios, and public location text.
Compare follower counts, following counts, verification, and account dates.
Use public counts to sort a roster for manual review. Do not call a high count
"influence" without a clear method. This endpoint does not calculate reach,
engagement, demographics, sentiment, or audience quality.

### How do I compare list member snapshots?

Finish both snapshots before comparing their member IDs. Added IDs indicate
newly observed members. Missing IDs indicate newly unobserved members. Record
both snapshot times and completion states. A renamed username is not a new
member. Never report removals from an incomplete later snapshot.

### Can I export members from a private Twitter list?

Access depends on the credentials and visibility available to the read
service. Never assume a private List is readable. A `404` means the List is unavailable
or the List ID is wrong. Do not promise access to private Lists. Public
profile fields also do not grant outreach consent.

### Can this endpoint add or remove list members?

No. This GET endpoint only reads the current roster. It cannot create Lists,
add members, remove members, follow Lists, or publish tweets. Use X's supported
write tools for owner-authorized changes. Xquik does not expose those actions
through this endpoint.

### How do I find active members or recent tweets?

This response describes profiles, not recent activity. Retrieve
[List Tweets](/api-reference/x/list-tweets) for posts from the current List
timeline. Analyze tweets separately from List membership. A profile count does
not prove recent activity. One active account can publish many
posts while remaining one List member.

<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/lists/1234567890/members" \
    -H "x-api-key: xq_your_api_key_here" | jq
  ```

  ```javascript Node.js theme={null}
  const listId = "1234567890";
  const response = await fetch(`https://xquik.com/api/v1/x/lists/${listId}/members`, {
    headers: { "x-api-key": "xq_your_api_key_here" },
  });
  const data = await response.json();
  const memberRows = data.users.map((user) => ({
    list_id: listId,
    member_id: user.id,
    username: user.username,
    display_name: user.name,
    bio: user.description ?? null,
    follower_count: user.followers ?? null,
    following_count: user.following ?? null,
    verified: user.verified ?? false,
    profile_image_url: user.profilePicture ?? null,
  }));
  const nextCursor = data.has_next_page ? data.next_cursor : null;
  ```

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

  list_id = "1234567890"
  response = requests.get(
      f"https://xquik.com/api/v1/x/lists/{list_id}/members",
      headers={"x-api-key": "xq_your_api_key_here"},
  )
  data = response.json()
  member_rows = [
      {
          "list_id": list_id,
          "member_id": user["id"],
          "username": user["username"],
          "display_name": user["name"],
          "bio": user.get("description"),
          "follower_count": user.get("followers"),
          "following_count": user.get("following"),
          "verified": user.get("verified", False),
          "profile_image_url": user.get("profilePicture"),
      }
      for user in data["users"]
  ]
  next_cursor = data["next_cursor"] if data["has_next_page"] else None
  ```
</CodeGroup>

## Direct list member handoff

`GET /x/lists/{id}/members` examples create one row per List member. Send saved
rows to a CRM, warehouse, audience tool, or agent. Use
[`list_member_extractor`](/api-reference/extractions/create) for a saved job.
That job supports CSV, JSON, or XLSX file export.

Store `list_id`, `member_id`, `username`, and `display_name`. Keep profile
counts, verification, `has_next_page`, and `next_cursor`.

<CardGroup cols={2}>
  <Card title="Member roster" icon="users">
    Page accounts the list owner curated as members. Use the row shape above for
    CRM, warehouse, and audience imports.
  </Card>

  <Card title="Next page" icon="arrow-right">
    Store `has_next_page` and `next_cursor`. Only request another page when
    `has_next_page` is true.
  </Card>

  <Card title="Page size" icon="rows-3">
    Automatic pages accept `1-300`. Standard accepts `1-200`. The returned
    `users.length` is the row count for the page.
  </Card>

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

## Export a curated list roster

Use List members for profiles selected by one List owner. Keep the List ID on
every row. Also keep the collection time and snapshot status.

Useful list-member columns include:

* User ID, username, and profile name.
* Biography, location, and verification state.
* Follower and following counts.
* List ID and collection timestamp.

Compare snapshots by user ID. Profile owners can rename their usernames. List
membership reflects curation, not audience interest. Use List followers for
profiles that follow the List. Use account followers for one profile's
audience. For CRM imports, deduplicate by List ID and user ID. The same
profile can then appear under several Lists.

## Track list curation changes

Create complete snapshots at consistent intervals. Mark added user IDs as
newly observed members. Mark missing IDs only after a complete later snapshot.

Keep the list name and owner in your snapshot metadata. The endpoint path uses
the list ID. Reviewers often recognize the readable name.

Use snapshot differences to review curation decisions. Do not call them
follower growth. The List owner controls membership.

Create one change row for each added or removed user ID. Include the earlier
and later snapshot times. Keep the current username only as a display label.

Send uncertain comparisons to review. Never publish incomplete comparisons.

## Path parameters

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

## Query parameters

<ParamField query="cursor" type="string">
  Pass `next_cursor` back unchanged. Xquik cursors resume automatic coverage.
  Existing unprefixed cursors keep legacy behavior.
</ParamField>

<ParamField query="mode" type="string">
  Omit `mode` for automatic maximum coverage. Use `standard` for legacy
  pagination. Use `coverage` for one diagnostic response without cursors.
</ParamField>

<ParamField query="after" type="string">
  Legacy cursor alias for `cursor`. When both are present, `cursor` wins.
</ParamField>

<ParamField query="pageSize" type="number">
  Automatic pages accept `1-300`. Standard pages accept `1-200`. Default: `200`.
</ParamField>

## Which list endpoint?

<CardGroup cols={2}>
  <Card title="List members" icon="users">
    Use `GET /x/lists/{id}/members` for accounts the list owner added to the
    list.
  </Card>

  <Card title="List followers" icon="user-plus">
    Use [`GET /x/lists/{id}/followers`](/api-reference/x/list-followers) for
    accounts that follow the list.
  </Card>

  <Card title="List tweets" icon="message-square-text">
    Use [`GET /x/lists/{id}/tweets`](/api-reference/x/list-tweets) for tweets
    from accounts in the list.
  </Card>

  <Card title="Bulk list jobs" icon="file-spreadsheet">
    Use [`Create extraction`](/api-reference/extractions/create) with
    `list_member_extractor`, `list_follower_explorer`, or `list_post_extractor`
    when the workflow needs a saved export.
  </Card>
</CardGroup>

### User result filters

These filters apply before billing. Selective filters can return fewer rows.

<ParamField query="minFollowers" type="integer">
  Require this minimum follower count. Filtering happens before billing.
</ParamField>

<ParamField query="maxFollowers" type="integer">
  Allow this maximum follower count. Missing counts pass this filter.
</ParamField>

<ParamField query="minFollowing" type="integer">
  Require this minimum following count.
</ParamField>

<ParamField query="maxFollowing" type="integer">
  Allow this maximum following count. Missing counts pass this filter.
</ParamField>

<ParamField query="minStatuses" type="integer">
  Require this minimum post count.
</ParamField>

<ParamField query="maxStatuses" type="integer">
  Allow this maximum post count. Missing counts pass this filter.
</ParamField>

<ParamField query="minAccountAgeDays" type="integer">
  Require this minimum account age in days.
</ParamField>

<ParamField query="verifiedOnly" type="boolean">
  When `true`, only return verified profiles.
</ParamField>

<ParamField query="verifiedType" type="string">
  Match the exact verification type.
</ParamField>

<ParamField query="hasWebsite" type="boolean">
  When `true`, require a profile website.
</ParamField>

<ParamField query="hasLocation" type="boolean">
  When `true`, require a profile location.
</ParamField>

<ParamField query="bioContains" type="string">
  Require every comma-separated or line-separated bio term.
</ParamField>

<ParamField query="locationContains" type="string">
  Require this text in the profile location.
</ParamField>

<ParamField query="usernameContains" type="string">
  Require this text in the username.
</ParamField>

## Headers

<ParamField header="x-api-key" type="string">
  Full account key. Sessions and OAuth also work.
</ParamField>

<ParamField header="Authorization" type="string">
  `Bearer xq_your_guest_key_here` for `paid_reads`.
</ParamField>

## Response

### 200 OK

<ResponseField name="users" type="object[]">
  Array of list members.
  **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">
    Contains the profile bio.
  </ResponseField>

  <ResponseField name="followers" type="number">
    Shows how many accounts follow this profile.
  </ResponseField>

  <ResponseField name="following" type="number">
    Shows how many accounts this profile follows.
  </ResponseField>

  <ResponseField name="verified" type="boolean">
    Shows if X marks this profile as verified.
  </ResponseField>

  <ResponseField name="profilePicture" type="string">
    Links to the profile image.
  </ResponseField>

  <ResponseField name="location" type="string">
    Shows the location written on the profile.
  </ResponseField>

  <ResponseField name="createdAt" type="string">
    Shows when the account began, in ISO 8601 format.
  </ResponseField>

  <ResponseField name="statusesCount" type="number">
    Shows the post count if X returns it.
  </ResponseField>

  <ResponseField name="coverPicture" type="string">
    Links to the cover image if X returns it.
  </ResponseField>

  <ResponseField name="mediaCount" type="number">
    Shows the media post count if X returns it.
  </ResponseField>

  <ResponseField name="url" type="string">
    Website URL from profile. Omitted if empty.
  </ResponseField>

  <ResponseField name="favouritesCount" type="number">
    Shows how many posts this account liked if X returns it.
  </ResponseField>

  <ResponseField name="hasCustomTimelines" type="boolean">
    Shows custom timelines if X returns this field.
  </ResponseField>

  <ResponseField name="isTranslator" type="boolean">
    Shows X translator status if X returns it.
  </ResponseField>

  <ResponseField name="withheldInCountries" type="string[]">
    Lists country codes where X withholds this account. Omitted if empty.
  </ResponseField>

  <ResponseField name="possiblySensitive" type="boolean">
    Shows if X marks the account as sensitive. Omitted if X does not send it.
  </ResponseField>

  <ResponseField name="pinnedTweetIds" type="string[]">
    Lists pinned Tweet IDs. Omitted if none.
  </ResponseField>

  <ResponseField name="isAutomated" type="boolean">
    Shows if X marks this account as automated. Omitted if X does not send it.
  </ResponseField>

  <ResponseField name="automatedBy" type="string">
    Names the operator. Omitted when the account is not automated.
  </ResponseField>

  <ResponseField name="unavailable" type="boolean">
    Shows if X could not load the account. Omitted when X loads it.
  </ResponseField>

  <ResponseField name="unavailableReason" type="string">
    Explains why X could not load the account. Omitted when X loads it.
  </ResponseField>

  <ResponseField name="verifiedType" type="string">
    Shows Business or Government status. Omitted for blue checks or unverified profiles.
  </ResponseField>

  <ResponseField name="profile_bio" type="object">
    Adds the structured bio and its tags. Omitted if X does not send it.
  </ResponseField>

  <ResponseField name="isBlueVerified" type="boolean">
    Shows if X Premium verifies the account. Omitted if X does not send it.
  </ResponseField>

  <ResponseField name="isVerified" type="boolean">
    Shows the normalized verified state. Omitted if X does not send it.
  </ResponseField>

  <ResponseField name="profileBannerUrl" type="string">
    Links to the profile banner. Omitted if X does not send it.
  </ResponseField>

  <ResponseField name="protected" type="boolean">
    Shows if the account protects its posts. Omitted if X does not send it.
  </ResponseField>

  <ResponseField name="communityRole" type="string">
    Shows a community role only in community results.
  </ResponseField>
</ResponseField>

<ResponseField name="has_next_page" type="boolean">Shows if another page exists.</ResponseField>
<ResponseField name="next_cursor" type="string">Gives the next cursor. Pass it as the `cursor` query value.</ResponseField>

```json theme={null}
{
  "users": [
    {
      "id": "987654321",
      "username": "username",
      "name": "Xquik",
      "followers": 10000,
      "verified": true,
      "profilePicture": "https://pbs.twimg.com/profile_images/xquik/photo.jpg"
    }
  ],
  "has_next_page": true,
  "next_cursor": "DAACCgACGE..."
}
```

### 400 Invalid list ID

```json theme={null}
{ "error": "invalid_list_id", "message": "List ID required" }
```

The list ID path parameter is empty.

### 401 Unauthenticated

Anonymous requests get `WWW-Authenticate: Bearer` and a guest wallet checkout action. This is not a Payment challenge.

```json theme={null}
{ "error": "unauthenticated" }
```

Missing or invalid API key.

### 402 Payment required

Account keys get account options. Guest keys get guest top-up only.
No checkout starts automatically. Confirm any payment action.

### 404 List not found

```json theme={null}
{ "error": "not_found" }
```

Xquik could not resolve the list. Check the list ID.

### 502 X API unavailable

```json theme={null}
{ "error": "x_api_unavailable" }
```

The read service returned an error. Retry after a short delay.

### 429 Rate limit exceeded

```json theme={null}
{ "error": "rate_limit_exceeded", "retryAfter": 60 }
```

You exceeded your tier's rate limit. Wait for the `Retry-After` header.

### 424 Dependency failed

```json theme={null}
{ "error": "x_api_unavailable" }
```

The v1 response can return 424 when the read service fails.

<Note>
  **Related.** [List Followers](/api-reference/x/list-followers) · [List Tweets](/api-reference/x/list-tweets)
</Note>

<div className="related-api-links">
  <Accordion title="Related follower, list & community APIs" icon="link">
    * Profiles: [Search users](/api-reference/x/search-users) · [Search autocomplete](/api-reference/x/search-autocomplete) · [Get user](/api-reference/x/twitter-profile-lookup) · [Batch users](/api-reference/x/batch-users)
    * Followers: [Followers](/api-reference/x/followers) · [Following](/api-reference/x/following) · [Follower IDs](/api-reference/x/follower-ids) · [Following IDs](/api-reference/x/following-ids) · [Creator subscriptions](/api-reference/x/user-subscriptions) · [Affiliates](/api-reference/x/user-affiliates) · [Similar accounts](/api-reference/x/user-similar) · [Verified followers](/api-reference/x/verified-followers) · [Followers you know](/api-reference/x/followers-you-know) · [Check follower](/api-reference/x/check-follower)
    * Lists: [Search lists](/api-reference/x/search-lists) · [User lists](/api-reference/x/user-lists) · [List memberships](/api-reference/x/user-list-memberships) · [List members](/api-reference/x/list-members) · [List followers](/api-reference/x/list-followers)
    * Communities: [Find](/api-reference/x/community-find) · [Popular](/api-reference/x/community-popular) · [Topics](/api-reference/x/community-topics) · [Suggested](/api-reference/x/community-suggested) · [Details](/api-reference/x/community-info) · [Members](/api-reference/x/community-members) · [Moderators](/api-reference/x/community-moderators) · [Timeline](/api-reference/x/community-tweets) · [Media](/api-reference/x/community-media) · [Keyword search](/api-reference/x/community-search)
  </Accordion>
</div>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.