> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sorsa.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 响应格式

# API 响应格式：User 与 Tweet 对象结构

Sorsa API 以 JSON 返回所有数据。本页介绍响应结构、核心数据对象、字段类型和分页模型，让你了解各端点会返回什么。

***

## 约定

在了解具体对象之前，请先查看适用于整个 API 的格式规则。

**ID 是字符串。** 所有 X/Twitter ID（`id`、`conversation_id_str`、`in_reply_to_tweet_id` 等）都以字符串返回，而非整数。X 使用的 Snowflake ID 是 64 位数字，超出了 JavaScript 的 `Number.MAX_SAFE_INTEGER`。使用字符串可防止浏览器、Node.js 及将 JSON 数字表示为浮点数的语言发生静默精度丢失。

**核心时间戳是 ISO 8601 字符串。** User 和 Tweet 的 `created_at` 使用如 `2026-03-06T12:00:00Z` 的值。其他日期字段请查看端点结构，不要假设验证结果或关系日期使用相同格式。

**布尔值使用严格类型。** `verified`、`is_reply`、`protected` 和 `can_dm` 等状态标记始终为 `true` 或 `false`，不会使用 `0`/`1` 或 `"true"`/`"false"`。

**null 与缺失字段。** 请稳健处理可选字段，区分缺失值与实际测得的零或 `false`。遍历 `bio_urls`、`pinned_tweet_ids` 等可选数组时，将 null 或缺失值统一为空列表（Python 使用 `user.get("bio_urls") or []`；JavaScript 使用 `user.bio_urls ?? []`）。精简响应模型会省略完整 User 对象中的部分字段。

***

## 响应包装结构

返回单个对象的端点（如 `/info` 或 `/tweet-info`）直接在顶层返回对象。返回列表的端点使用以下包装结构之一。

**UsersResponse**：用于 `/followers`、`/follows`、`/verified-followers`、`/retweeters`、`/search-users`、`/list-members` 和 `/list-followers`。`/community-members` 使用相同包装字段，但返回精简的 `CommunityUser` 对象。

```text theme={null}
{
  "users": [ ... ],
  "next_cursor": "abc123"
}
```

**TweetsResponse**：用于 `/user-tweets`、`/comments`、`/quotes`、`/search-tweets`、`/mentions`、`/list-tweets`、`/community-tweets` 和 `/community-search-tweets`。

```text theme={null}
{
  "tweets": [ ... ],
  "next_cursor": "abc123"
}
```

**FollowersResponse**：用于 `/new-followers-7d`、`/new-following-7d` 和 `/top-following`。`/top-followers` 使用 `TopFollowersResponse`，包含精简资料和 `score` 字段。

```text theme={null}
{
  "users": [ ... ]
}
```

注意：FollowersResponse 不包含 `next_cursor`，而是在一次响应中返回完整结果集。

***

## User 对象

User 对象表示 X/Twitter 账号资料。`/info` 直接返回该对象；列表端点将其作为数组元素；每个 Tweet 对象也会在 `user` 字段中嵌入它。

```text theme={null}
{
  "id": "44196397",
  "username": "elonmusk",
  "display_name": "Elon Musk",
  "description": "Mars & Cars, Chips & Dips",
  "location": "Earth",
  "created_at": "2009-06-02T20:12:29Z",
  "followers_count": 236021252,
  "followings_count": 1292,
  "favourites_count": 214650,
  "tweets_count": 98479,
  "media_count": 4374,
  "profile_image_url": "https://pbs.twimg.com/profile_images/.../photo_normal.jpg",
  "profile_background_image_url": "https://pbs.twimg.com/profile_banners/44196397/...",
  "bio_urls": ["https://example.com"],
  "pinned_tweet_ids": ["2028500984977330453"],
  "verified": true,
  "can_dm": false,
  "protected": false,
  "possibly_sensitive": false
}
```

| 字段                             | 类型                       | 说明                   |
| :----------------------------- | :----------------------- | :------------------- |
| `id`                           | string                   | 永久数字用户 ID（Snowflake） |
| `username`                     | string                   | 当前用户名（不含 @）          |
| `display_name`                 | string                   | 公开个人资料名称             |
| `description`                  | string                   | 账号简介                 |
| `location`                     | string                   | 用户填写的所在地（自由文本）       |
| `created_at`                   | string                   | 账号创建时间戳              |
| `followers_count`              | integer                  | 粉丝数                  |
| `followings_count`             | integer                  | 关注的账号数               |
| `favourites_count`             | integer                  | 该账号累计点赞次数            |
| `tweets_count`                 | integer                  | 累计发布推文数              |
| `media_count`                  | integer                  | 累计发布媒体数量             |
| `profile_image_url`            | string                   | 头像 URL               |
| `profile_background_image_url` | string                   | 横幅图片 URL             |
| `bio_urls`                     | array of strings or null | 简介中的 URL             |
| `pinned_tweet_ids`             | array of strings or null | 置顶推文 ID              |
| `verified`                     | boolean                  | 认证状态（蓝色、金色或灰色认证标记）   |
| `can_dm`                       | boolean                  | 是否开放私信               |
| `protected`                    | boolean                  | 账号是否为私有              |
| `possibly_sensitive`           | boolean                  | 账号是否被标记为敏感           |

***

## Follower 对象

Follower 在 User 对象基础上增加一个字段，由 `/new-followers-7d`、`/new-following-7d` 和 `/top-following` 返回。`/top-followers` 返回单独的精简模型，其中包含 `score`。

| 新增字段           | 类型     | 说明        |
| :------------- | :----- | :-------- |
| `followerDate` | string | 记录关注关系的日期 |

***

## Tweet 对象

Tweet 对象包含单条推文的完整内容、元数据、互动指标和嵌套关系。`/tweet-info` 直接返回该对象，推文列表端点将其作为数组元素。

```text theme={null}
{
  "id": "1234567890123456789",
  "full_text": "This is the complete tweet text including mentions and links",
  "created_at": "2026-03-06T12:00:00Z",
  "lang": "en",
  "bookmark_count": 42,
  "likes_count": 1500,
  "quote_count": 23,
  "reply_count": 89,
  "retweet_count": 312,
  "view_count": 250000,
  "conversation_id_str": "1234567890123456789",
  "in_reply_to_tweet_id": null,
  "in_reply_to_username": null,
  "is_reply": false,
  "is_quote_status": false,
  "is_replies_limited": false,
  "entities": [ ... ],
  "user": { ... },
  "quoted_status": null,
  "retweeted_status": null
}
```

**内容字段**

| 字段           | 类型     | 说明                         |
| :----------- | :----- | :------------------------- |
| `id`         | string | 唯一推文 ID（Snowflake）         |
| `full_text`  | string | 完整推文正文                     |
| `created_at` | string | 发布时间戳                      |
| `lang`       | string | 检测到的语言代码，例如 "en"、"ja"、"es" |

**互动指标**

| 字段               | 类型      | 说明     |
| :--------------- | :------ | :----- |
| `likes_count`    | integer | 点赞总数   |
| `retweet_count`  | integer | 转推总数   |
| `reply_count`    | integer | 回复总数   |
| `quote_count`    | integer | 引用推文总数 |
| `view_count`     | integer | 展示总次数  |
| `bookmark_count` | integer | 收藏总数   |

**对话串与回复上下文**

| 字段                     | 类型             | 说明            |
| :--------------------- | :------------- | :------------ |
| `conversation_id_str`  | string         | 对话串首条推文的 ID   |
| `in_reply_to_tweet_id` | string or null | 此推文所回复的推文 ID  |
| `in_reply_to_username` | string or null | 被回复账号的用户名     |
| `is_reply`             | boolean        | 此推文是否为回复      |
| `is_quote_status`      | boolean        | 此推文是否引用了另一条推文 |
| `is_replies_limited`   | boolean        | 作者是否限制了回复     |

**嵌套对象**

| 字段                 | 类型                   | 说明                |
| :----------------- | :------------------- | :---------------- |
| `user`             | User object          | 推文作者的完整资料         |
| `entities`         | array of TweetEntity | 媒体和链接附件           |
| `quoted_status`    | Tweet object or null | 被引用的推文（完整对象，递归）   |
| `retweeted_status` | Tweet object or null | 原始被转推的推文（完整对象，递归） |

`quoted_status` 和 `retweeted_status` 字段包含完整 Tweet 对象，包括各自的 `user`、`entities` 和互动指标。因此一次 API 调用即可获得全部相关数据，无需追加请求。

***

## TweetEntity 对象

`entities` 数组的每个元素表示推文中的媒体附件或嵌入链接。

```text theme={null}
{
  "type": "photo",
  "link": "https://pbs.twimg.com/media/..._large.jpg",
  "preview": "https://pbs.twimg.com/media/..._small.jpg"
}
```

| 字段        | 类型     | 说明                                     |
| :-------- | :----- | :------------------------------------- |
| `type`    | string | 实体类型，例如 `photo`、`video`、`animated_gif` |
| `link`    | string | 原始分辨率资源的直接 URL                         |
| `preview` | string | 预览文本或缩略图 URL                           |

***

## 基于游标的分页

支持分页的列表端点使用游标分页。批量查询和前面提到的加密货币分析列表不使用游标。对于不断新增内容的动态信息流，这种方式比基于偏移量的分页更可靠。

**工作流程：**

1. 首次请求不传游标。
2. 响应在返回数据的同时包含 `next_cursor` 字段。
3. 将 `next_cursor` 值放入下一个请求，以获取下一页。
4. `next_cursor` 为 `null` 或缺失时，表示已到达数据末尾。

**GET 端点**通过查询参数接收游标：

```text theme={null}
curl --request GET \
  --url 'https://api.sorsa.io/v3/followers?username=elonmusk&next_cursor=abc123' \
  --header 'ApiKey: YOUR_API_KEY'
```

**POST 端点**通过 JSON 请求体接收游标：

```text theme={null}
curl --request POST \
  --url 'https://api.sorsa.io/v3/search-tweets' \
  --header 'ApiKey: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{"query": "bitcoin", "next_cursor": "abc123"}'
```

**Python 示例：分页获取全部粉丝**

```text theme={null}
import time
import requests

API_KEY = "YOUR_API_KEY"
all_users = []
cursor = None

while True:
    params = {"username": "elonmusk"}
    if cursor:
        params["next_cursor"] = cursor

    response = requests.get(
        "https://api.sorsa.io/v3/followers",
        params=params,
        headers={"ApiKey": API_KEY},
        timeout=30,
    )
    response.raise_for_status()
    data = response.json()

    all_users.extend(data["users"])
    cursor = data.get("next_cursor")

    if not cursor:
        break

    time.sleep(0.05)  # respect rate limit

print(f"Fetched {len(all_users)} followers")
```

更多分页策略和性能建议请参阅[分页](https://docs.sorsa.io/zh-Hans/pagination)。

***

## 后续步骤

* [分页](https://docs.sorsa.io/zh-Hans/pagination)：高级分页方式与最佳实践
* [错误码](https://docs.sorsa.io/zh-Hans/error-codes)：错误响应的结构
* [API 参考](https://docs.sorsa.io/zh-Hans/api-reference-guide)：完整端点结构及请求、响应示例
