> ## 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`のような値です。他の日付フィールドは各エンドポイントのスキーマを確認してください。確認結果やフォロー関係の日付も同じ形式とは限りません。

**真偽値は厳密なbooleanです。** `verified`、`is_reply`、`protected`、`can_dm`などの状態フラグは必ず`true`または`false`で、`0`・`1`や文字列の`"true"`・`"false"`ではありません。

**nullと欠落フィールド。** 任意フィールドは慎重に扱い、値がない場合と、実際に測定された0や`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`がありません。1回のレスポンスで結果全体を返します。

***

## 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                  | DMを受け付けているか             |
| `protected`                    | boolean                  | アカウントが非公開か              |
| `possibly_sensitive`           | boolean                  | センシティブなアカウントとして指定されているか |

***

## Followerオブジェクト

Followerオブジェクトは、Userオブジェクトにフィールドを1つ追加したものです。`/new-followers-7d`、`/new-following-7d`、`/top-following`で返されます。`/top-followers`は、`score`を持つ別の簡略モデルを返します。

| 追加フィールド        | 型      | 説明             |
| :------------- | :----- | :------------- |
| `followerDate` | string | フォロー関係が記録された日付 |

***

## Tweetオブジェクト

Tweetオブジェクトには、1件のツイートの全文、メタデータ、エンゲージメント指標、ネストされた関連情報が含まれます。`/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`には、それぞれの`user`、`entities`、エンゲージメント指標を含む完全なTweetオブジェクトが入ります。そのため追加のリクエストを送らず、1回の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/ja/pagination)を参照してください。

***

## 次のステップ

* [ページネーション](https://docs.sorsa.io/ja/pagination)：高度な実装パターンと推奨事項
* [エラーコード](https://docs.sorsa.io/ja/error-codes)：エラーレスポンスの構造
* [APIリファレンス](https://docs.sorsa.io/ja/api-reference-guide)：リクエストとレスポンスの例を含む全エンドポイントのスキーマ
