跳到文档正文

连接、认证与心跳

使用文档列出的区域端点,在升级连接时认证,并保留原生 ping 和 pong 处理。

运行五分钟快速开始
在聊天中打开
按产品代码校对:2026年9月2日

选择基础 URL

接口URL用途
WebSocket(美国)wss://ws-iad.tweetstream.io/ws用于美国境内的连接
WebSocket(全球)wss://ws-global.tweetstream.io/ws用于美国以外的连接
RESThttps://api.tweetstream.io/api/history、/api/me 和账号管理的基础域名
Dashboardhttps://tweetstream.io/dashboardAPI key、监控列表、账单和 Discord 路由

认证请求

实时客户端使用 WebSocket 子协议认证,REST 请求使用 Bearer token。API key 只能保存在服务端,绝不能放入公开的浏览器代码。

上下文Header 或协议说明
WebSockettweetstream.v1 + tweetstream.auth.token.<API_KEY>首选的实时认证方式
WebSocket fallbackAuthorization: Bearer <API_KEY> or ?apiKey=<API_KEY>优先使用 Authorization;只有运行时无法设置 Header 时才使用查询参数认证
RESTAuthorization: Bearer <API_KEY>Pro 或 Scale 的 History 请求使用标准 key。有效或试用中的 Ultra 可用拥有该账号的标准 key 或 Ultra key 请求 AFFILIATE。账号管理和 /api/me 可使用任一 key

认证服务端连接

typescript
const socket = new WebSocket("wss://ws-global.tweetstream.io/ws", [
  "tweetstream.v1",
  `tweetstream.auth.token.${process.env.TWEETSTREAM_API_KEY}`,
]);
 
socket.addEventListener("message", (event) => {
  const message = JSON.parse(event.data);
  console.log(message.t, message.op, message.d);
});

连接

美国境内使用 wss://ws-iad.tweetstream.io/ws,其他地区使用 wss://ws-global.tweetstream.io/ws。服务端返回 tweetstream.v1,不会回显携带认证 token 的协议。示例通过指数退避重连。短连接会继续增加等待时间,稳定连接 30 秒后重置。

使用 Node.js 连接

typescript
import WebSocket from "ws";
 
type StreamEvent = {
  t?: string;
  op?: string;
  d?: {
    author?: { handle?: string };
    detected?: unknown;
    text?: string;
  };
};
 
const apiKey = process.env.TWEETSTREAM_API_KEY;
if (!apiKey) {
  throw new Error("Missing TWEETSTREAM_API_KEY");
}
 
let retry = 0;
let healthyTimer: ReturnType<typeof setTimeout> | undefined;
let reconnectTimer: ReturnType<typeof setTimeout> | undefined;
 
function scheduleReconnect(reason: string) {
  if (reconnectTimer) return;
 
  const delayMs = Math.min(30_000, 1_000 * 2 ** retry) + Math.floor(Math.random() * 500);
  retry += 1;
  console.warn(`Reconnecting in ${delayMs}ms: ${reason}`);
  reconnectTimer = setTimeout(() => {
    reconnectTimer = undefined;
    connect();
  }, delayMs);
}
 
function connect() {
  const ws = new WebSocket("wss://ws-global.tweetstream.io/ws", [
    "tweetstream.v1",
    `tweetstream.auth.token.${apiKey}`,
  ]);
 
  ws.on("open", () => {
    if (reconnectTimer) clearTimeout(reconnectTimer);
    reconnectTimer = undefined;
    healthyTimer = setTimeout(() => {
      retry = 0;
      healthyTimer = undefined;
    }, 30_000);
    console.log("TweetStream connected");
  });
 
  ws.on("message", (raw) => {
    const event = JSON.parse(raw.toString()) as StreamEvent;
 
    if (event.t === "tweet" && event.op === "content") {
      const tweet = event.d;
      console.log(tweet?.author?.handle, tweet?.text);
    }
 
    if (event.t === "tweet" && event.op === "meta") {
      console.log("enrichment", event.d?.detected);
    }
  });
 
  ws.on("close", (code, reason) => {
    if (healthyTimer) clearTimeout(healthyTimer);
    healthyTimer = undefined;
    scheduleReconnect(`close ${code}: ${reason.toString()}`);
  });
 
  ws.on("unexpected-response", (_request, response) => {
    console.error("Connection rejected", response.statusCode, response.statusMessage);
    response.resume();
    if (response.statusCode === 429 || response.statusCode === 503) {
      scheduleReconnect(`HTTP ${response.statusCode}`);
      return;
    }
    process.exitCode = 1;
  });
 
  ws.on("error", (error) => {
    console.error("WebSocket error", error.message);
  });
}
 
connect();

使用 Python 连接

使用任何能发送这两个子协议的 WebSocket 运行时。正常关闭和传输错误都会通过指数退避重连。短连接会继续增加等待时间,稳定连接 30 秒后重置。

Python 重连客户端

python
import asyncio
import json
import os
import websockets
 
API_KEY = os.environ["TWEETSTREAM_API_KEY"]
URI = "wss://ws-global.tweetstream.io/ws"
PROTOCOLS = ["tweetstream.v1", f"tweetstream.auth.token.{API_KEY}"]
 
async def main():
    loop = asyncio.get_running_loop()
    retry = 0
    while True:
        connected_at = None
        reason = "connection closed"
        try:
            async with websockets.connect(URI, subprotocols=PROTOCOLS) as ws:
                connected_at = loop.time()
                async for raw in ws:
                    event = json.loads(raw)
                    if event["t"] == "tweet" and event["op"] == "content":
                        tweet = event["d"]
                        print(tweet.get("author", {}).get("handle"), tweet.get("text"))
        except Exception as error:
            reason = str(error)
 
        if connected_at is not None and loop.time() - connected_at >= 30:
            retry = 0
        wait = min(30, 2 ** retry)
        retry = min(retry + 1, 5)
        print(f"reconnecting in {wait}s after {reason}")
        await asyncio.sleep(wait)
 
asyncio.run(main())

处理心跳和断开

TweetStream 每 30 秒发送一次原生 WebSocket ping。标准 Node.js 和 Python 客户端会自动回复 pong。服务端会关闭无响应的连接。重连后,使用 History API 回补已存内容、资料、关注和关联账号事件。

处理限制和重试

套餐设定活跃 WebSocket、监控账号和 History API 限制。收到 429 时暂停对应流程;如果响应包含 retryAfterSeconds,按其等待,否则使用常规退避。

接口限制信号推荐处理
WebSocket连接升级时返回 429关闭不用的连接,或升级到更多连接数的套餐
History API限流时返回 retryAfterSeconds等待后再回放下一个窗口
监控账号/api/me 返回套餐用量批量添加前检查 count 和 limit