xapi-to 0.1.19 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: xapi
3
- description: Access real-time external data via the xapi CLI — Twitter/X (including resolving and downloading tweet videos), Douyin/TikTok, Reddit, LinkedIn, Weibo, on-chain crypto data (price, holders, wallets, DEX, CEX), web/news/image/video/scholar search, AI text/image/video/speech generation and transcription, and SMS verification. Configure the Anthropic/OpenAI-compatible xAPI AI Gateway or the xAPI WebSocket Gateway for realtime voice, streaming ASR/TTS, and provider-native bidirectional sessions. Use when the user mentions xapi, wants to call a third-party API, asks what external services are available, or needs to connect an AI or realtime client to xAPI.
3
+ description: Access real-time external data and managed cloud sandboxes via the xapi CLI — Twitter/X, social platforms, crypto, web/news search, AI generation, SMS verification, and auditable ephemeral compute. Configure the xAPI AI or WebSocket Gateways, or use sandbox run for automatic quote/create/execute/cleanup. Use when the user mentions xapi, external services, or sandbox compute.
4
4
  metadata: {"openclaw":{"emoji":"x","requires":{"anyBins":["npx"]},"primaryEnv":"XAPI_KEY"}}
5
5
  ---
6
6
 
@@ -62,6 +62,17 @@ xapi offers two types of APIs under a unified interface:
62
62
 
63
63
  Both types use the same discovery and call workflow. Use `--source capability` or `--source api` on commands that expose source filtering.
64
64
 
65
+ ## Managed Sandbox Compute
66
+ Read `guides/sandbox.md` before creating a billable instance. For a one-shot
67
+ command, prefer `sandbox run`; it quotes, applies a price ceiling, waits,
68
+ executes, and terminates in `finally`:
69
+ ```bash
70
+ npx xapi-to sandbox run --command 'python3 -c "print(6 * 7)"'
71
+ ```
72
+ Use granular commands only for multi-step work. Keep the instance ID, terminate
73
+ in cleanup, and verify terminal state/cost afterward. Do not use `--keep` unless
74
+ the user explicitly wants a reusable, continuing-to-bill instance.
75
+
65
76
  ## Usage Workflow
66
77
 
67
78
  **Critical rule:** Before calling any API, always use `get` to understand the required parameters.
@@ -362,7 +373,7 @@ npx xapi-to call web.search --input '{"q":"hello world"}'
362
373
  npx xapi-to call serper.search --input '{"body":{"q":"hello world"}}'
363
374
  ```
364
375
 
365
- This ensures correct types (strings, numbers, booleans) are preserved.
376
+ Read `guides/serper.md` before using direct `serper.*` actions; it covers all current v7 actions, mini-batches, Reviews, billing, and the `web.search.*` boundary.
366
377
 
367
378
  ## Code Generation (`--code`)
368
379
 
@@ -436,10 +447,10 @@ Beyond built-in capabilities, xapi proxies **dozens** of third-party API service
436
447
  - **Douyin** (`douyin`) — Douyin/TikTok API (videos, users, trending, comments)
437
448
  - **Twitter API** (`twitter`) — Alternative Twitter data API
438
449
  - **Reddit** (`reddit`) — Reddit API (posts, comments, subreddits, search)
439
- - **LinkedIn** (`linkedin`) — LinkedIn API (person profiles & career history, company pages, posts & comments, job search)
450
+ - **LinkedIn** (`linkedin`) — LinkedIn API (person profiles & career history, company pages, posts & comments, job search). For career history, see `guides/linkedin.md` first — the profile endpoint silently omits `experience`/`education` for ordinary profiles
440
451
  - **Weibo** (`weibo-app`) — Weibo API (user profiles, feeds, search, trending)
441
452
  - **5SIM SMS** (`5sim-sms`) — SMS verification (virtual numbers, activation codes)
442
- - **Serper API** (`serper`) — Google Search API
453
+ - **Serper API** (`serper`) — 12 provider-native Google Search actions including web, images, news, maps, places, video, shopping, scholar, patents, autocomplete, Lens, and reviews. Eleven support mini-batch; Reviews does not. Read `guides/serper.md` before calling them
443
454
  - **OpenRouter API** (`openrouter`) — Multi-model AI gateway (chat, embeddings, audio transcription/speech, video)
444
455
 
445
456
  The full catalog also spans many other categories — crypto/on-chain data, CEX market data, stocks & macro, social platforms, news, weather, and more. Discover them with `search` / `services`.
@@ -455,8 +466,6 @@ The full catalog also spans many other categories — crypto/on-chain data, CEX
455
466
 
456
467
  The CLI retries idempotent metadata reads and `task poll` for transient timeouts, network failures, `408`, `429`, and `502`–`504`. It does not automatically retry arbitrary `call` actions because the upstream may already have completed a write; confirm the result before manually retrying posts, payments, or other mutations. Ordinary JSON execution has a 60-second request ceiling. HTTP SSE streams and raw downloads instead use a 60-second no-data timeout, reset whenever a chunk arrives; override it with `XAPI_TRANSFER_IDLE_TIMEOUT_MS` when an upstream legitimately pauses longer.
457
468
 
458
- ## Tips
459
-
460
469
  - Use `--page` and `--page-size` for pagination on `list`, `search`, and `services`.
461
470
 
462
471
  ## Specialized Guides
@@ -465,17 +474,20 @@ When the user's task involves these workflows, read the corresponding guide file
465
474
 
466
475
  - **`guides/twitter.md`** — Twitter/X (推特): read and paginate tweets/replies/media, download the highest-quality MP4 from a video tweet, advanced search, read long-form X Articles directly from `tweet_detail`, post tweets, reply, quote, like, retweet, OAuth binding
467
476
  - **`guides/reddit.md`** — Reddit: user profiles, posts, comments, subreddit feeds, popular/news/games feeds, trending, search
468
- - **`guides/linkedin.md`** — LinkedIn (领英): person profiles with career history, company pages, posts & comments, job search & job detail — every endpoint but job search is addressed by an ordinary LinkedIn page URL, and post comments need a numeric `urn` alongside `url`
477
+ - **`guides/linkedin.md`** — LinkedIn (领英): person profiles with career history, company pages, posts & comments, job search & job detail — every endpoint but job search is addressed by an ordinary LinkedIn page URL, and post comments need a numeric `urn` alongside `url`. **Read this guide before summarizing anyone's background:** `get__user__profile` returns `experience: null` / `education: null` for ordinary (non-creator) profiles because it reads the logged-out page, and the guide gives the fallback that recovers the real career history
469
478
  - **`guides/tiktok.md`** — TikTok: user profiles, videos, comments, search, hashtags, music, live rooms, feed
470
479
  - **`guides/douyin.md`** — Douyin (抖音): user profiles, videos, comments, hot search, hashtags, music, video mix/series
471
480
  - **`guides/xiaohongshu.md`** — 小红书 (Xiaohongshu): user profiles, notes, comments, search, topics, products, creator inspiration
472
481
  - **`guides/weibo.md`** — Weibo (微博): hot search, content search, user profiles, post details, comments, reposts, media
473
482
  - **`guides/google_search.md`** — Google Search: web, realtime, news, image, video, scholar, maps, places, shopping
483
+ - **`guides/serper.md`** — direct Serper v7 API: 12 provider-native actions, object-or-array mini-batches, Reviews pagination and batch exception, Lens, dynamic per-credit billing, and the current Webpage service boundary
474
484
  - **`guides/crypto.md`** — Crypto (加密货币): on-chain token price/overview/holders/security/OHLCV, wallet analytics, DEX pairs, CEX spot prices by symbol, news — covers contract-address vs symbol addressing and multi-chain
475
485
  - **`guides/ai.md`** — AI (人工智能): synchronous or SSE-streamed text, embeddings, asynchronous image/video generation with `task wait`, text-to-speech, and speech-to-text
476
486
  - **`guides/ai_gateway.md`** — xAPI AI Gateway: Claude Code and Anthropic/OpenAI SDK setup, model discovery, routing strategies, streaming, fallback, routing/billing headers, direct media endpoints, and known limitations
477
487
  - **`guides/ws_gateway.md`** — xAPI WebSocket Gateway: OpenAI Realtime, streaming ASR/TTS, simultaneous interpretation, podcast generation, service/path routing, browser authentication, native binary protocols, limits, billing, close codes, and reconnects
488
+ - **`guides/sandbox.md`** — managed Sandbox compute: AI tool selection, one-shot and multi-step lifecycles, provider pinning, files, Cloudflare Web previews, suspension, GPU jobs, parallel agents, cleanup recovery, audit/history, and billing verification
478
489
  - **`guides/sms.md`** — SMS verification: buy virtual phone numbers, receive verification codes, finish/cancel orders (5SIM)
490
+ - **`guides/provider.md`** — Provider management: create/update services, About/changelog, version lifecycle, metrics/events and request receipts, Skill upload/linking, rollback/delete, earnings transfer
479
491
 
480
492
  ## Security
481
493
 
@@ -8,6 +8,7 @@ Complete guide for LinkedIn operations via xAPI — person profiles with career
8
8
 
9
9
  - [Key concept: everything is addressed by URL](#key-concept-everything-is-addressed-by-url)
10
10
  - [Person data](#person-data)
11
+ - [When `experience` and `education` come back `null`](#when-experience-and-education-come-back-null)
11
12
  - [Company data](#company-data)
12
13
  - [Posts and comments](#posts-and-comments)
13
14
  - [Jobs](#jobs)
@@ -56,6 +57,48 @@ One call returns the whole profile — no follow-up requests for individual sect
56
57
 
57
58
  There are no separate `get__user__experience` / `educations` / `skills` / `honors` / `publications` endpoints in v2 — that was the older `username` → `urn` two-step API. If you were using those IDs, they now return `Action not found`.
58
59
 
60
+ ### When `experience` and `education` come back `null`
61
+
62
+ `get__user__profile` reads the **logged-out** public page. LinkedIn renders the full career and school sections there only for creator/open profiles; on an ordinary member's page it serves a trimmed topcard. The call still succeeds with `code: 200`, so the failure is silent — you get identity, `current_company`, `educations_details`, `followers`, and `people_also_viewed`, but:
63
+
64
+ ```json
65
+ { "position": null, "experience": null, "education": null, "about": "Don't use LinkedIn that much…" }
66
+ ```
67
+
68
+ `null` here means **not rendered to logged-out visitors**, not "this person has no jobs listed". A truncated `about` ending in `…` is the same signal. Never summarize a person's background from a response in this state, and never report the profile as private or empty — fall back:
69
+
70
+ ```bash
71
+ npx xapi-to call icypeas-email.api_scrape_profile \
72
+ --input '{"method":"GET","params":{"url":"https://www.linkedin.com/in/ricky-wang-74b3a0194/"}}'
73
+ ```
74
+
75
+ This returns a differently-shaped payload under `data.result`:
76
+
77
+ | Field | Contents |
78
+ |---|---|
79
+ | `worksFor[]` | Current positions — `jobTitle`, `startDate`, `description`, nested `company` (industry, size, website, HQ) |
80
+ | `alumniOf[]` | Past positions — same shape plus `endDate` |
81
+ | `educations[]` | `name`, `degree`, `fieldsOfStudy[]`, `description` |
82
+ | `headline`, `description` | Headline and the full untruncated About text |
83
+ | `firstname`, `lastname`, `address`, `numOfConnections`, `skills[]`, `languages[]` | Identity and profile detail |
84
+
85
+ Check `data.status` before reading `data.result`: `FOUND` means real data, `NOT_FOUND` means `result` is `null` and this source has nothing for that URL either. Two caveats worth carrying into any summary: the snapshot is cached, so `headline` can lag the person's current role, and `startDate`/`endDate` are year-granular (often stamped to January), so treat them as approximate. `jobTitle` also reflects whatever the member typed, which can disagree with a company's own announcement — prefer cross-checking a role against `web.search` before asserting a title.
86
+
87
+ Do not reach for `contactout-api.v1_linkedin_enrich` as a fallback. Without a separate ContactOut contract it returns a fully-populated **sample profile** (`"Example Person"` at `"Legros, Smitham and Kessler"`) with `status_code: 200`, which is easy to mistake for real data, and it is the most expensive LinkedIn-adjacent action in the catalog.
88
+
89
+ ### Person profile decision path
90
+
91
+ ```
92
+ get__user__profile
93
+ ├─ experience[] present → done, use it
94
+ └─ experience/education == null → icypeas-email.api_scrape_profile
95
+ ├─ status == FOUND → read worksFor / alumniOf / educations
96
+ └─ status == NOT_FOUND → say the career history is unavailable;
97
+ fall back to web.search for public
98
+ bios, or twitter.user_by_screen_name
99
+ when the person came from an X handle
100
+ ```
101
+
59
102
  ### Get a person's posts
60
103
 
61
104
  ```bash
@@ -144,6 +187,10 @@ This is the most expensive LinkedIn endpoint — search first, then fetch detail
144
187
  npx xapi-to call linkedin.api_v1_linkedin_web__v2_get__user__profile \
145
188
  --input '{"method":"GET","params":{"url":"https://www.linkedin.com/in/williamhgates/"}}'
146
189
 
190
+ # 1b. Only if experience/education came back null — career history from the fallback
191
+ npx xapi-to call icypeas-email.api_scrape_profile \
192
+ --input '{"method":"GET","params":{"url":"https://www.linkedin.com/in/williamhgates/"}}'
193
+
147
194
  # 2. Their posts (take `urn` from each item for step 3)
148
195
  npx xapi-to call linkedin.api_v1_linkedin_web__v2_get__user__posts \
149
196
  --input '{"method":"GET","params":{"url":"https://www.linkedin.com/in/williamhgates/","page":1}}'
@@ -186,6 +233,12 @@ npx xapi-to call linkedin.api_v1_linkedin_web__v2_get__company__profile \
186
233
  | `search__jobs` | Job search | `keywords` | `location`, `page` |
187
234
  | `get__job__detail` | Full job posting | `url` | — |
188
235
 
236
+ One non-`linkedin` action belongs in this workflow:
237
+
238
+ | Action ID | Purpose | Required params | Notes |
239
+ |---|---|---|---|
240
+ | `icypeas-email.api_scrape_profile` | Career history for profiles the logged-out page hides | `url` | Fallback when `get__user__profile` returns `experience: null`. Check `data.status == "FOUND"`. |
241
+
189
242
  Detail-style endpoints (`get__*__profile`, `get__post__detail`) are the cheapest; list-style endpoints (posts, comments, job search) cost more per call, and `get__job__detail` is the most expensive. Run `npx xapi-to get <action-id>` for the current `meta.pricing` rather than assuming these ratios hold.
190
243
 
191
244
  ## Error Handling
@@ -195,4 +248,6 @@ Detail-style endpoints (`get__*__profile`, `get__post__detail`) are the cheapest
195
248
  - **`must have required property 'urn'`** — `get__post__comments` needs the numeric `urn` alongside `url`. See [Get comments on a post](#get-comments-on-a-post).
196
249
  - **`must match pattern "^[0-9]+$"` on `/params/urn`** — you passed the prefixed `urn:li:activity:<id>` form. Send the digits only.
197
250
  - **`API Token lacks required permissions`** (upstream `403`) — the account's upstream provider token has no LinkedIn scope. This is an account entitlement, not a parameter problem; enable it in the provider dashboard.
251
+ - **`experience: null` / `education: null` / `about` ending in `…` on `get__user__profile`** — not an error and not a private profile: the logged-out page LinkedIn serves for ordinary members omits those sections. Fall back to `icypeas-email.api_scrape_profile`. See [When `experience` and `education` come back `null`](#when-experience-and-education-come-back-null).
252
+ - **A ContactOut response naming `Example Person` at `Legros, Smitham and Kessler`** — `contactout-api.*` returned its sample payload because the account has no ContactOut entitlement. It carries `status_code: 200` and a `message` pointing at a sales call. Discard it; never summarize from it.
198
253
  - **Empty `data[]` on a valid URL** — either the page is private/deleted, or you paginated past the end. LinkedIn also rate-limits aggressively; retry with backoff rather than in a tight loop.
@@ -0,0 +1,198 @@
1
+ # Provider service management
2
+
3
+ Read this guide for provider-side service authoring and operations. These
4
+ commands use `XAPI-KEY` directly and never exchange it for a broad JWT session.
5
+ The key must belong to the service owner and carry the scope named by the
6
+ operation.
7
+
8
+ ## Inspect capabilities and scopes
9
+
10
+ ```bash
11
+ npx xapi-to provider --help
12
+ npx xapi-to skill --help
13
+ npx xapi-to skill spec
14
+ ```
15
+
16
+ Use narrowly scoped keys. Common scopes are:
17
+
18
+ - `service:create`, `service:read`, `service:update`
19
+ - `version:create`, `service:publish`, `service:rollback`
20
+ - `observability:read`
21
+ - `skill:read`, `skill:submit`
22
+ - `earnings:read`; `earnings:transfer` only when reinvestment is intended
23
+ - `service:delete` only for deliberate removal workflows
24
+
25
+ Scope permission and ownership are independent. A key with a scope still cannot
26
+ manage another provider's service or Skill.
27
+
28
+ ## Create and describe a service
29
+
30
+ Create uses the backend service DTO as JSON so credentials and endpoint
31
+ contracts do not have to appear in shell history:
32
+
33
+ ```bash
34
+ npx xapi-to provider create --file ./service.json
35
+ npx xapi-to provider list
36
+ npx xapi-to provider get <service-id>
37
+ ```
38
+
39
+ Keep the three service content layers distinct:
40
+
41
+ - `description` is the short marketplace-card summary.
42
+ - `aboutMarkdown` is the long About tab.
43
+ - `website` is a public HTTP(S) link.
44
+
45
+ Prefer files for long text:
46
+
47
+ ```bash
48
+ npx xapi-to provider update <service-id> \
49
+ --description "Short marketplace summary" \
50
+ --about-file ./ABOUT.md \
51
+ --website https://example.com
52
+ ```
53
+
54
+ Use `--clear-about` or `--clear-website` to clear a value. Provider metadata
55
+ updates cannot modify the version contract or upstream credentials; use the
56
+ version command for those fields.
57
+
58
+ ## Edit and publish a revision
59
+
60
+ ```bash
61
+ # Inspect current majors and revisions
62
+ npx xapi-to provider versions <service-id>
63
+
64
+ # Either create a new major or pull a working revision from an existing major
65
+ npx xapi-to provider major create <service-id>
66
+ npx xapi-to provider revision start <service-id> <major>
67
+
68
+ # Merge a partial version-contract update; add --replace for full replacement
69
+ npx xapi-to provider version update \
70
+ <service-id> <version-id> --file ./contract.json
71
+
72
+ # Inspect before publishing
73
+ npx xapi-to provider diff <service-id> <major>
74
+
75
+ # Submit through the normal review gate with public release notes
76
+ npx xapi-to provider publish \
77
+ <service-id> <revision-id> --changelog-file ./CHANGELOG.md
78
+
79
+ # Inspect the review result
80
+ npx xapi-to provider review <service-id> <revision-id>
81
+ ```
82
+
83
+ The changelog is provider-authored, public release information associated with
84
+ that revision. It is not a system deployment log. Build, review, and runtime
85
+ events are generated by the platform and should only be read, never uploaded as
86
+ if they were evidence.
87
+
88
+ `publish` can change live service behavior after review. The CLI does not
89
+ automatically retry this write after an ambiguous transport failure. Read the
90
+ version overview and review state before deciding whether to submit again.
91
+
92
+ ## Create, upload, and link the usage Skill
93
+
94
+ Generate a service-specific starting point from the currently serving endpoints:
95
+
96
+ ```bash
97
+ npx xapi-to provider skill scaffold \
98
+ <service-id> --output ./my-service/SKILL.md
99
+ ```
100
+
101
+ The scaffold command refuses to overwrite an existing file unless `--force` is
102
+ explicitly supplied. Complete the instructions and metadata, then submit either
103
+ a local directory or a public GitHub tree:
104
+
105
+ ```bash
106
+ npx xapi-to skill submit --dir ./my-service
107
+
108
+ npx xapi-to skill submit \
109
+ --github https://github.com/org/repo/tree/main/skills/my-service \
110
+ --version 1.0.0
111
+ ```
112
+
113
+ Local submission skips symlinks, `.git`, and `node_modules`; requires a root
114
+ `SKILL.md`; permits at most 100 files; limits each file to 512 KiB and the encoded
115
+ package to 2 MiB. The server still performs manifest validation and secret
116
+ scanning. A successful upload creates or updates the owned Skill version and
117
+ submits it for review; it is not immediately public.
118
+
119
+ Use the returned submission ID:
120
+
121
+ ```bash
122
+ npx xapi-to skill status <submission-id>
123
+ npx xapi-to skill wait <submission-id> --timeout 10m
124
+ ```
125
+
126
+ After the Skill is published, bind it as the service's primary tutorial and
127
+ record the serving-contract fingerprint:
128
+
129
+ ```bash
130
+ npx xapi-to provider skill link <service-id> <skill-id>
131
+ npx xapi-to provider skill fingerprint \
132
+ <service-id> --skill-version-id <skill-version-id>
133
+ npx xapi-to provider skill context <service-id>
134
+ ```
135
+
136
+ Only a Skill owned by the same provider can be linked, and one Skill can be the
137
+ primary Skill of only one service. The backend permits linking a pending Skill,
138
+ but the public marketplace exposes only a published version; wait for publication
139
+ unless intentionally preparing the association early. Use `provider skill unlink`
140
+ to remove the primary association. The context response reports drift when host,
141
+ major version, or serving endpoints no longer match the stored fingerprint; update
142
+ and resubmit the Skill rather than merely overwriting the fingerprint.
143
+
144
+ ## Observe and recover
145
+
146
+ ```bash
147
+ npx xapi-to provider metrics --days 30
148
+ npx xapi-to provider metrics <service-id> --days 7
149
+ npx xapi-to provider events --limit 50
150
+ npx xapi-to provider events --after '<opaque-next-cursor>' --limit 50
151
+ ```
152
+
153
+ Pass event cursors back unchanged. Metrics and events are owner-scoped; usage
154
+ events are also restricted to the current key where applicable.
155
+
156
+ Verify the finalized cost of a canary or provider call with its receipt ID. Use
157
+ the `X-XAPI-Request-Id` response header or the final `xapi.usage` SSE event, and
158
+ wait when asynchronous billing has not finalized yet:
159
+
160
+ ```bash
161
+ npx xapi-to usage <request-id>
162
+ npx xapi-to usage wait <request-id> --timeout 1m
163
+ ```
164
+
165
+ Receipt reads are idempotent. The wait command applies one total deadline,
166
+ retries not-found and transient transport failures within that deadline, and
167
+ fails immediately for permanent authorization or validation errors.
168
+
169
+ Rollback and default-major changes affect live routing:
170
+
171
+ ```bash
172
+ npx xapi-to provider rollback \
173
+ <service-id> <major> --revision <published-revision-id> \
174
+ --reason "Restore the last known-good contract"
175
+ npx xapi-to provider default-major <service-id> <major>
176
+ npx xapi-to provider deprecate <service-id> <major>
177
+ npx xapi-to provider restore <service-id> <major>
178
+ ```
179
+
180
+ Inspect the target revision before rollback. Do not automatically retry an
181
+ ambiguous rollback response. Deletion requires both `service:delete` and an
182
+ explicit service name or ID confirmation:
183
+
184
+ ```bash
185
+ npx xapi-to provider delete <service-id> --confirm <service-name-or-id>
186
+ ```
187
+
188
+ ## Earnings reinvestment
189
+
190
+ ```bash
191
+ npx xapi-to earnings
192
+ npx xapi-to earnings list --status SETTLED
193
+ npx xapi-to earnings transfer 1 --idempotency-key <stable-operation-key>
194
+ ```
195
+
196
+ Transfer is one-way: it converts settled provider earnings into spendable xAPI
197
+ balance. Confirm the amount and available settled balance first. A transfer may
198
+ be retried only with the same idempotency key and the same amount.