> ## 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 bookmark folders API & saved tweet export

> List Twitter bookmark folders by ID and name. Export each folder's saved tweets with authors, replies, likes, reposts, views, media & cursor checkpoints.

<Panel>
  <Tabs defaultTabIndex={0} sync={false}>
    <Tab title="200" id="response-x-bookmark-folders-200">
      ```json theme={null}
      {
        "folders": [
          {
            "id": "1234567890",
            "media": {
              "originalImageUrl": "https://pbs.twimg.com/media/cover.jpg"
            },
            "name": "Read Later"
          }
        ],
        "has_next_page": false,
        "next_cursor": ""
      }
      ```
    </Tab>

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

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

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

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

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

    <Tab title="503" id="response-x-bookmark-folders-503">
      ```json theme={null}
      {
        "error": "x_api_unavailable",
        "message": "Xquik is busy right now. Retry shortly."
      }
      ```
    </Tab>
  </Tabs>
</Panel>

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

<Info>
  List Twitter bookmark folders for one connected account. Each row contains a
  folder ID and name for a saved tweet export. [X documents bookmark folders as
  private, authenticated-user content.](https://docs.x.com/x-api/posts/bookmarks/introduction)
</Info>

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

The route reads bookmark folders through your connected X account. Without one,
it returns `424 account_required`. Use [Connect X account](/api-reference/x-accounts/connect)
to add one. When your connected X accounts are busy, it returns `503`. Retry
after the `Retry-After` delay.

X shows bookmark folders only to X Premium accounts. For any other account, the
route returns `424 bookmark_folders_unavailable`, & a retry returns the same.
Upgrade that account on X, or read all saved tweets with
[Bookmarks](/api-reference/x/bookmarks) without `folderId`.

Use folder IDs from this response with `GET /x/bookmarks?folderId=...` to read
tweets saved inside a folder.

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

  ```javascript Node.js theme={null}
  const response = await fetch("https://xquik.com/api/v1/x/bookmarks/folders", {
    headers: { "x-api-key": "xq_YOUR_KEY_HERE" },
  });
  const data = await response.json();
  const folderRows = data.folders.map((folder) => ({
    folder_id: folder.id,
    folder_name: folder.name,
    bookmarks_endpoint: `/x/bookmarks?folderId=${encodeURIComponent(folder.id)}`,
    has_more_folders: data.has_next_page,
  }));

  for (const row of folderRows) {
    process.stdout.write(`${JSON.stringify(row)}\n`);
  }
  ```

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

  response = requests.get(
      "https://xquik.com/api/v1/x/bookmarks/folders",
      headers={"x-api-key": "xq_YOUR_KEY_HERE"},
  )
  data = response.json()
  folder_rows = [
      {
          "folder_id": folder["id"],
          "folder_name": folder["name"],
          "bookmarks_endpoint": f"/x/bookmarks?folderId={folder['id']}",
          "has_more_folders": data["has_next_page"],
      }
      for folder in data["folders"]
  ]

  for row in folder_rows:
      print(json.dumps(row))
  ```
</CodeGroup>

The Node.js and Python snippets build bookmark folder rows. They do not
print the full response. Store `folderRows` or `folder_rows`.
Then pass `folder_id` into `GET /x/bookmarks?folderId=...`.

## Direct bookmark folder handoff

Use `GET /x/bookmarks/folders` for an authenticated X account. It serves a
saved-tweet workflow, CRM enrichment job, research queue, or agent.
Store `folder_id` and `folder_name` with the connected account ID.
The route returns one folder page. `has_next_page` stays `false`, and
`next_cursor` stays empty. Use each folder ID with
[Bookmarks](/api-reference/x/bookmarks) to fetch its saved tweets.

## Twitter bookmark folder workflow

### 1. Discover existing folders

Call the route with the connected account's Xquik API key. It lists that
account's private folders. It cannot create, rename, move, or delete folders.
An empty `folders` array means the X Premium account has no folders.

### 2. Build a folder index

Use `folder_id` as the stable join key. Folder names can change or repeat.
Protect folder names like saved tweets. Exclude them from public logs, URLs,
and shared filenames.

### 3. Export saved tweets by folder

Pass each folder ID to `GET /x/bookmarks?folderId=...`. Saved tweet rows can
include text, authors, likes, replies, reposts, views, media, and cursors. Write
the folder ID beside every row to keep folder membership.

### 4. Resume and audit the export

The folder list has no next page. The bookmarked-tweet route paginates per
folder. Store its `next_cursor`, collection time, and connected account ID.

## Export Twitter bookmark folders

Every folder list is a snapshot for one account. Compare folder IDs
with the preceding snapshot. Match renamed folders by ID. A missing ID only
means the current snapshot omitted it. Keep prior exports until verification.

### Store one checkpoint per folder

Store the folder ID, bookmark cursor, completion state, and collection time.
Retry only the incomplete folder after `424`, `429`, or `502` responses.
Upsert rows by account, folder, and tweet IDs. Save every row before advancing
the cursor.

### Define folder export records

Store `account_id`, `folder_id`, and `folder_name` beside each saved tweet.
Keep tweet, author, engagement, media, and timestamp fields. Store
`source_cursor` beside each page. Validate IDs before exporting to a
spreadsheet, CRM, research queue, or storage system.

## Twitter bookmark folder questions

### Do Twitter bookmarks have folders?

Yes, for X Premium accounts. This endpoint lists the named folders visible to
the connected account.

### Can this API create or rename bookmark folders?

No. This route only reads folder IDs and names.

### Can I access folders from mobile and desktop?

Yes. The endpoint works independently of the device. It returns folders
available to the connected account.

### How do I back up Twitter bookmark folders?

Save the folder index as JSON Lines or CSV. Export each folder's saved tweets.
Join both files by `folder_id`. Include the account ID and collection time.

### What errors can stop a folder export?

A `401` response means the key cannot access the connected account. A `402`
response requires more credits. Respect retry guidance in a `429` response.
`424 account_required` means you have no connected X account.
`424 bookmark_folders_unavailable` means the account has no X Premium. Retry
other `424`, `502` & `503` read failures later.

## Query parameters

<ParamField query="cursor" type="string">
  Pass `next_cursor` from the previous page. Omit it for the first page.
</ParamField>

## Headers

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

## Response

### 200 OK

<ResponseField name="folders" type="object[]">
  Array of bookmark folders.
  **Folder object fields.**

  <ResponseField name="id" type="string">
    This value contains the folder ID.
  </ResponseField>

  <ResponseField name="name" type="string">
    This value contains the folder name.
  </ResponseField>

  <ResponseField name="media" type="object">
    Public folder cover image metadata. Omitted if unavailable.
  </ResponseField>
</ResponseField>

<ResponseField name="has_next_page" type="boolean">
  Always `false` for the bookmark folder route.
</ResponseField>

<ResponseField name="next_cursor" type="string">
  Always an empty string for the bookmark folder route.
</ResponseField>

<Note>
  **Related.** [Bookmarks](/api-reference/x/bookmarks) · [Timeline](/api-reference/x/timeline)
</Note>

<div className="related-api-links">
  <Accordion title="Related timeline, bookmark & notification APIs" icon="link">
    * Account feeds: [Home timeline](/api-reference/x/timeline) · [Notifications](/api-reference/x/notifications) · [Mentions](/api-reference/x/user-mentions)
    * Saved and private: [Bookmarks](/api-reference/x/bookmarks) · [Bookmark folders](/api-reference/x/bookmark-folders) · [DM history](/api-reference/x/dm-history)
  </Accordion>
</div>


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