事件

信封

每个事件都有相同的信封;d 携带下文描述的类型专属载荷。

字段类型含义
vint信封版本。目前为 1
tstring事件类型,见下表
opcreate | update | deletecreate、update(同一 id 的补全)或 delete
idstring稳定标识。按它去重
tsint (ms)在 X 上发生的时间,自纪元起的毫秒数。X 不提供资料变更、关注与取关、新增认证粉丝和删帖发生的时刻:这些事件的值是我们检测到的时间
sidstring用于回放的流位置;出现在流中和历史记录中
target.idstring被监控账号的 X 数字 id(search.match 中为帖子作者的)
target.screen_namestring被监控账号的用户名
target.namestring账号的显示名
dobject类型专属载荷

事件类型

类型类别含义
tweet.create帖子该账号发布了新内容
tweet.reply帖子它回复了某人;reply_to 携带被回复的帖子,含文本和媒体
tweet.retweet帖子它转推了某人;retweet_of 携带完整的原帖
tweet.quote帖子它引用了某人;quoted 携带完整的被引用帖子
tweet.edit帖子它编辑了一条帖子;事件携带新版本,edit_of 是被它替换的版本
tweet.delete帖子该账号发布过的一条帖子消失了
profile.name资料显示名称已更改
profile.screen_name资料用户名已更改
profile.bio资料简介已更改
profile.location资料位置已更改
profile.url资料资料链接已更改
profile.avatar资料头像已更改;old 和 new 为图片 URL
profile.banner资料横幅已更改;old 和 new 为图片 URL
profile.pinned资料置顶帖子已更改;tweet 和 old_tweet 携带帖子本身
profile.verified资料认证标识出现或消失
follow.add关注关系该账号开始关注某人;user 是对方的完整资料
follow.remove关注关系该账号取消关注了某人
followers.verified.add关注关系一个认证账号开始关注它;user 携带简介、计数、位置、注册日期
account.status账号账号变为受保护、被封禁或不可见,或恢复正常
search.match搜索有人发布了匹配你某个关键词的内容;keyword 说明是哪个,author 是其完整资料

对于“开始关注”或“新增粉丝”,X 不提供时间戳,所以这些事件的 ts 是我们检测到该变化的时刻。

你不必接收每个账号的每一种类型。选择事件类型介绍了如何只收其中几种,例如只收新增蓝V粉丝。

载荷

五种载荷结构覆盖全部十八种类型。

Tweet 载荷

tweet.create、tweet.reply、tweet.retweet 和 tweet.quote 的 d,也是 search.match 的基础。

字段类型含义
tweet_idstring帖子 id,字符串
kindtweet | reply | retweet | quote帖子的种类
textstring全文(含长帖)
langstring | nullX 检测到的语言
authorUser发布它的账号,完整的 User 对象,与 search.match 的作者相同:用户名、显示名、简介、头像、横幅、各项计数、认证、位置、链接和注册时间。精简第一帧里是最近一次读到的账号资料;update 携带与帖子一同读到的资料
reply_toBrief+ | null回复时:被回复的帖子——一个 Brief 加上其作者的 screen_name、tweet_id 和 user_id
retweet_ofBrief | null转推时:原帖
quotedBrief | null引用时:被引用的帖子
mediastring[]纯图片 URL,每个媒体项一个
media_itemsMedia[]每个媒体项,含类型、视频变体和尺寸
urlsstring[]帖子中展开后的链接
articleArticle | null帖子链接了 X 文章时:该文章
counts{reply, rt, like, quote, bookmark}我们读取时的回复、转推、点赞、引用和书签计数
viewsint | null浏览量,X 提供时才有
urlstring帖子的规范链接
fullbool在第一帧精简的 create 上为 false;事件携带整条帖子后为 true
kind_finalbooltrue 表示 kind 已确定;false 只出现在 kind 为 tweet 的精简第一帧上:这条帖子仍可能是引用,随后的 update(同一 id)会给出定论
kind_wastweet | null (update only)只出现在确定帖子种类的那个 update 上,且仅当第一帧给出的种类不同:第一帧当时的种类(结果是引用的帖子为 tweet)
edit_ofBrief | null仅 tweet.edit:被这一版替换的版本(它的 id,以及我们有记录时的正文和作者)
示例
{
  "v": 1,
  "t": "tweet.create",
  "op": "create",
  "id": "tweet:2097879002992070835",
  "ts": 1789012345678,
  "sid": "1789012346012-0",
  "target": {
    "id": "1652541",
    "screen_name": "Reuters",
    "name": "Reuters"
  },
  "d": {
    "tweet_id": "2097879002992070835",
    "kind": "tweet",
    "text": "Ash-covered shoes and a president in crisis…",
    "lang": "en",
    "author": {
      "id": "1652541",
      "screen_name": "Reuters",
      "name": "Reuters",
      "bio": "Top and breaking news, pictures and videos from Reuters.",
      "avatar": "https://pbs.twimg.com/profile_images/1874154135869616128/nJDmubGJ_normal.jpg",
      "banner": "https://pbs.twimg.com/profile_banners/1652541/1573687397",
      "followers": 25900000,
      "following": 1150,
      "tweets": 1080000,
      "location": "Around the world",
      "url": "https://www.reuters.com",
      "verified": true,
      "verified_type": "Business",
      "protected": false,
      "created_at": "2007-03-20T17:46:05Z",
      "category": null
    },
    "reply_to": null,
    "retweet_of": null,
    "quoted": null,
    "media": [
      "https://pbs.twimg.com/media/….jpg"
    ],
    "media_items": [
      {
        "type": "photo",
        "url": "https://pbs.twimg.com/media/….jpg",
        "expanded_url": "https://x.com/Reuters/status/2097879002992070835/photo/1",
        "width": 1200,
        "height": 675
      }
    ],
    "urls": [
      "https://reut.rs/…"
    ],
    "counts": {
      "reply": 12,
      "rt": 40,
      "like": 131,
      "quote": 3,
      "bookmark": 9
    },
    "views": 20411,
    "url": "https://x.com/Reuters/status/2097879002992070835",
    "full": true,
    "kind_final": true
  }
}

第一帧 create 刻意精简:它携带 id、作者(author,即最近一次读到的账号资料)以及文本(可能被截短),因此能在看到帖子的那一刻就发出;url 已指向该帖子。此刻引用帖未必能与原创帖区分,这样的帧会标为 tweet.create 并带 kind_final: false。随后同一 id 上的 update 携带上面的完整载荷和确定的类型:如果是引用,则为 tweet.quote 并带 kind_was: "tweet"。

同一条帖子首次投递时的样子,尚未补全
{
  "v": 1,
  "t": "tweet.create",
  "op": "create",
  "id": "tweet:2097879002992070835",
  "ts": 1789012345678,
  "sid": "1789012346012-0",
  "target": {
    "id": "1652541",
    "screen_name": "Reuters",
    "name": "Reuters"
  },
  "d": {
    "tweet_id": "2097879002992070835",
    "kind": "tweet",
    "text": "Ash-covered shoes and a president in crisis…",
    "author": {
      "id": "1652541",
      "screen_name": "Reuters",
      "name": "Reuters",
      "bio": "Top and breaking news, pictures and videos from Reuters.",
      "avatar": "https://pbs.twimg.com/profile_images/1874154135869616128/nJDmubGJ_normal.jpg",
      "banner": "https://pbs.twimg.com/profile_banners/1652541/1573687397",
      "followers": 25900000,
      "following": 1150,
      "tweets": 1080000,
      "location": "Around the world",
      "url": "https://www.reuters.com",
      "verified": true,
      "verified_type": "Business",
      "protected": false,
      "created_at": "2007-03-20T17:46:05Z",
      "category": null
    },
    "url": "https://x.com/Reuters/status/2097879002992070835",
    "full": false,
    "kind_final": false
  }
}

删除载荷

tweet.delete 的 d。只针对我们见过且现已消失的帖子发送。它的 ts 是我们检测到删除的时间;帖子本身的时间在它之前的 create 帧里。

字段类型含义
tweet_idstring被删帖子的 id
urlstring它原来的位置
示例
{
  "v": 1,
  "t": "tweet.delete",
  "op": "delete",
  "id": "tweet:2097879002992070835:delete",
  "ts": 1789012345678,
  "sid": "…",
  "target": {
    "id": "1652541",
    "screen_name": "Reuters",
    "name": "Reuters"
  },
  "d": {
    "tweet_id": "2097879002992070835",
    "url": "https://x.com/Reuters/status/2097879002992070835"
  }
}

资料变更载荷

所有 profile.* 事件的 d。这些事件的 op 为 update。

字段类型含义
fieldstring哪个资料字段变了;与类型中 profile. 之后的词相同
oldany之前的值
newany新的值
tweetBrief (pinned only)profile.pinned 时:新置顶的帖子
old_tweetBrief (pinned only)profile.pinned 时:之前置顶的帖子,如果我们有的话
示例
{
  "v": 1,
  "t": "profile.bio",
  "op": "update",
  "id": "profile:1652541:bio:9c1d2e3f4a5b",
  "ts": 1789012400000,
  "sid": "…",
  "target": {
    "id": "1652541",
    "screen_name": "Reuters",
    "name": "Reuters"
  },
  "d": {
    "field": "bio",
    "old": "Top news and analysis from around the world.",
    "new": "Top news, analysis and video from around the world."
  }
}

关注载荷

follow.add、follow.remove 和 followers.verified.add 的 d。

字段类型含义
userUser对方账号,完整的 User 对象
示例
{
  "v": 1,
  "t": "follow.add",
  "op": "create",
  "id": "follow:44196397:12:add:496948",
  "ts": 1789012400000,
  "sid": "…",
  "target": {
    "id": "44196397",
    "screen_name": "elonmusk",
    "name": "Elon Musk"
  },
  "d": {
    "user": {
      "id": "12",
      "screen_name": "jack",
      "name": "jack",
      "bio": "…",
      "avatar": "https://pbs.twimg.com/profile_images/…",
      "banner": null,
      "followers": 6400000,
      "following": 4200,
      "tweets": 29000,
      "location": "",
      "url": null,
      "verified": true,
      "verified_type": "blue",
      "protected": false,
      "created_at": "2006-03-21T20:50:14Z",
      "category": null
    }
  }
}

账号状态载荷

account.status 的 d。状态取值为 active(正常)、protected(帖子仅对批准的关注者可见)、suspended(被 X 封禁)或 unavailable(已停用、已删除或因其他原因不可见)。ts 是我们检测到变化的时间。

字段类型含义
oldactive | protected | suspended | unavailable之前的状态
newactive | protected | suspended | unavailable现在的状态
reasonstring | nullX 给出的原文说明(如有,例如 Suspended)
示例
{
  "v": 1,
  "t": "account.status",
  "op": "update",
  "id": "account:9000002:status:active>suspended:497010",
  "ts": 1789236000000,
  "sid": "…",
  "target": {
    "id": "9000002",
    "screen_name": "some_account",
    "name": "Some Account"
  },
  "d": {
    "old": "active",
    "new": "suspended",
    "reason": "Suspended"
  }
}

search.match 的 d:一个 Tweet 载荷加上关于命中的三个字段。信封中的 target 是帖子作者,不必是你的监控目标之一。

字段类型含义
keyword.idint命中的关键词的 id
keyword.querystring它的查询
keyword.labelstring | null它的标签,如果你设置了的话
authorUser作者的完整资料
author_is_targetbool如果作者同时也是本系统监控的账号,则为 true
…TweetPayloadTweet 载荷的所有字段
示例
{
  "v": 1,
  "t": "search.match",
  "op": "create",
  "id": "search:12:2097900000000000000",
  "ts": 1789012500000,
  "sid": "…",
  "target": {
    "id": "9000001",
    "screen_name": "some_trader",
    "name": "Some Trader"
  },
  "d": {
    "tweet_id": "2097900000000000000",
    "kind": "tweet",
    "text": "$SOL breaking out…",
    "lang": "en",
    "author": {
      "id": "9000001",
      "screen_name": "some_trader",
      "name": "Some Trader",
      "bio": "…",
      "followers": 1200,
      "verified": false,
      "…": "…"
    },
    "keyword": {
      "id": 12,
      "query": "($SOL OR \"Solana\") -filter:retweets",
      "label": "solana"
    },
    "author_is_target": false,
    "media": [],
    "media_items": [],
    "urls": [],
    "url": "https://x.com/some_trader/status/2097900000000000000",
    "full": true
  }
}