# Checkra1neth Xbird Skill Xbird REST API

> xbird REST API — Twitter/X with x402 Micropayments

- Skill: `tomevault-io/checkra1neth-xbird-skill-xbird-rest-api` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/checkra1neth-xbird-skill-xbird-rest-api`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/checkra1neth-xbird-skill-xbird-rest-api/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/checkra1neth-xbird-skill-xbird-rest-api

---


# xbird REST API — Twitter/X with x402 Micropayments

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.

## When to Use

- Backend services or scripts that need Twitter data via HTTP
- Autonomous agents without MCP support
- Any language/framework (not just TypeScript)
- Direct programmatic integrations

**Don't use when:** Running inside Claude Code / Cursor / Windsurf (use MCP instead), or operating on Virtuals marketplace (use ACP instead).

## Setup

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

## Authentication

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

## Complete Example

```typescript
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();
```

## Quick Reference

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

## Common Mistakes

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

---
> Source: [checkra1neth/xbird-skill](https://github.com/checkra1neth/xbird-skill) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-06-16 -->

