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

# Connected X accounts API, health & write readiness

> Page through connected X accounts, inspect login health, and select the correct Xquik connection before Tweets, replies, DMs, likes, follows, or profile writes.

<Panel>
  <Tabs defaultTabIndex={0} sync={false}>
    <Tab title="200" id="response-x-accounts-list-200">
      ```json theme={null}
      {
        "accounts": [
          {
            "id": "42",
            "xUserId": "9876543210",
            "xUsername": "elonmusk",
            "status": "active",
            "health": "healthy"
          }
        ],
        "hasMore": false
      }
      ```
    </Tab>

    <Tab title="400" id="response-x-accounts-list-400">
      ```json theme={null}
      {
        "error": "invalid_input",
        "message": "Invalid account list cursor or limit."
      }
      ```
    </Tab>

    <Tab title="401" id="response-x-accounts-list-401">
      ```json theme={null}
      {
        "error": "unauthenticated",
        "message": "Authentication required. Provide a valid API key or bearer token."
      }
      ```
    </Tab>

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

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

<Callout icon="circle-check" color="#16a34a">
  **Free.** This endpoint does not consume credits.
</Callout>

List X accounts connected to the authenticated Xquik account. Read each local
ID, username, and health before a write.

It does not search public Twitter
accounts. Use [Search Users](/api-reference/x/search-users) for public profiles.

<Info>
  Check `accounts[].health` before every write. Use only a ready connection.
</Info>

## Common uses

| Workflow | Use the response for |
| - | - |
| Before a Tweet, reply, DM, like, or follow | Select `accounts[].id` |
| After connection or reauthentication | Confirm username and health |
| Before scheduled work | Exclude blocked accounts |
| During support | Compare status, health, and timestamps |

## Scope, ordering & pagination

The response contains only connections owned by the authenticated Xquik
account. The API orders accounts by `createdAt` from earliest to latest. The
connection ID breaks ties between equal timestamps.

Send `limit` to enable cursor pagination. The default is 50. The maximum is 100. Pass `nextCursor` unchanged as `cursor` while `hasMore` is true.

The opt-in contract paginates by default. Send this header:

```http theme={null}
xquik-api-contract: 2026-04-29
```

That contract returns `has_more` and `next_cursor`. The examples below show
the default v1 camelCase fields.

Calls without `limit` or `cursor` return up to 10,000 connections.
Existing clients keep working. Larger lists receive cursor fields. Paginate in new
integrations.

An account without connections receives `{"accounts": [], "hasMore": false}`
when pagination is active.

## Request

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://xquik.com/api/v1/x/accounts?limit=50" \
    -H "x-api-key: xq_YOUR_KEY_HERE"
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://xquik.com/api/v1/x/accounts?limit=50", {
    headers: { "x-api-key": "xq_YOUR_KEY_HERE" },
  });
  if (!response.ok) throw new Error(`List failed: ${response.status}`);
  const page = await response.json();
  ```
</CodeGroup>

## Headers

<ParamField header="x-api-key" type="string">
  Xquik API key. Generate one from the [dashboard](https://xquik.com/dashboard).
</ParamField>

<ParamField header="Authorization" type="string">
  OAuth bearer token using `Bearer YOUR_TOKEN`.
</ParamField>

## Query parameters

<ParamField query="limit" type="integer" default="50">
  Page size from 1 through 100. The API caps larger values at 100.
</ParamField>

<ParamField query="cursor" type="string">
  Opaque `nextCursor` from the previous page. Do not decode or change it.
</ParamField>

## Read every page

```javascript theme={null}
let cursor;

do {
  const query = new URLSearchParams({ limit: "100" });
  if (cursor) query.set("cursor", cursor);

  const response = await fetch(`https://xquik.com/api/v1/x/accounts?${query}`, {
    headers: { "x-api-key": "xq_YOUR_KEY_HERE" },
  });
  if (!response.ok) throw new Error(`List failed: ${response.status}`);

  const page = await response.json();
  for (const account of page.accounts) {
    console.log(account.id, account.xUsername, account.health);
  }
  cursor = page.hasMore ? page.nextCursor : undefined;
} while (cursor);
```

## Response

<ResponseField name="accounts" type="object[]" required>
  Connected X accounts. Empty when no connection exists.
</ResponseField>

<ResponseField name="hasMore" type="boolean">
  `true` when another cursor page exists. Present on paginated responses.
</ResponseField>

<ResponseField name="nextCursor" type="string">
  Opaque cursor for the next page. Present only when another page exists.
</ResponseField>

<ResponseField name="accounts[].id" type="string" required>
  Xquik connection ID. Use it as `accountId` for write endpoints.
</ResponseField>

<ResponseField name="accounts[].xUsername" type="string" required>
  Connected X username without `@`.
</ResponseField>

<ResponseField name="accounts[].xUserId" type="string" required>
  Stable X user ID. This is not the Xquik connection ID.
</ResponseField>

<ResponseField name="accounts[].status" type="string" required>
  Stored connection status. Read `health` before writes.
</ResponseField>

<ResponseField name="accounts[].health" type="string" required>
  Current write readiness. See [Account health](#account-health).
</ResponseField>

<ResponseField name="accounts[].connectedAt" type="string">
  ISO 8601 time when the account last connected or reconnected. Omitted before login.
</ResponseField>

<ResponseField name="accounts[].createdAt" type="string" required>
  ISO 8601 connection creation time.
</ResponseField>

<ResponseField name="accounts[].updatedAt" type="string" required>
  ISO 8601 time when the connection last changed.
</ResponseField>

```json theme={null}
{
  "accounts": [
    {
      "id": "3",
      "xUsername": "example",
      "xUserId": "44196397",
      "status": "active",
      "health": "healthy",
      "connectedAt": "2026-02-20T08:15:00.000Z",
      "createdAt": "2026-02-20T08:15:00.000Z",
      "updatedAt": "2026-02-20T08:15:00.000Z"
    }
  ],
  "hasMore": true,
  "nextCursor": "MjAyNi0wMi0yMFQwODoxNTowMC4wMDBafDM="
}
```

## Choose the correct identifier

| Field | Scope | Use |
| - | - | - |
| `id` | Xquik connection | Pass as `accountId` to write endpoints |
| `xUserId` | X account | Correlate public read responses |
| `xUsername` | Public handle | Confirm the account the operator meant |

Do not send `xUserId` where a write endpoint requires `accountId`.

## Account health

The `status` field alone is not enough. Check `health` before every write.

| Health | Write readiness | Next action |
| - | - | - |
| `healthy` | Ready | Continue with the intended write |
| `recovering` | Retry on use | Let the next action reconnect |
| `temporaryIssue` | Wait | Respect the cooldown |
| `needsReauth` | Blocked | Reauthenticate with current credentials |
| `locked` | Blocked | Complete recovery on X, then reauthenticate |
| `suspended` | Blocked | Resolve the suspension on X |

**Recovery details.** `needsReauth` covers credentials, TOTP, email
verification, passkeys, and other security challenges. Use
[reauth](/api-reference/x-accounts/reauth) after resolving X-side prompts.
`locked` can require account-side verification. `suspended` stays blocked
until X restores the account. `recovering` reconnects on the next use.
`temporaryIssue` stays paused during a transient cooldown.

Use [Bulk Retry](/api-reference/x-accounts/bulk-retry) only for eligible temporary
failures. It cannot fix credentials, locks, or suspensions.

## Errors

### 400 Invalid input

The cursor or limit is invalid. Restart without a cursor or send a valid limit.

### 401 Unauthenticated

Send a valid Xquik API key or OAuth bearer token.

### 429 Rate limited

Wait for `Retry-After`, then request the same page again.

<Note>
  **Next steps.** [Connect X Account](/api-reference/x-accounts/connect),
  [Re-authenticate X Account](/api-reference/x-accounts/reauth), or
  [Bulk Retry](/api-reference/x-accounts/bulk-retry).
</Note>


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