Build Lean SaaS cube logoBuild Lean SaaS
Back to Always-On Agents
Course lesson 5decisionskillintermediate

How to Use the X API to Turn Bookmarks into Linear Inbox Tasks

A practical build-in-public guide to using the X API bookmarks endpoint, a daily cron job, and a small OpenClaw/Codex skill to turn saved posts into Linear Triage issues.

Austin Witherow
12 min read
Use the attached skill
How to Use the X API to Turn Bookmarks into Linear Inbox Tasks cover image

I bookmark too many things on X.

Some of them are useful. Most of them turn into a second inbox I never process.

That is the exact kind of workflow I want Build Lean SaaS to cover: small, practical, slightly scrappy automations that turn attention into something operational. Not a giant product. Not a month-long platform build. A real workflow that can run every morning and put saved ideas where work actually happens.

If you want this to run every day without depending on your laptop, start with Codex on a VPS: Set Up an Always-On AI Development Box, then Connect Hermes to Discord. The bookmark sync stores OAuth tokens and processed tweet IDs locally, and the Discord channel gives Hermes somewhere to report what it captures.

Course path

Follow the Always-On Agents course path

Follow the complete public course path, install the skills as you go, and use DevelopJoy when you want the workflow wired into your actual VPS.

Public walkalong guide
Installable skills
DevelopJoy setup path

The project is simple:

  1. Read my X bookmarks once per day.
  2. Skip anything already processed.
  3. Create raw capture issues in Linear Triage.
  4. Post the reviewable captures into Discord so a human can discuss what deserves real work.

I also turned it into a small installable skill:

The public page explains the workflow. The repo folder contains the actual SKILL.md and script.

This is intentionally a raw capture bot. It is not a posting bot, not a general X automation system, and not an AI task generator. The job is to move saved source material into the place where work gets triaged.

The first version is free on purpose. The paid opportunity is not hiding the source. It is helping people install it, keep their agent workspace current, and adapt the workflow to their own tools through pair-programming support and done-for-you focus sprints from DevelopJoy.

Who this is for

This is for builders who already use X bookmarks as a research inbox and Linear as the place where work gets triaged.

It is a good fit if:

  • You want saved posts to become reviewable Linear Triage items.
  • You are comfortable creating an X Developer app and a Linear API key.
  • You want a cron-friendly script instead of a hosted product.
  • You want a deterministic capture step before any AI agent starts rewriting tasks.

It is not a good fit if you want a posting bot, a social media automation suite, or a fully hosted bookmark manager.

Why X bookmarks are a good automation target

Bookmarks are usually not finished tasks. They are sparks.

That makes them a bad fit for a project backlog and a good fit for an inbox. I do not want every saved post to become a committed task. I want it to become a reviewable item with source context, so I can decide later whether it is an idea, a note, a content angle, a bug, a feature, or noise.

Linear Triage is a good default target because it is built for incoming work. The sync creates raw issues. I can accept, decline, merge, label, or rewrite them later.

That distinction matters. The first version should capture bookmarks, not pretend every bookmark is already a clear task.

What the X API gives you for bookmarks

The endpoint we care about is:

For a personal automation, you authenticate with OAuth 2.0 and ask for these scopes:

The offline.access scope matters because the cron job needs a refresh token. Without it, the script can work once and then fail when the access token expires.

The useful request shape is:

Use max_results=100. That is enough for the daily run if you add fewer than 100 bookmarks per day, and it keeps the request count low during a backlog import.

What does this cost?

Last verified on May 9, 2026: X API access is mostly pay-as-you-go through credits. For your own account data, X documents Owned Reads pricing, and owned reads are currently priced at $0.001 per returned resource.

For this workflow, the cost is driven by the number of bookmarks returned.

If you have about 500 existing bookmarks:

If your daily sync reads one full page:

That is roughly $3/month if the first page is always full.

ScenarioAPI shapeEstimated X API cost
First backlog clear500 returned bookmarksAbout $0.50
Normal daily runUp to 100 returned bookmarksUp to about $0.10/day
Full month at one full page/day3,000 returned bookmarksAbout $3/month

In practice, if you add fewer than 100 bookmarks per day, the cost is still tiny compared with the value of not losing the ideas. The important thing is to treat X as a paid dependency and keep the sync boring: one daily run, one page by default, explicit backfill when you need it.

Before production use, check the X Developer Console for your own app's current prices, credits, and endpoint access. X API pricing and access rules change often enough that your console should be treated as the source of truth.

Should the script delete bookmarks after syncing?

Not in v1.

Deleting bookmarks would make the X bookmark list behave more like an inbox queue. It could also reduce future read cost because the first page would stay smaller.

But deletion changes the trust model. It requires bookmark.write, and a bug could remove saved posts you expected to keep.

So the first version is read-only against X. It stores processed tweet IDs locally and leaves your bookmarks alone. Once the read-only version has proven itself, an opt-in delete mode can be a separate change.

The actual workflow

The sync is intentionally small.

The local state file stores two things:

  • X OAuth token data.
  • Processed tweet IDs.
  • Linear issue identifiers and URLs for bookmarks already captured.

That is enough for a personal cron job. No database. No queue. No hosted service.

Linear issue shape

Each bookmark becomes a raw capture issue.

The title is short:

The description includes:

  • Source marker: x-bookmark-capture-sync
  • X URL
  • Author
  • Tweet text
  • Tweet ID
  • Posted date when available

The script omits stateId when creating the Linear issue. With Linear Triage enabled for the team, that lets the item land in Triage instead of pretending it belongs in a committed workflow state.

Install the skill

The installable source lives in:

To install from the public Build Lean SaaS skill files:

For OpenClaw-style usage, keep the folder shape and point the agent at the SKILL.md.

Supported implementation

Want help getting this running in your agent workspace?

The source is free. Pair with DevelopJoy when you want guided setup, or use a focus sprint when you want the workflow implemented for you.

Build it with us

Pair-programming lab

$100/mo
Monthly pairing session
Agent workspace setup help
PR review and workflow debugging
Start pair programming

Have us build it

Done-for-you focus sprint

Starts at $500/mo
Four monthly development hours
One focused workflow lane
Two alignment meetings + revision pass
Explore focus sprints
Prefer DIY? Install manually.

Requirements before you start

You need a few pieces in place before the commands below will work:

RequirementWhy it matters
X Developer account and appCreates the OAuth client used to read your own bookmarks.
X API creditsBookmark reads are paid owned reads under the current pricing model.
OAuth 2.0 callback URLLets you approve access and receive the code and state values.
Linear API keyLets the script create issues through Linear's GraphQL API.
Linear team IDTells Linear which team's Triage inbox receives the captures.
Node.jsRuns the bundled .mjs script.
cron or another schedulerRuns the sync once per day after the manual test works.

The script intentionally stores state locally. If you run it on a server, keep the state file on persistent storage so processed bookmarks and OAuth refresh tokens survive deploys.

Configure it

Create an X API app with OAuth 2.0 enabled. Add your local callback URL in the X Developer Console.

Then export:

Optional:

Verify before creating issues

Start with help output:

Then run a dry run:

Dry run fetches bookmarks and prints the Linear issues it would create. It does not call Linear, does not create issues, and does not mark bookmarks as processed.

I tested the script locally with these checks before publishing:

The expected behavior is boring: help prints, invalid page counts fail clearly, exchange requires --state, and dry runs avoid Linear writes.

Authorize X

From the skill folder:

Open the printed URL, approve access, and copy the code value from the callback URL.

Then copy both code and state from the callback URL and run:

That stores the refresh token in the local state file.

Run the daily sync

For normal daily use:

That fetches the first page of bookmarks.

If your local state is already warm, you can stop once the script sees a bookmark it already processed:

If you want a smaller paid read on the daily run, lower the page size:

If you want the daily job to inspect more than one page:

For the initial backlog:

If you want to keep the first test small:

For a safe first backlog test:

Add the cron job

Use a daily cron once the manual run works.

That gives you a daily Linear Triage inbox item for each new bookmark without turning X into another place you have to remember to process.

Troubleshooting

OAuth says the code verifier is missing.

Run auth-url again from the same environment where you will run exchange. The script stores the PKCE verifier in the local state file.

OAuth says the state is missing or mismatched.

Copy both code and state from the same callback URL. If you opened multiple authorization URLs, use the newest one and rerun auth-url if needed.

The cron job works manually but fails overnight.

Cron often runs with a smaller environment than your shell. Use absolute paths, export the required environment variables inside the cron context, and send logs to a file.

Linear issues are created but not landing in Triage.

Confirm Triage is enabled for the target team. The script intentionally omits stateId; Linear decides whether that becomes a Triage item for the team.

The daily run costs more than expected.

Lower --page-size, use --stop-after-seen, and avoid unnecessary backfills. The script dedupes Linear issues locally, but X can still charge for resources returned by the API.

You want to delete bookmarks after syncing.

Do not bolt that onto the read-only flow casually. Deletion requires bookmark.write and should be a separate opt-in mode after the capture workflow has proven itself.

What I would add next

The useful next version is not a bigger dashboard.

I would add:

  • Optional bookmark deletion after successful Linear creation.
  • A second agent skill that turns raw bookmark captures into scoped tasks.

The first version should stay boring. Capture the thing. Put it where work happens. Process it later.

That is the whole point of this Build Lean SaaS experiment: build content around small automations we actually use, then ship the reusable artifact alongside the article.

The follow-up: agent triage

The next workflow is where Hermes, Codex, or another agent runner becomes useful inside the Discord review room.

The capture bot should stay deterministic. Then a separate heartbeat can process the raw Linear Triage items:

  1. Read new issues created by x-bookmark-capture-sync.
  2. Score each bookmark for usefulness, novelty, implementation value, documentation value, and actionability.
  3. Ask clarifying questions in Discord when a bookmark looks promising but underspecified.
  4. Convert standout items into documentation tasks, implementation tasks, research tasks, or product notes.
  5. Leave low-value captures alone or label them for later cleanup.

That separation keeps the first workflow cheap and trustworthy. The agent only enters once the source material is already captured and visible in the Discord/Linear review loop.

I shipped that follow-up as the companion skill:

The full walkalong implementation is here:

References

Use the skill

Start with the install page:

Then run it manually once before trusting cron.

Next action

Keep this inside the course path

Continue the lesson sequence, install the skill when one exists, or use DevelopJoy when you want the workflow wired into your real workspace.