From xbird
Accesses Twitter/X data via stateless pay-per-request REST API using x402 USDC micropayments on Base mainnet. For backend services, autonomous agents, and programmatic integrations via HTTP.
npx claudepluginhub checkra1neth/xbird-skillThis skill uses the workspace's default tool permissions.
Pay-per-request Twitter/X API. Every call is metered via x402 (USDC on Base). Fully stateless — the server stores nothing. No database, no stored credentials.
Enables Twitter/X interactions via 35 MCP Node.js tools: tweet/post threads, search/read tweets/timelines/mentions, manage likes/retweets/bookmarks/followers, update profile/bio/avatar/banner, upload media. Zero-config browser auth.
Posts to X (Twitter) using official OAuth 1.0a API. Use for tweeting, updates, or content publishing; bypasses rate limits and bot detection of cookie-based tools like bird CLI.
Integrates with X/Twitter API to post tweets and threads, read timelines and user data, search content, and retrieve analytics. Handles OAuth 1.0a/2.0 authentication and rate limits for programmatic use.
Share bugs, ideas, or general feedback.
Pay-per-request Twitter/X API. Every call is metered via x402 (USDC on Base). Fully stateless — the server stores nothing. No database, no stored credentials.
Don't use when: Running inside Claude Code / Cursor / Windsurf (use MCP instead), or operating on Virtuals marketplace (use ACP instead).
# 1. Install xbird and generate a stateless token
npx @checkra1n/xbird login
# 2. Fund the wallet shown in login output with USDC on Base
The login command auto-detects your browser cookies, encrypts them into a self-contained stateless token locally, and saves it. Nothing is sent to the server.
Mode 1 — Stateless token (recommended): run xbird login to generate a token, then pass it via X-Encryption-Key header. The token is self-contained — the server decrypts per-request and stores nothing.
Mode 2 — Per-request headers (simplest): pass X-Twitter-Auth-Token + X-Twitter-CT0 on every request.
import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const client = new x402Client();
registerExactEvmScheme(client, { signer: account });
const paymentFetch = wrapFetchWithPayment(fetch, client);
const SERVER = "https://xbirdapi.up.railway.app";
// Search with stateless token
const res = await paymentFetch(
`${SERVER}/api/search?q=${encodeURIComponent("AI agents")}&count=10`,
{
headers: {
"X-Encryption-Key": process.env.XBIRD_TOKEN!, // from xbird login
},
},
);
const { data, cursor } = await res.json();
Server: https://xbirdapi.up.railway.app
Response: { data: {...} } or { data: [...], cursor: "..." }
Error: { error: "message" }
Undo: POST to engage, DELETE to undo (like, retweet, bookmark)
Bulk: Resolve handle → numeric ID via GET /api/users/:handle first
Pricing: Read $0.001 | Search $0.005 | Bulk/Write $0.01 | Media $0.05
Full endpoint list: see endpoints.md. Payment flow details: see x402-flow.md.
| Mistake | Fix |
|---|---|
| Payment error "invalid_payload" | Wallet address == server payTo. EIP-3009 rejects self-payment. Use a different wallet. |
| Using handle for bulk endpoints | /api/users/:id/tweets needs numeric ID. Call GET /api/users/:handle first. |
| Empty USDC balance | Fund wallet with USDC on Base mainnet (eip155:8453). $0.10 = hundreds of calls. |
| Sending only one credential header | Both X-Twitter-Auth-Token AND X-Twitter-CT0 required, or use X-Encryption-Key with stateless token. |
| Invalid token format | Token must be xbird_sk_<key>.<ciphertext>.<iv>. Re-run npx @checkra1n/xbird login to generate. |
| Rate limit 429 | Twitter rate limit. Wait 1-2 minutes, retry. |