How to Sort Your Twitter Bookmarks Using AI and Browser Console Scripts

AIJavaScriptAutomation

If you have been bookmarking tweets for years like I have, then your bookmarks are probably a mix of gems, insightful threads, useful tutorials, funny moments, outdated news, and tweets you saved “for later” and never looked at again.

Twitter lets you bookmark tweets, but it offers almost no tools to organize them. You can create Bookmark Collections (folders), but moving tweets into them is a one-by-one manual process. With over 1,000 bookmarks, that is hours of clicking, and nobody has time for that.

In this article, you’ll learn how to use AI to categorize your bookmarks, identify the junk, and then use browser console scripts to bulk-remove the garbage and sort the rest into topic folders. All of this in about 30 minutes.

Table of Contents

What You’ll Need

Before we start, here is everything you need for this tutorial:

  • Google Chrome (or any Chromium browser with DevTools)
  • A Twitter bookmark export tool — costs around $1 one-time (the one I used exports JSON)
  • An AI tool — ChatGPT, Claude, Gemini, or any LLM that can read JSON
  • Basic comfort with Chrome DevTools — pressing F12 and clicking tabs
  • About 30 minutes of your time

Step 1: Export Your Bookmarks

First, we need to get your bookmarks out of Twitter.

  1. Search for “Twitter Bookmark Export” in your browser — several tools exist as Chrome extensions or web apps
  2. Install/open the tool
  3. Click Export and choose the JSON format
  4. Pay the small fee (around $1 for lifetime access to full exports)
  5. Download the ZIP file and extract it

You will end up with a JSON file containing every bookmark, along with fields like:

  • full_text — the tweet content
  • screen_name — the author’s username
  • tweeted_at — when the tweet was posted
  • tweet_url — direct link to the tweet
  • extended_media — images/videos if any

Here is what an example entry looks like:

{
  "screen_name": "elonmusk",
  "full_text": "AI will transform everything...",
  "tweeted_at": "2026-03-15T10:30:00.000Z",
  "tweet_url": "https://x.com/elonmusk/status/1234567890"
}

Step 2: Analyze Your Bookmarks with AI

Now we hand the heavy lifting over to AI. Upload your JSON file to your AI tool of choice and use a prompt like this:

Analyze my Twitter bookmarks JSON file. For each bookmark, classify it into one of these topics: AI/Tech, Finance/Crypto, Nigeria/Africa, Design/Creative, Career/Business, Sports, Health/Fitness, Politics/News, Comedy/Memes, or Other (unclassified).

Then tell me:

  1. How many bookmarks in each category
  2. Which ones look like spam or accidental bookmarks
  3. Which ones are your own tweets (self-bookmarks)

Output a JSON file mapping each tweet ID to its category, and flag ones to delete.

Feel free to tweak the categories to match your interests. When the AI is done, it will return:

  • A topic breakdown (e.g., “AI/Tech: 175, Finance: 169, Nigeria: 114...”)
  • A list of tweet IDs to keep, organized by topic
  • A list of tweet IDs to delete (spam, unclassified junk)

Save both lists somewhere handy, you will need them for the next steps.

Step 3: Capture Twitter’s Internal API Mutations

This is the key technical step, so pay attention here. Twitter’s internal API uses GraphQL mutations that change over time, which means we need to capture the current mutation IDs from your browser.

To capture a mutation:

  1. Open twitter.com in Chrome
  2. Press F12 and click the Network tab
  3. In the filter box, type graphql
  4. Perform the action manually (e.g., unbookmark one tweet)
  5. Find the new request that appeared in the Network tab
  6. Click it and look at the URL and Payload tabs

While you are here, also open any of these GraphQL requests, expand Request Headers, and copy the string that comes after Bearer in the Authorization header. This is Twitter’s public web client token that the website itself uses, and you will need to paste it into the scripts later. Do not share it anywhere public.

You need three mutations:

Mutation 1: DeleteBookmark (for removing bookmarks)

Action: Manually unbookmark one tweet (click the bookmark icon on a bookmarked tweet)

In the Network tab, find the request containing DeleteBookmark, then copy from the URL:

https://x.com/i/api/graphql/YOUR_QUERY_ID_HERE/DeleteBookmark

And copy from the Payload tab:

{
  "variables": {"tweet_id": "1234567890"},
  "queryId": "YOUR_QUERY_ID_HERE"
}

Mutation 2: createBookmarkFolder (for creating collections)

Action: Create a new Bookmark Collection (click the + button in bookmarks sidebar)

Find the createBookmarkFolder request, then copy:

queryId: YOUR_QUERY_ID
Payload: {variables: {name: "Test"}, queryId: "YOUR_QUERY_ID"}

Mutation 3: bookmarkTweetToFolder (for adding tweets to collections)

Action: Save a tweet to a collection (click ... on a tweet → Save to collection → pick one)

Find the bookmarkTweetToFolder request, then copy:

queryId: YOUR_QUERY_ID
Payload: {variables: {bookmark_collection_id: "COLLECTION_ID", tweet_id: "TWEET_ID"}, queryId: "YOUR_QUERY_ID"}

One important thing to note: these mutation IDs change whenever Twitter updates their app. If your scripts start failing with 404 errors, just re-capture the mutations using the steps above.

Step 4: Bulk Unbookmark the Junk

Now it is time to remove the junk tweets. Here is the complete script — paste it into Chrome DevTools Console while on twitter.com:

// === TWITTER BULK UNBOOKMARK SCRIPT ===
// Replace the array below with your "delete" tweet IDs from Step 2

const TWEET_IDS_TO_UNBOOKMARK = [
  "1234567890",
  "2345678901",
  // ... paste all IDs to delete
];

const DELAY_MS = 1500; // 1.5 seconds between requests
const sleep = ms => new Promise(r => setTimeout(r, ms));

async function getCSRFToken() {
    const cookie = document.cookie.split(';')
        .find(c => c.trim().startsWith('ct0='));
    return cookie ? cookie.split('=')[1] : null;
}

async function unbookmarkTweet(tweetId) {
    const ct0 = await getCSRFToken();
    if (!ct0) {
        console.error('Not logged in?');
        return false;
    }

    // Update these two values from Step 3
    const url = 'https://x.com/i/api/graphql/YOUR_MUTATION_ID/DeleteBookmark';

    try {
        const response = await fetch(url, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-Csrf-Token': ct0,
                'Authorization': 'Bearer YOUR_BEARER_TOKEN'
            },
            body: JSON.stringify({
                variables: { tweet_id: tweetId },
                queryId: 'YOUR_QUERY_ID_HERE' // Update this too
            })
        });
        return response.ok;
    } catch (e) {
        console.error(`Error: ${e.message}`);
        return false;
    }
}

async function main() {
    console.log(`Removing ${TWEET_IDS_TO_UNBOOKMARK.length} bookmarks...`);
    let success = 0, failed = 0;

    for (let i = 0; i < TWEET_IDS_TO_UNBOOKMARK.length; i++) {
        const id = TWEET_IDS_TO_UNBOOKMARK[i];
        const result = await unbookmarkTweet(id);

        if (result) {
            success++;
            console.log(`[${i+1}] ✓ ${id}`);
        } else {
            failed++;
            console.log(`[${i+1}] ✗ ${id}`);
        }

        if (i < TWEET_IDS_TO_UNBOOKMARK.length - 1) {
            await sleep(DELAY_MS);
        }
    }

    console.log(`Done! Removed: ${success}, Failed: ${failed}`);
}

main();

Before running it, make sure you have replaced:

  • YOUR_BEARER_TOKEN — the token you copied from the Authorization header in Step 3
  • YOUR_MUTATION_ID_HERE — from the DeleteBookmark URL
  • YOUR_QUERY_ID_HERE — from the DeleteBookmark payload
  • The tweet IDs array — from your AI analysis

Here is how the script works:

  • It reads your CSRF token from cookies (required for authenticated requests)
  • It sends a DELETE request for each tweet at 1.5-second intervals
  • It logs progress as it goes
  • Typical speed is around 40 tweets per minute

Step 5: Create Your Topic Collections

Next, create all your topic collections. You can do this manually (click + in the bookmarks sidebar) or use the API.

The manual approach is simpler:

  1. In the bookmarks sidebar, click the + button
  2. Create collections: AI/Tech, Finance, Nigeria, Design, Career, Comedy, Health, Politics, Sports
  3. Note the collection ID from each URL: twitter.com/i/bookmarks/collections/COLLECTION_ID

If you prefer the automated route, use this script instead:

async function createCollection(name) {
    const ct0 = document.cookie.split(';')
        .find(c => c.trim().startsWith('ct0=')).split('=')[1];

    // Update mutation ID from Step 3
    const url = 'https://x.com/i/api/graphql/YOUR_MUTATION_ID/createBookmarkFolder';

    const response = await fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-Csrf-Token': ct0,
            'Authorization': 'Bearer YOUR_BEARER_TOKEN'
        },
        body: JSON.stringify({
            variables: { name },
            queryId: 'YOUR_QUERY_ID_HERE'
        })
    });

    return response.ok;
}

// Create all collections
const collections = ['AI/Tech', 'Finance', 'Nigeria', 'Design', 
                     'Career', 'Comedy', 'Health', 'Politics', 'Sports'];

for (const name of collections) {
    await createCollection(name);
    console.log(`Created: ${name}`);
    await new Promise(r => setTimeout(r, 1500));
}

Remember to swap in your own mutation ID, query ID, and bearer token before running it.

Step 6: Sort the Remaining Bookmarks

Now for the main event — sorting your kept tweets into the right folders.

// === TWITTER BOOKMARK SORTER ===
// Map each collection to its ID and the tweet IDs to add

const COLLECTIONS = {
    'AI/Tech': {
        id: 'COLLECTION_ID_FROM_URL',
        tweets: ['tweet_id_1', 'tweet_id_2', /* ... */]
    },
    'Finance': {
        id: 'COLLECTION_ID_FROM_URL',
        tweets: ['tweet_id_3', 'tweet_id_4', /* ... */]
    },
    // ... add all collections
};

const DELAY_MS = 1500;
const sleep = ms => new Promise(r => setTimeout(r, ms));

async function getHeaders() {
    const ct0 = document.cookie.split(';')
        .find(c => c.trim().startsWith('ct0=')).split('=')[1];
    return {
        'Content-Type': 'application/json',
        'X-Csrf-Token': ct0,
        'Authorization': 'Bearer YOUR_BEARER_TOKEN'
    };
}

async function addToCollection(collectionId, tweetId) {
    const headers = await getHeaders();
    // Update mutation ID from Step 3
    const url = 'https://x.com/i/api/graphql/YOUR_MUTATION_ID/bookmarkTweetToFolder';

    try {
        const response = await fetch(url, {
            method: 'POST',
            headers,
            body: JSON.stringify({
                variables: {
                    bookmark_collection_id: collectionId,
                    tweet_id: tweetId
                },
                queryId: 'YOUR_QUERY_ID_HERE'
            })
        });
        return response.ok;
    } catch (e) {
        return false;
    }
}

async function main() {
    let total = 0, failed = 0;

    for (const [name, info] of Object.entries(COLLECTIONS)) {
        console.log(`\n📁 ${name} (${info.tweets.length} tweets)`);

        for (let i = 0; i < info.tweets.length; i++) {
            const result = await addToCollection(info.id, info.tweets[i]);
            if (result) {
                total++;
                if ((i + 1) % 20 === 0) console.log(`  [${i+1}] ✓`);
            } else {
                failed++;
            }
            await sleep(DELAY_MS);
        }
    }

    console.log(`\nDone! Sorted: ${total}, Failed: ${failed}`);
}

main();

As before, replace:

  • Collection IDs — from the URLs after creating collections
  • Tweet IDs — from your AI analysis, grouped by topic
  • Mutation IDs — from Step 3
  • YOUR_BEARER_TOKEN — from the Authorization header in Step 3

Then sit back and watch the console do its thing.

Troubleshooting

A few issues you might run into and how to fix them:

  • “Query not found” / 404 errors — Twitter changed the mutation ID. Re-capture it from DevTools (Step 3).
  • Requests fail silently — Check that you are logged into twitter.com. The CSRF token (ct0) must be present in your cookies.
  • Collections don’t appear after creating — Refresh the bookmarks page. Sometimes there is a cache delay.
  • Rate limiting (429 errors) — Increase DELAY_MS to 3000 or higher. The 1.5-second delay is conservative but safe.
  • Script stops mid-way — Just paste and run again. It is idempotent, meaning adding an already-sorted tweet is a no-op.

Results

I ran this whole workflow on my own account, and here is what I got:

Before: 1,260 unorganized bookmarks, and it was impossible to find anything.

After about 30 minutes:

  • 10 topic collections (AI/Tech, Finance, Nigeria, Design, DevOps, Career, Comedy, Health, Politics, Sports)
  • 76 general tweets left in All Bookmarks
  • 440 junk tweets removed (stale, spam, unclassified)

Conclusion

And there you have it, an organized Twitter bookmarks library, sorted by topic, without spending hours clicking one tweet at a time.

A few parting tips: customize the AI prompt topics to match your interests (the scripts don’t care what categories you use, they just map tweet IDs to collection IDs), run the workflow periodically to keep new bookmarks sorted, and feel free to share it with friends since the scripts work for anyone logged into their own account.

On safety, these scripts only interact with Twitter’s official internal API, the same endpoints the website itself uses. They don’t store your credentials, don’t bypass authentication, and respect rate limits. No scraping, no credential sharing, no third-party services.

See you next time.