添加和移除账号
从后端调用 REST 端点来修改监控列表。
发送账号 handle
在 accounts 中发送一个 handle 或 handle 数组。开头的 @ 可以省略,匹配不区分大小写。
添加账号
const apiKey = process.env.TWEETSTREAM_API_KEY;
if (!apiKey) throw new Error("Missing TWEETSTREAM_API_KEY");
const response = await fetch("https://api.tweetstream.io/api/add-account", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
accounts: ["marketdesk", "realDonaldTrump"],
}),
});
if (!response.ok && response.status !== 207) {
throw new Error(`Add failed (${response.status}): ${await response.text()}`);
}
console.log(await response.json());移除账号
const apiKey = process.env.TWEETSTREAM_API_KEY;
if (!apiKey) throw new Error("Missing TWEETSTREAM_API_KEY");
const response = await fetch("https://api.tweetstream.io/api/remove-account", {
method: "DELETE",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
accounts: "marketdesk",
}),
});
if (!response.ok && response.status !== 207) {
throw new Error(`Remove failed (${response.status}): ${await response.text()}`);
}
console.log(await response.json());选择凭证范围
标准 API key 更新标准监控账号列表。有效的 Ultra key 更新 Ultra 选择,并执行其已付费账号上限。
读取每条结果
响应包含每个 handle 的处理结果。重试前应读取每行状态,而不能只看 HTTP 状态。
命令结果
{
"action": "follow",
"requestId": "8b4f9c9c-9e7b-4a0c-9c7d-2d4d6f0a9a25",
"error": null,
"results": [
{
"input": "marketdesk",
"state": "added"
},
{
"input": "realDonaldTrump",
"state": "added"
}
],
"summary": {
"failed": 0,
"succeeded": 2,
"total": 2
}
}检查当前用量
使用标准或 Ultra API key 调用 /api/me。此私有响应不会缓存。
读取套餐和用量字段
响应包含基础套餐用量和附加的 Ultra Speed 详情。
| 字段 | 类型 | 说明 |
|---|---|---|
| credentialScope | standard 或 ultra_speed | 本次 Bearer key 的权限范围 |
| plan | BASIC、ELITE 或 ENTERPRISE | 运行时套餐枚举 |
| trackedAccounts | object | 数量、限制和规范化 handles |
| websocket | object | 当前活跃连接数和套餐限制 |
| stripe | object | 订阅状态和账期字段;标识符应视为私有 |
| ultraSpeed | object 或 null | Ultra 状态、账期、限制、独立 WebSocket 用量和取消时间 |
查看响应
账号用量请求
const apiKey = process.env.TWEETSTREAM_API_KEY;
if (!apiKey) throw new Error("Missing TWEETSTREAM_API_KEY");
const response = await fetch("https://api.tweetstream.io/api/me", {
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
if (!response.ok) {
throw new Error(`Account status failed (${response.status}): ${await response.text()}`);
}
console.log(await response.json());账号用量响应
{
"credentialScope": "standard",
"plan": "ELITE",
"trackedAccounts": {
"count": 2,
"limit": 250,
"handles": ["marketdesk", "realDonaldTrump"]
},
"websocket": {
"count": 1,
"limit": 10
},
"stripe": {
"subscriptionStatus": "ACTIVE",
"customerId": "[redacted]",
"hasCustomer": true,
"subscriptionId": "[redacted]",
"currentPeriodStart": "2026-06-30T00:00:00.000Z",
"currentPeriodEnd": "2026-07-30T00:00:00.000Z",
"canceledAt": null
},
"ultraSpeed": {
"active": true,
"status": "ACTIVE",
"billingCycle": "MONTHLY",
"paymentRail": "STRIPE_CARD",
"accountLimit": 25,
"websocket": {
"count": 1,
"limit": 5
},
"currentPeriodEnd": "2026-07-30T00:00:00.000Z",
"cancelAtPeriodEnd": false,
"canceledAt": null
}
}跟踪关联账号列表变更
已监控的企业账号在有效或试用中的 Pro、Scale 和 Ultra 套餐上默认关闭关联账号列表变更。
开启或关闭提醒
使用 POST /api/affiliate-alerts、DELETE /api/affiliate-alerts 或控制台。将已监控的 handle 作为 account 发送,开头的 @ 可以省略。重复请求是安全的。成功时返回 { account, affiliateAlertsEnabled }。
修改提醒设置
async function setAffiliateAlerts(account: string, enabled: boolean) {
const response = await fetch("https://api.tweetstream.io/api/affiliate-alerts", {
method: enabled ? "POST" : "DELETE",
headers: {
Authorization: `Bearer ${process.env.TWEETSTREAM_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ account }),
});
if (!response.ok) {
throw new Error(await response.text());
}
return await response.json();
}
console.log(await setAffiliateAlerts("marketdesk", true));
console.log(await setAffiliateAlerts("marketdesk", false));处理设置错误
开启提醒时,TweetStream 会检查账号是否仍符合企业账号资格。检查失败时返回 400 和 { error: "This account is not a business account." }。
| 状态 | 出现时机 | 处理方式 |
|---|---|---|
| 200 | 已保存的设置与请求一致 | 读取 affiliateAlertsEnabled |
| 400 | 请求 body 无效或账号不是企业账号 | 修正请求 |
| 401 | Bearer key 缺失或无效 | 发送有效的 API key |
| 403 | 订阅或功能权限未生效 | 检查套餐权限 |
| 404 | 此 API key 未监控该 handle | 检查已监控 handle |
| 500 | TweetStream 无法确认资格 | 稍后重试 |
保存和回放变更
变更会发送到 WebSocket、控制台实时流和 Discord 通知路由。关键词过滤不适用。按 (organization.id, member.id) 保存关系,eventId 仅用于完全相同的重放去重。使用 GET /api/history?type=affiliate 回放已记录变化。不提供当前列表快照或功能上线前回补。
接收币安广场帖子
币安广场账号默认关闭。可在控制台或通过此 API 开启。它们与 X 监控账号分开管理,不占用 X 账号额度。
列出和修改设置
GET /api/binance-square 返回已保存的设置,以及 displayName、squareHandle、profileUrl、avatarUrl 和 enabled。POST /api/binance-square 开启账号;DELETE /api/binance-square 关闭账号。将广场 handle 放在 account 中,开头的 @ 可以省略。重复请求是安全的。
profileUrl是规范地址。没有头像时,avatarUrl为null。- 设置属于 TweetStream 用户,因此生效的 Standard 和 Ultra 凭证会共享它们。
- 保存成功时返回
{ account, binanceSquareEnabled },其中包含规范 handle。
列出币安广场账号
const response = await fetch(
"https://api.tweetstream.io/api/binance-square",
{
headers: {
Authorization: `Bearer ${process.env.TWEETSTREAM_API_KEY}`,
},
},
);
if (!response.ok) {
throw new Error(await response.text());
}
const catalog = await response.json();
console.log(catalog);
// {
// accounts: [{
// avatarUrl: "https://bin.bnbstatic.com/static/content/live-admin-api/images/chVikg58jFQ6ScXcVmWNmj.png",
// displayName: "币安Binance华语",
// enabled: true,
// profileUrl: "https://www.binance.com/en/square/profile/Vpo7Qwqy63rk7_Km3zYYaQ",
// squareHandle: "binancezh"
// }],
// canManage: true
// }开启或关闭帖子
async function setBinanceSquarePosts(account: string, enabled: boolean) {
const response = await fetch("https://api.tweetstream.io/api/binance-square", {
method: enabled ? "POST" : "DELETE",
headers: {
Authorization: `Bearer ${process.env.TWEETSTREAM_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ account }),
});
if (!response.ok) {
throw new Error(await response.text());
}
return await response.json();
}
console.log(await setBinanceSquarePosts("binancezh", true));
// { account: "binancezh", binanceSquareEnabled: true }处理实时内容
已开启账号的帖子、回复和引用会通过 WebSocket 和适用的 Discord 路由发送。广场内容不会存入 History,因此重连后不会补发错过的帖子。关键词过滤仍然生效。Discord 默认使用全局 webhook,适用账号专属路由时除外。
- 内容使用
tweet/content,author.platform为binance_square,kind为post、reply或quote。 - 后续推文操作的
d.platform为binance_square;使用(platform, tweetId)作为帖子键。 - 有引用上下文时,回复和引用会包含
ref。帖子和个人主页链接使用币安规范地址。
币安广场内容事件
{
"v": 1,
"t": "tweet",
"op": "content",
"id": "358051617962575",
"ts": 1772000001100,
"d": {
"tweetId": "358051617962575",
"kind": "quote",
"text": "Example Binance Square quote",
"createdAt": 1772000001000,
"receivedAt": 1772000001100,
"link": "https://www.binance.com/en/square/post/358051617962575",
"author": {
"id": "Vpo7Qwqy63rk7_Km3zYYaQ",
"handle": "@binancezh",
"platform": "binance_square",
"url": "https://www.binance.com/en/square/profile/Vpo7Qwqy63rk7_Km3zYYaQ"
},
"ref": {
"type": "quote",
"tweetId": "358012920288073"
}
}
}处理设置错误
| 状态 | 出现时机 | 处理方式 |
|---|---|---|
| 200 | 已列出目录或保存设置 | 读取响应 body |
| 400 | 请求 body 无效或账号不在目录中 | 修正请求 |
| 401 | Bearer key 缺失或无效 | 发送有效的 API key |
| 403 | API 凭证未生效 | 检查订阅状态 |
| 500 | TweetStream 无法保存此设置 | 稍后重试 |
读取账号处理结果
| 状态 | 出现时机 | 推荐处理 |
|---|---|---|
| added | 账号已加入监控列表 | 视为成功 |
| already_following | 账号已经在监控中 | 作为逐行幂等结果处理 |
| removed | 账号已移除 | 视为成功 |
| not_following | 账号原本没有被监控 | 作为逐行幂等结果处理 |
| invalid_input, duplicate, not_found, failed | 输入无效、输入重复、账号不存在或操作失败 | 展示逐行 message,仅在合适时重试 |
读取 REST 状态码
Add 和 remove 端点为每个 handle 返回一行结果。HTTP 状态说明批处理结果,每行 result 说明对应 handle 的结果。
| 状态 | 出现时机 | 说明 |
|---|---|---|
| 200 | 没有任何行失败,包括幂等成功结果 | summary.failed 为 0;already_following 和 not_following 都属于成功结果 |
| 207 | 部分行成功,部分行失败 | 重试前读取 results 和 summary |
| 400 | 请求 body 无效,或每一行都因非临时原因失败 | 重试前先修正请求或逐行错误 |
| 503 | 每一行都因临时原因失败 | 使用退避策略重试整批请求 |
检查套餐限制
- Minimum:试用后 50 个监控账号和 3 个 WebSocket 连接。
- Trial:3 天内 5 个监控账号和 1 个 WebSocket 连接。
- Pro:250 个监控账号和 10 个 WebSocket 连接。
- Scale:可在定价页自助配置更高的监控账号和 WebSocket 限制。
- Pro 和 Scale 提供 History 回放;Ultra 提供 affiliate 回放。