From 25d7cd51faa02561160105899534dc0d5a015d42 Mon Sep 17 00:00:00 2001 From: "Li, Amazing Ang" Date: Wed, 25 Mar 2026 15:07:59 +0800 Subject: [PATCH 1/2] Rename xTokenBalance to balance Update the CLI to use the API's new 'balance' field instead of 'xTokenBalance'. Adjusted src/commands/balance.ts to read me.balance, updated the unit test mock in src/tests/balance.test.ts, and changed the README to reflect "show USD balance". --- README.md | 2 +- src/commands/balance.ts | 6 +++--- src/tests/balance.test.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e7e9b1d..4e6877d 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ xapi oauth providers # list available providers ```bash xapi register # create account, saves apiKey automatically -xapi balance # show xToken balance +xapi balance # show USD balance xapi topup # generate payment URL xapi topup --method stripe --amount 10 # stripe, $10 xapi topup --method x402 # x402 (USDC on Base) diff --git a/src/commands/balance.ts b/src/commands/balance.ts index 84cf54b..0588ef9 100644 --- a/src/commands/balance.ts +++ b/src/commands/balance.ts @@ -1,6 +1,6 @@ /** * balance command - * Fetches xTokenBalance from GET /auth/me + * Fetches balance from GET /auth/me */ import { getConfig, requireApiKey, XAPI_API_HOST, scheme } from '../config.ts'; @@ -20,12 +20,12 @@ export async function balance(args: string[], flags: Record) { } try { - const me = await request<{ xTokenBalance: string; accountType: string; tier: string }>( + const me = await request<{ balance: string; accountType: string; tier: string }>( `${scheme(XAPI_API_HOST)}://${XAPI_API_HOST}/api/auth/me`, { method: 'GET', headers: { Authorization: `Bearer ${token!}` } }, ); output({ - balance: me.xTokenBalance, + balance: me.balance, accountType: me.accountType, tier: me.tier, }, flags.format as any); diff --git a/src/tests/balance.test.ts b/src/tests/balance.test.ts index d72a750..518342f 100644 --- a/src/tests/balance.test.ts +++ b/src/tests/balance.test.ts @@ -34,7 +34,7 @@ describe('balance command', () => { user: {}, }); const requestSpy = spyOn(client, 'request').mockResolvedValue({ - xTokenBalance: '999.5', + balance: '999.5', accountType: 'ENTITY', tier: 'BASIC', }); From 1924938e0c488bb1094d9554e4ccffcc70d7d821 Mon Sep 17 00:00:00 2001 From: "Li, Amazing Ang" Date: Thu, 26 Mar 2026 03:21:10 +0800 Subject: [PATCH 2/2] Add Twitter and SMS specialized guides, unify terminology - Add guides/twitter.md: read tweets, post, reply, quote, OAuth binding - Add guides/sms.md: 5SIM virtual numbers, verification codes, billing notes - Replace "action" with "API" throughout SKILL.md for clarity - Fix rest_id field name in Twitter user lookup note - Reference guides from main SKILL.md under Specialized Guides section Co-Authored-By: Claude Opus 4.6 (1M context) --- skills/xapi/SKILL.md | 55 +++++++----- skills/xapi/guides/sms.md | 164 ++++++++++++++++++++++++++++++++++ skills/xapi/guides/twitter.md | 156 ++++++++++++++++++++++++++++++++ 3 files changed, 351 insertions(+), 24 deletions(-) create mode 100644 skills/xapi/guides/sms.md create mode 100644 skills/xapi/guides/twitter.md diff --git a/skills/xapi/SKILL.md b/skills/xapi/SKILL.md index 59e51ec..30c9da1 100644 --- a/skills/xapi/SKILL.md +++ b/skills/xapi/SKILL.md @@ -19,7 +19,7 @@ npx xapi-to ## Setup -Before calling any action, you need an API key: +Before calling any API, you need an API key: ```bash # Register a new account (apiKey is saved automatically) @@ -41,27 +41,27 @@ All commands support: - `--format json|pretty|table` — Output format (default: `json`). `pretty` for indented JSON, `table` for tabular display. - `--help` — Show command-specific help. -## Two types of actions +## Two types of APIs -xapi offers two types of actions under a unified interface: +xapi offers two types of APIs under a unified interface: -1. **Capabilities** (`--source capability`) — Built-in actions with known IDs (Twitter, crypto, AI, web search, news) -2. **APIs** (`--source api`) — Third-party API proxies, discovered via `list`, `search`, or `services` +1. **Capabilities** (`--source capability`) — Built-in APIs with known IDs (Twitter, crypto, AI, web search, news) +2. **Third-party APIs** (`--source api`) — Proxied services, discovered via `list`, `search`, or `services` All commands work with both types. Use `--source capability` or `--source api` to filter. ## Usage Workflow -**Critical rule:** Before calling any action, always use `get` to understand the required parameters. +**Critical rule:** Before calling any API, always use `get` to understand the required parameters. -### Discovering actions +### Discovering APIs ```bash # Search by keyword npx xapi-to search "twitter" npx xapi-to search "token price" --source api -# List all actions (supports --source, --category, --page, --page-size) +# List all APIs (supports --source, --category, --page, --page-size) npx xapi-to list npx xapi-to list --source capability npx xapi-to list --category Social --page-size 10 @@ -70,11 +70,11 @@ npx xapi-to list --category Social --page-size 10 npx xapi-to categories npx xapi-to services --category Social -# Get action schema (shows required parameters) +# Get API schema (shows required parameters) npx xapi-to get crypto.token.price ``` -### Calling actions +### Calling APIs ```bash # Always get the schema first, then call @@ -84,7 +84,7 @@ npx xapi-to call twitter.tweet_detail --input '{"tweet_id":"1234567890"}' ### Multi-method endpoints -Some API actions have multiple HTTP methods on the same path (e.g. GET and POST on `/2/tweets`). Use `--method` to select which one: +Some APIs have multiple HTTP methods on the same path (e.g. GET and POST on `/2/tweets`). Use `--method` to select which one: ```bash # get returns an array when multiple methods exist @@ -95,11 +95,11 @@ npx xapi-to get x-official.2_tweets --method POST npx xapi-to call x-official.2_tweets --method POST --input '{"body":{"text":"Hello!"}}' ``` -## Built-in Capabilities — Quick Reference +## Built-in APIs — Quick Reference Always use `--input` with JSON for passing parameters. -### Twitter / X (8 actions) +### Twitter / X (8 APIs) ```bash # Get user profile @@ -125,9 +125,9 @@ npx xapi-to call twitter.search_timeline --input '{"raw_query":"bitcoin","count" npx xapi-to call twitter.retweeters --input '{"tweet_id":"1234567890"}' ``` -Note: Twitter user_id is a numeric ID. To get it, first call `twitter.user_by_screen_name` with the username, then extract `user_id` from the response. +Note: Twitter user_id is a numeric ID. To get it, first call `twitter.user_by_screen_name` with the username, then extract `rest_id` from the response. -### Crypto (2 actions) +### Crypto (2 APIs) ```bash # Get token price and 24h change @@ -137,7 +137,7 @@ npx xapi-to call crypto.token.price --input '{"token":"BTC","chain":"bsc"}' npx xapi-to call crypto.token.metadata --input '{"token":"ETH","chain":"eth"}' ``` -### Web Search (9 actions) +### Web Search (9 APIs) ```bash # General web search @@ -168,7 +168,7 @@ npx xapi-to call web.search.places --input '{"q":"best ramen in Tokyo"}' npx xapi-to call web.search.shopping --input '{"q":"mechanical keyboard"}' ``` -### AI Text Processing (5 actions) +### AI Text Processing (5 APIs) ```bash # Fast chat completion @@ -192,10 +192,10 @@ npx xapi-to call ai.embedding.generate --input '{"input":"hello world"}' Always use `--input` with a JSON object to pass parameters: ```bash -# Simple parameters (capability-type actions) +# Simple parameters (built-in capabilities) npx xapi-to call web.search --input '{"q":"hello world"}' -# Nested objects (API-type actions with pathParams/params/body) +# Nested objects (third-party APIs with pathParams/params/body) npx xapi-to call serper.search --input '{"body":{"q":"hello world"}}' ``` @@ -203,7 +203,7 @@ This ensures correct types (strings, numbers, booleans) are preserved. ## Code Generation (`--code`) -Use `--code ` with `get` or `call` to generate ready-to-use code snippets instead of executing the action. This is useful for embedding xapi calls into scripts or applications. +Use `--code ` with `get` or `call` to generate ready-to-use code snippets instead of executing the API call. This is useful for embedding xapi calls into scripts or applications. Supported targets and aliases: @@ -216,7 +216,7 @@ Supported targets and aliases: | `go` | — | net/http | — | ```bash -# Generate a curl command from action schema (template with empty values) +# Generate a curl command from API schema (template with empty values) npx xapi-to get crypto.token.price --code curl # Generate a Python snippet with your input pre-filled @@ -233,7 +233,7 @@ npx xapi-to get web.search --code ts ## OAuth (Twitter Write Access) -Some actions (e.g. posting tweets via `x-official.2_tweets` with POST) require OAuth authorization. Use `oauth` commands to bind your Twitter account to your API key. +Some APIs (e.g. posting tweets via `x-official.2_tweets` with POST) require OAuth authorization. Use `oauth` commands to bind your Twitter account to your API key. ```bash # List available OAuth providers @@ -274,7 +274,7 @@ Beyond built-in capabilities, xapi proxies several third-party API services incl - **Twitter API** (`twitter`) — Alternative Twitter data API with 26 endpoints - **Reddit** (`reddit`) — Reddit API with 24 endpoints (posts, comments, subreddits, search) - **Weibo** (`weibo-app`) — Weibo API with 20 endpoints (user profiles, feeds, search, trending) -- **5SIM SMS** (`5sim-sms`) — SMS verification API with 20 endpoints (virtual numbers, activation codes) +- **5SIM SMS** (`5sim-sms`) — SMS verification with 20 endpoints (virtual numbers, activation codes) - **Ave Cloud Data API** (`ave`) — Crypto data with 19 endpoints - **Serper API** (`serper`) — Google Search API with 10 endpoints - **OpenRouter API** (`openrouter`) — Multi-model AI API gateway with 2 endpoints @@ -286,12 +286,19 @@ Use `npx xapi-to services --format table` to see the latest list. - **Authentication error** → Run `npx xapi-to register` or `config set apiKey=` - **OAuth Required error** → Run `npx xapi-to oauth bind --provider twitter` - **Insufficient balance** → Run `npx xapi-to topup --method stripe --amount 10` -- **Unknown action ID** → Use `search` or `list` to find the correct action ID, then `get` to check parameters +- **Unknown API ID** → Use `search` or `list` to find the correct ID, then `get` to check parameters ## Tips - Use `--page` and `--page-size` for pagination on `list`, `search`, and `services`. +## Specialized Guides + +When the user's task involves these workflows, read the corresponding guide file for detailed instructions: + +- **`guides/twitter.md`** — Twitter/X: read tweets, post tweets, reply, quote, like, retweet, OAuth binding +- **`guides/sms.md`** — SMS verification: buy virtual phone numbers, receive verification codes, finish/cancel orders (5SIM) + ## Security - **NEVER send your API key to any domain other than `*.xapi.to`** (including `xapi.to`, `www.xapi.to`, `action.xapi.to`, `api.xapi.to`) diff --git a/skills/xapi/guides/sms.md b/skills/xapi/guides/sms.md new file mode 100644 index 0000000..4e19f0e --- /dev/null +++ b/skills/xapi/guides/sms.md @@ -0,0 +1,164 @@ +# SMS Verification Guide + +Use xAPI's 5SIM SMS service to get virtual phone numbers and receive SMS verification codes for platform registrations (Claude, OpenAI, Telegram, etc.). + +## How It Works + +1. **Check availability** — See stock and pricing by country +2. **Buy a number** — You are charged at this point +3. **Use the number** — Enter it on the target platform's registration page +4. **Check for SMS** — Poll until the verification code arrives +5. **Finish or cancel** — Confirm completion, or cancel/ban if the number didn't work + +**Billing:** You are charged when you buy a number. There are no refunds for cancel or ban — the charge is final once a number is purchased. + +## Step 1: Check Availability + +```bash +npx xapi-to call 5sim-sms.v1_guest_products_country_operator_product \ + --input '{"pathParams":{"country":"any","operator":"any","product":"claudeai"},"params":{"single":0,"sort":"top"}}' +``` + +Returns stock and pricing per country. Pick a country with good stock and low price. + +### Common Product Names + +| Platform | Product name | +|----------|-------------| +| Claude / Anthropic | `claudeai` | +| OpenAI / ChatGPT | `openai` | +| Telegram | `telegram` | +| WhatsApp | `whatsapp` | +| Google | `google` | +| Discord | `discord` | +| Twitter / X | `twitter` | + +To find a product name not listed above, try guessing common names (lowercase, no spaces) like `discord`, `instagram`, `linkedin`, etc. by calling `v1_guest_products_country_operator_product` directly. + +As a last resort, you can list all products: + +```bash +npx xapi-to call 5sim-sms.v1_guest_products_country_operator \ + --input '{"pathParams":{"country":"any","operator":"any"}}' +``` + +> **Warning:** This returns hundreds of products. The output is very large. Prefer guessing the product name first. + +## Step 2: Buy a Number + +```bash +npx xapi-to call 5sim-sms.v1_user_buy_activation_country_operator_product \ + --input '{"pathParams":{"country":"england","operator":"any","product":"claudeai"}}' +``` + +Response: + +```json +{ + "id": 123456789, + "phone": "+447123456789", + "operator": "three", + "product": "claudeai", + "price": 0.05, + "status": "PENDING", + "country": "england" +} +``` + +**Save the `id` and `phone`.** The `id` is needed for all subsequent operations. + +**You are charged at this point.** The cost is deducted from your balance when the number is purchased. + +## Step 3: Use the Number + +Tell the user to: + +1. Go to the target platform's sign-up page (e.g. claude.ai) +2. Enter the phone number from step 2 (e.g. `+447123456789`) +3. Click "Send verification code" + +**This step requires human action.** Wait for the user to confirm they've requested the code. + +## Step 4: Check for SMS + +```bash +npx xapi-to call 5sim-sms.v1_user_check_id \ + --input '{"pathParams":{"id":"123456789"}}' +``` + +Response when SMS received: + +```json +{ + "id": 123456789, + "phone": "+447123456789", + "status": "RECEIVED", + "sms": [ + { + "created_at": "2026-03-26T10:30:00Z", + "text": "Your Claude verification code is: 834291", + "code": "834291" + } + ] +} +``` + +If `status` is still `PENDING`, wait a few seconds and poll again. Typical wait is 10-60 seconds. + +**Polling strategy:** Check every 5 seconds, up to 2 minutes. If no SMS arrives, suggest trying a different country. + +## Step 5: Finish or Cancel + +### Finish (mark order as completed) + +After the user has successfully used the verification code: + +```bash +npx xapi-to call 5sim-sms.v1_user_finish_id \ + --input '{"pathParams":{"id":"123456789"}}' +``` + +### Cancel (mark order as cancelled — no refund) + +If the SMS never arrives or the number doesn't work: + +```bash +npx xapi-to call 5sim-sms.v1_user_cancel_id \ + --input '{"pathParams":{"id":"123456789"}}' +``` + +**No refund.** The charge is final. This just closes the order. + + +## Complete Agent Workflow + +When a user asks to register for a platform using SMS verification: + +1. Ask which platform (to determine the product name) +2. Check availability and pricing — suggest the cheapest option with good stock +3. Buy a number — show the phone number to the user +4. Tell the user to enter the number on the platform and request the code +5. Poll for SMS — check every 5 seconds until received +6. Show the verification code to the user +7. Wait for user to confirm they've completed registration +8. Call finish to confirm, or cancel if something went wrong + +## API Reference + +| API | Description | +|-----------|-------------| +| `5sim-sms.v1_guest_products_country_operator_product` | Check stock and pricing by country/product | +| `5sim-sms.v1_guest_products_country_operator` | List all available products | +| `5sim-sms.v1_guest_countries` | List all supported countries | +| `5sim-sms.v1_guest_prices` | Query prices by country/product/carrier | +| `5sim-sms.v1_user_buy_activation_country_operator_product` | Buy a number (reserve balance) | +| `5sim-sms.v1_user_check_id` | Check order status and SMS content | +| `5sim-sms.v1_user_finish_id` | Confirm completion (charge now) | +| `5sim-sms.v1_user_cancel_id` | Cancel order (no refund) | + +## Error Handling + +- **"Bad product"** → Wrong product name. Try guessing (lowercase, no spaces). Avoid listing all products — the response is 84KB with 1373 items. +- **SMS never arrives** → Cancel and try a different country. Higher-priced numbers tend to work better. +- **Insufficient balance** → Top up: `npx xapi-to topup --method stripe --amount 10` +- **Number rejected by platform** → Some platforms block certain countries. Try USA or UK numbers. diff --git a/skills/xapi/guides/twitter.md b/skills/xapi/guides/twitter.md new file mode 100644 index 0000000..95a8ab6 --- /dev/null +++ b/skills/xapi/guides/twitter.md @@ -0,0 +1,156 @@ +# Twitter / X Guide + +Complete guide for Twitter operations via xAPI — reading data, posting tweets, replying, and OAuth setup. + +## Reading Twitter Data (no OAuth needed) + +### Look up a user by @handle + +```bash +npx xapi-to call twitter.user_by_screen_name --input '{"screen_name":"elonmusk"}' +``` + +Returns `rest_id` (numeric user ID), `name`, `screen_name`, `followers_count`, `statuses_count`, etc. + +**Important:** Most Twitter actions require the numeric `user_id` (called `rest_id` in the response), not the @handle. Always look up the user first to get the ID. + +### Get a user's recent tweets + +```bash +npx xapi-to call twitter.user_tweets --input '{"user_id":"44196397","count":10}' +``` + +Each tweet includes: `id`, `full_text`, `created_at`, `favorite_count`, `retweet_count`, `reply_count`, `views_count`, `media`, `author`, and `quoted_tweet` if applicable. + +### Get a specific tweet and its replies + +```bash +npx xapi-to call twitter.tweet_detail --input '{"tweet_id":"2035526376468394305"}' +``` + +### Search tweets + +```bash +npx xapi-to call twitter.search_timeline --input '{"raw_query":"AI agents","count":20}' +``` + +### Get user's media posts + +```bash +npx xapi-to call twitter.user_media --input '{"user_id":"44196397"}' +``` + +### Get followers / following + +```bash +npx xapi-to call twitter.followers --input '{"user_id":"44196397"}' +npx xapi-to call twitter.following --input '{"user_id":"44196397"}' +``` + +### Get retweeters + +```bash +npx xapi-to call twitter.retweeters --input '{"tweet_id":"1234567890"}' +``` + +## Posting Tweets (OAuth required) + +Posting, replying, quoting, liking, and retweeting all require OAuth. This is a **one-time setup** — the user authorizes once, then the agent can post freely. + +### Step 1: Bind Twitter OAuth + +```bash +npx xapi-to oauth bind --provider twitter +``` + +This opens a browser for the user to authorize. After authorization, the binding is saved to the API key. + +Verify: + +```bash +npx xapi-to oauth status +``` + +Should show `tweet.write` in scopes. + +### Step 2: Post a tweet + +```bash +npx xapi-to call x-official.2_tweets --method POST \ + --input '{"body":{"text":"Hello from my AI agent!"}}' +``` + +**Character limit:** 280 characters (140 CJK characters). Each CJK character counts as 2. + +### Reply to a tweet + +```bash +npx xapi-to call x-official.2_tweets --method POST \ + --input '{"body":{"text":"Great point!","reply":{"in_reply_to_tweet_id":"2035526376468394305"}}}' +``` + +### Quote tweet + +```bash +npx xapi-to call x-official.2_tweets --method POST \ + --input '{"body":{"text":"Worth reading 👇","quote_tweet_id":"2035526376468394305"}}' +``` + +### Delete a tweet + +```bash +npx xapi-to call x-official.2_tweets_id --method DELETE \ + --input '{"pathParams":{"id":"2036012345678901234"}}' +``` + +### Like a tweet + +```bash +npx xapi-to call x-official.2_users_id_likes --method POST \ + --input '{"pathParams":{"id":""},"body":{"tweet_id":"2035526376468394305"}}' +``` + +### Retweet + +```bash +npx xapi-to call x-official.2_users_id_retweets --method POST \ + --input '{"pathParams":{"id":""},"body":{"tweet_id":"2035526376468394305"}}' +``` + +## Common Workflows + +### Research and tweet + +1. Search the web: `web.search.realtime` → get latest news +2. Summarize: `ai.text.summarize` → create a concise summary +3. Post: `x-official.2_tweets` POST → tweet the summary + +### Monitor and reply + +1. Get user tweets: `twitter.user_tweets` → check latest posts +2. Get tweet detail: `twitter.tweet_detail` → read the thread +3. Reply: `x-official.2_tweets` POST with `reply` → respond + +## API Reference + +| API | Method | Description | +|-----------|--------|-------------| +| `twitter.user_by_screen_name` | — | Look up user by @handle | +| `twitter.user_tweets` | — | Get user's recent tweets | +| `twitter.user_media` | — | Get user's media posts | +| `twitter.tweet_detail` | — | Get tweet + replies | +| `twitter.search_timeline` | — | Search tweets | +| `twitter.followers` | — | Get user's followers | +| `twitter.following` | — | Get user's following | +| `twitter.retweeters` | — | Get tweet retweeters | +| `x-official.2_tweets` | POST | Post a tweet | +| `x-official.2_tweets` | DELETE | Delete a tweet | +| `x-official.2_users_id_likes` | POST | Like a tweet | +| `x-official.2_users_id_retweets` | POST | Retweet | + +## Error Handling + +- **OAuth Required** → Run `npx xapi-to oauth bind --provider twitter` +- **403 Forbidden** → Twitter account may have restrictions; check account status +- **Tweet too long** → Shorten to 280 chars (140 CJK) +- **User not found** → Check the screen_name spelling