用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/ratacat/ratacats-skills --skill x-undocumented-api命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | x-undocumented-api |
| description | Manual-only; never auto-load. Use only when explicitly named (x-undocumented-api / x-api-skill). |
| metadata | {"category":"developer tools","blurb":"Safe guide to X.com's private web API: verifies current GraphQL operations, request headers, cursors, and secret-safe evidence.","keywords":["x","undocumented","api"]} |
Use this skill for X.com's frontend web API: GraphQL operations under https://x.com/i/api/graphql, supporting REST-like web endpoints under https://x.com/i/api, and the browser headers/cookies those calls require.
operationName as the durable conceptual endpoint, and queryId as rotating bundle metadata.auth_token, ct0, bearer tokens, proxy credentials, or full upstream payloads.x-client-transaction-id from the current X web page/bundle material and the exact request method/path.itemFilter can be an application-side filter rather than a proven GraphQL variable.Read only what the task needs:
Reusable script:
scripts/extract-x-graphql-endpoints.ts: fetch current X web bundles and save a JSON/CSV operation inventory.SearchTimeline author queries and record lane yield per page, not just total pages.X web GraphQL paths have this form:
https://x.com/i/api/graphql/<queryId>/<operationName>?variables=<json>&features=<json>
Some operations also use fieldToggles=<json>.
Authenticated reads commonly need these headers:
authorization: Bearer <X web bearer token>
x-csrf-token: <ct0>
cookie: ct0=<ct0>; auth_token=<auth_token>
x-client-transaction-id: <generated for method + full path>
x-twitter-active-user: yes
x-twitter-auth-type: OAuth2Session
x-twitter-client-language: en
origin: https://x.com
referer: https://x.com/
The transaction ID path must include the query ID:
/i/api/graphql/<queryId>/<operationName>
| Symptom | Likely cause | Next check |
|---|---|---|
| HTTP 401 or 403 | Expired cookies, missing ct0, bad bearer token, access restriction, account challenge | Refresh browser session material; do not print secrets |
| Empty HTTP 404 | Missing/invalid x-client-transaction-id or stale query ID | Verify full path includes query ID and regenerate transaction ID from current X material |
| HTTP 429 | Rate limited account, IP, or operation | Inspect X rate-limit headers and retry windows |
| HTTP 400 | Variable, feature, or field-toggle mismatch | Compare request payload with current bundle caller code |
| HTTP 200 with empty timeline | Access limitation, wrong response path, stale variables, logged-out limitation, or empty source | Inspect top-level keys and instruction path without dumping payload |
| Data is stale or incomplete | Search index behavior or ranking product choice | Prefer native timeline operations when available |
| Mutation returns HTTP 200 but no send captured in the HTTP log, yet the action took effect | The action rode a WebSocket, not an HTTP mutation (X Chat sends are WS frames to wss://chat-ws.x.com/ws) | Use a WebSocket frame capture (CDP WebSocketFrameSent/Received), not request logging. HTTP GraphQL capture will never see these sends |
| Reply verification mismatch after REST or fallback send | X may prepend the leading @handle; the visible draft text is often the display_text_range slice | Compare against legacy.full_text.slice(display_text_range) when available |
SearchTimeline uses rawQuery, product, count, optional cursor, and promoted-content controls.SearchTimeline author queries can outperform native user timelines for corpus collection. In live xpool probes on 2026-06-18, from:<handle> -filter:replies -filter:retweets and from:<handle> filter:replies reached 100 lane items in 5 pages for sampled accounts where native timeline crawls hit only 39-47 items after 20 pages.SearchTimeline continuations under rotating accounts produced concentrated 404 / timeout / network failures; pinning one account per lane materially reduced that failure mix, though it did not remove empty-page degeneration.ListLatestTweetsTimeline, not SearchTimeline list:<id>.CommunityTweetsTimeline, not a SearchTimeline community operator.wss://chat-ws.x.com/ws?token=<JWT>), not a GraphQL/REST mutation. Legacy DM mutations (useSendMessageMutation, REST dm/new2.json) are gone from current bundles. See the 2026-06-18 notes below.UserTweetsAndReplies local itemFilter handling is not proof of an upstream GraphQL variable. In the 2026-06-18 bundle scan, itemFilter, authored_posts, and authored_replies strings were absent from the current client-web bundle.UserTweets can include repost surfaces; do not treat it as pure authored root-post history without checking surface kind or local filters. In 2026-06-18 live xpool probes, native UserTweets recovered materially more root-post items than author-search for some post-light accounts (64 vs 20, 100 vs 74, 22 vs 2 in early comparisons, later 22 vs 2, 1 vs 1, and 18 vs 0 on three more post-light accounts), so a post lane may need native-timeline preference even when reply lanes stay on search.These notes came from a live investigation (logged-in managed sessions via a CDP-backed browser tool, with WebSocket frame capture). Treat them as the current DM reality, superseding any older "send a DM via GraphQL" assumption.
useSendMessageMutation (query id MaxK2PKX1F9Z-9SwqwavTw in the 2023-era twitter-api-client registry) and the REST fallback dm/new2.json are absent from every current X web bundle chunk. Do not reuse them; they will not work./messages redirects to /i/chat/pin/new until the account is provisioned.wss://chat-ws.x.com/ws?token=<JWT>. HTTP GraphQL/REST capture during a real send observed zero send calls. There is no send operationName to extract — bundle extraction can never surface a DM send query id, by design, not by capture gap./i/chat/pin/recovery and must re-enter the PIN to re-derive keys before any read or send. Cookie-only / headless sessions are therefore insufficient for X Chat without PIN re-entry.dmBlockUser (IYw9u1KEhrS-t-BXsau4Uw), dmUnblockUser (Krbs6Nak_o7liWQwfV1jOQ), DmNsfwMediaFilterUpdate (of_N6O33zfyD4qsFJMYFxA), ConversationControlChange (57WYJNnWH0vM3Ip_gm8B2g), ConversationControlDelete (OoMO_aSZ1ZXjegeamF9QmA). These are block/unblock/control, not send.Network.enable does not capture POST bodies unless max_post_data_size is set; and WebSocket frames need dedicated WebSocketCreated / WebSocketFrameSent / WebSocketFrameReceived handlers — request handlers never see them. A CDP tool without WS handlers is blind to X Chat./i/chat compose returns only the sender, and a typed message becomes a self-chat ("You: ") the other account never receives.These notes came from a live, user-approved xpool reply probe plus current X web bundle inspection. Treat query IDs as dated facts and regenerate before reusing.
CreateTweet query ID was 5CdvsV_zjv4L64XFifAglw; current observed TweetDetail query ID was oCon7R-cgWRFy6EfZjaKfg.POST /i/api/graphql/5CdvsV_zjv4L64XFifAglw/CreateTweet, returned HTTP 200, had no top-level GraphQL errors, and returned data.create_tweet.tweet_results.ct0 rotation boolean, rate-limit headers, body key names, created public tweet ID, parent tweet ID, and verifier result.tweet_text, media, semantic_annotation_ids, and reply.in_reply_to_tweet_id with exclude_reply_user_ids.fieldToggles on CreateTweet; include the current toggles when the bundle advertises them.engagement_request is conditional, not universal. X web emitted it only when composer/source state had promoted/impression content with both disclosure_type and impression_id; missing it is a source-context gap for impression-backed targets, not proof every direct reply is non-native.TweetDetail parent-thread visibility can lag or paginate. In the live probe, the created reply was initially behind a ShowMoreThreads cursor in rankingMode=Relevance, then appeared on page 1 a few minutes later.SearchTimeline can be a false negative for newly created replies. In the live probe, the reply was visible through parent TweetDetail Relevance, while SearchTimeline missed it by both conversation_id:<parent_id> and exact-text search.SearchTimeline presence as the source of truth for reply visibility. It is a discoverability/indexing signal only.ModeratedTimeline for the parent before labeling a reply hidden; in the live probe it returned a valid empty hidden-replies timeline while parent TweetDetail showed the reply.cursor_loop is often a corpus-shape signal, not a pure transport failure. In one fresh xpool worker slice, low-yield post loops split into two buckets: sparse accounts where replies also stopped early (average lifetime tweet count about 200) and reply-heavy accounts where replies still reached target (average lifetime tweet count about 4300 while root-post yield stayed near 7).UserTweets / replies=SearchTimeline rollout (1,534 samples since the 2026-06-18T21:39:50Z boot), reply lanes were dominated by target_items_reached and source_exhausted, while posts still split across target_items_reached, max_pages_reached, and cursor_loop. Treat that as evidence for a hybrid endpoint choice, not a single universally best authored-corpus endpoint.runner_terminated burst immediately after a PM2 restart can be rollover noise from in-flight work rather than a steady-state cursor signal. In the same 2026-06-18 investigation, all fresh runner_terminated reply-lane rows landed within about one second, 44-45 seconds after restart, with none afterward.TimelineTimelineCursor entries commonly carry Top and Bottom cursor values.count is not always honored by timeline operations; observe returned item counts. Current live author-search probes emitted about 20 items/page even when higher counts were requested.TweetDetailModeratedTimelineTweetDetail; a one-way poster-follows-parent-author edge did not clear that threshold in the sampled runs.Use when a consequential design, architecture, process, or policy choice depends on unknowns that reasoning alone cannot settle, or when an investigation plan may be over-scoped, prematurely branched, or full of experiments whose results may not change a decision. Not for questions answerable by a straightforward lookup alone.
Analyze one PM event for PMKNB: identify exact Polymarket/Kalshi instruments (conditionId, token IDs, tickers), assess market forces, resolution/oracle risk, liquidity, and counterparty risk; output forecast, report, brief, proposal, or no-publish.
Chained clarity review of a repo, plan, or work items — combines code review, plan refinement, deep-module architecture, DRY/cruft, and naming analysis. Use for clarify/defuzz/audit/harden/fresh-eyes requests.