# Data X

Ambil profil X, cari pengguna dan postingan, serta lakukan paginasi pada linimasa dan balasan.

Pilih operasi untuk data yang Anda butuhkan. Kelima endpoint menggunakan POST dan mengembalikan JSON di root, tanpa pembungkus `data` bersama.

Semua contoh menggunakan `FELO_API_KEY` dari [gambaran umum](https://openapi.felo.ai/id/docs/data-api/guides/felo-overview.md). Panggilan menggunakan **saldo platform**, bukan kredit Felo Pro. Contoh respons bersifat ilustratif; konten langsung dan bidang opsional bervariasi.

## Pilih operasi

| Kebutuhan | Endpoint |
|---|---|
| Profil untuk username yang diketahui | `POST /api/v1/data/x/user/info` |
| Temukan pengguna berdasarkan kueri pencarian | `POST /api/v1/data/x/user/search` |
| Postingan dari satu pengguna | `POST /api/v1/data/x/user/tweets` |
| Postingan yang cocok dengan kueri | `POST /api/v1/data/x/tweet/search` |
| Balasan ke postingan yang diketahui | `POST /api/v1/data/x/tweet/replies` |

## 1. Dapatkan profil pengguna

`POST /api/v1/data/x/user/info`

| Bidang | Tipe | Wajib | Arti |
|---|---|---|---|
| `usernames` | string array | Ya | 1–100 username; kirim handle tanpa `@` |

```bash
curl -sS --request POST "https://openapi.felo.ai/api/v1/data/x/user/info" \
  -H "Authorization: Bearer $FELO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"usernames":["OpenAI"]}'
```

Respons berisi `users` dan `total`. Setiap pengguna mencakup `user_id`, `username`, dan `display_name`; teks profil, jumlah pengikut, verifikasi, dan metadata lain juga mungkin ada. Satu batch dapat mengembalikan lebih sedikit profil daripada yang diminta. Cocokkan berdasarkan username atau ID, bukan berdasarkan posisi array.

```json
{"users":[{"user_id":"example-user-id","username":"example","display_name":"Example"}],"total":1}
```

## 2. Cari pengguna

`POST /api/v1/data/x/user/search`

| Bidang | Tipe | Wajib | Arti |
|---|---|---|---|
| `query` | string | Ya | 1–1.000 karakter |
| `cursor` | string | Tidak | Cursor paginasi, hingga 4.000 karakter |

```bash
curl -sS --request POST "https://openapi.felo.ai/api/v1/data/x/user/search" \
  -H "Authorization: Bearer $FELO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"AI research"}'
```

Respons berisi `users`, `total`, `has_next`, dan `next_cursor`. Tidak ada parameter `limit` pada operasi ini.

```json
{"users":[],"total":0,"has_next":false,"next_cursor":null}
```

## 3. Dapatkan linimasa pengguna

`POST /api/v1/data/x/user/tweets`

| Bidang | Tipe | Wajib | Arti |
|---|---|---|---|
| `username` | string | Satu pengenal wajib | Handle pengguna, hingga 100 karakter |
| `x_user_id` | string | Satu pengenal wajib | ID pengguna, hingga 100 karakter; didahulukan di atas `username` |
| `limit` | integer | Tidak | 1–1.000; implementasi saat ini menggunakan setidaknya 20, dengan default 20 |
| `cursor` | string | Tidak | Cursor paginasi, hingga 4.000 karakter |
| `include_replies` | boolean | Tidak | Sertakan balasan bertingkat; default `false` |

```bash
curl -sS --request POST "https://openapi.felo.ai/api/v1/data/x/user/tweets" \
  -H "Authorization: Bearer $FELO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"username":"OpenAI","limit":20,"include_replies":false}'
```

Respons berisi `tweets`, `total`, `has_next`, dan `next_cursor`. Menetapkan `limit` di bawah 20 tidak menjamin lebih sedikit item yang dikembalikan atau tagihan yang lebih kecil. Menyertakan balasan dapat menambah data yang dikembalikan dan hasil yang dapat ditagihkan.

### Batas hasil dan balasan bertingkat

`limit` adalah jumlah target postingan tingkat atas untuk permintaan ini, bukan jumlah hasil yang dijamin. Implementasi saat ini menggunakan target minimal 20: target 20 membaca satu halaman upstream; target yang lebih besar otomatis mengambil hingga 50 halaman. Sebelum setiap halaman, waktu berlalu diperiksa dan pengambilan halaman berikutnya berhenti setelah melebihi 60 detik. Pemeriksaan ini bukan jaminan bahwa seluruh permintaan HTTP selesai dalam 60 detik.

Pengumpulan juga berhenti ketika target tercapai, upstream tidak memiliki halaman berikutnya, sebuah halaman kosong, atau cursor tidak ada. Karena itu, respons sukses dapat berisi lebih sedikit postingan daripada `limit`. Gunakan `has_next` dan `next_cursor` untuk melanjutkan saat tersedia.

Dengan `include_replies=true`, setiap postingan yang dikembalikan mendapatkan hingga 5 halaman tambahan dan paling banyak 100 balasan bertingkat. Pengumpulan dapat berhenti lebih awal ketika tidak ada halaman berikutnya, sebuah halaman kosong, atau cursor tidak dapat maju. Balasan bertingkat ini berada di luar `limit` dan `total` tingkat atas, tetapi dapat menambah hasil yang dapat ditagihkan.

`replies` bertingkat bukan arsip balasan yang lengkap dan tidak mengekspos cursor kelanjutan terpisah untuk pengumpulan tambahan ini. Untuk melakukan paginasi balasan secara independen, gunakan operasi Baca balasan dan cursor yang dikembalikannya. Jangan gunakan kembali cursor postingan tingkat atas untuk balasan.

## 4. Cari postingan

`POST /api/v1/data/x/tweet/search`

| Bidang | Tipe | Wajib | Arti |
|---|---|---|---|
| `query` | string | Ya | Teks pencarian, 1–1.000 karakter |
| `query_type` | string | Tidak | `Latest` (default) atau `Top` |
| `limit` | integer | Tidak | 1–1.000; implementasi saat ini menggunakan setidaknya 20, dengan default 20 |
| `cursor` | string | Tidak | Cursor paginasi, hingga 4.000 karakter |
| `since_time` | integer or string | Tidak | Waktu mulai; gunakan detik Unix untuk nilai numerik yang tidak ambigu |
| `until_time` | integer or string | Tidak | Waktu akhir; gunakan detik Unix, bukan milidetik |

```bash
curl -sS --request POST "https://openapi.felo.ai/api/v1/data/x/tweet/search" \
  -H "Authorization: Bearer $FELO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"retrieval augmented generation","query_type":"Latest","limit":20}'
```

Respons berisi `tweets`, `total`, `has_next`, dan `next_cursor`. Objek post mencakup `id`, `content`, `author`, `created_at`, dan `metrics`; balasan serta post yang dikutip/di-retweet dapat bersarang. Perlakukan ID sebagai string.

### Batas jumlah hasil

`limit` adalah target, bukan jaminan. Implementasi saat ini menggunakan target minimal 20: target 20 membaca satu halaman upstream; target yang lebih besar otomatis mengambil hingga 50 halaman. Waktu berlalu diperiksa sebelum setiap halaman, dan tidak ada halaman tambahan yang diambil setelah melebihi 60 detik. Permintaan upstream yang sedang berlangsung masih dapat memakan waktu, jadi ini bukan batas waktu HTTP secara keseluruhan.

Pengumpulan juga berhenti ketika target tercapai, upstream tidak memiliki halaman berikutnya, sebuah halaman kosong, atau cursor tidak ada. Mengembalikan postingan lebih sedikit daripada `limit` tidak berarti permintaan gagal atau setiap postingan yang cocok telah diambil. Periksa `has_next` dan `next_cursor` sebelum melanjutkan.

```json
{
  "tweets": [{
    "id":"example-post-id",
    "content":"Example post content",
    "author":{"user_id":"example-user-id","username":"example","display_name":"Example"},
    "created_at":"2026-11-01T00:00:00Z",
    "metrics":{},
    "replies":[]
  }],
  "total":1,
  "has_next":false,
  "next_cursor":null
}
```

## 5. Baca balasan

`POST /api/v1/data/x/tweet/replies`

| Bidang | Tipe | Wajib | Arti |
|---|---|---|---|
| `tweet_ids` | string atau string array | Ya | Satu ID postingan atau batch hingga 20 ID |
| `cursor` | string | Tidak | Hingga 4.000 karakter; gunakan dengan satu ID postingan |
| `since_time` | integer | Tidak | Waktu mulai dalam detik Unix |
| `until_time` | integer | Tidak | Waktu akhir dalam detik Unix |

Ganti placeholder dengan ID postingan yang nyata:

```bash
curl -sS --request POST "https://openapi.felo.ai/api/v1/data/x/tweet/replies" \
  -H "Authorization: Bearer $FELO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tweet_ids":["POST_ID"]}'
```

Berbeda dengan linimasa dan pencarian postingan, balasan dikelompokkan di bawah `results`. Setiap entri memiliki status paginasi sendiri:

```json
{"results":[{"tweet_id":"POST_ID","replies":[],"total":0,"has_next":false,"next_cursor":null}]}
```

### Batas balasan per permintaan

Setiap permintaan membaca satu halaman balasan upstream per `tweet_id` dan mempertahankan paling banyak 100 balasan; permintaan ini tidak secara otomatis mengambil setiap halaman balasan. Dalam batch hingga 20 ID, batas 100 balasan diterapkan secara terpisah pada setiap entri `results`. Jumlah aktual bisa lebih rendah.

`total` setiap entri adalah jumlah balasan yang dikembalikan dalam entri tersebut, bukan jumlah balasan lengkap post. Untuk melanjutkan, gunakan `next_cursor` dari entri itu dan kirim hanya ID postingan tunggalnya pada permintaan berikutnya. Tidak ada parameter `limit` untuk meningkatkan batas per permintaan.

## Paginasi dan pengendalian biaya

`total` menghitung array yang bersesuaian dalam respons saat ini: postingan tingkat atas untuk kueri post, atau balasan di dalam setiap entri hasil untuk kueri balasan. Ini bukan jumlah kecocokan global, bukan jumlah balasan lengkap sebuah post, dan bukan jumlah billable final.

1. Kirim permintaan pertama tanpa `cursor`.
2. Baca `has_next` dan `next_cursor` dari respons. Untuk balasan, baca pada setiap entri hasil.
3. Jika ada halaman lain dan cursor tidak kosong, kirim ulang tanpa perubahan dengan kueri yang sama. Untuk batch balasan, lanjutkan setiap post secara terpisah.
4. Hentikan ketika tidak ada halaman berikutnya, ketika cursor berulang, atau ketika batas halaman atau pengeluaran Anda sendiri tercapai.

Metadata paginasi mencerminkan respons upstream terakhir; koleksi yang dikembalikan dapat dipotong pada batas hasil. Bahkan `has_next=false` bukan jaminan bahwa semua histori X atau balasan telah diambil. Tampilkan jumlah aktual yang dikembalikan, bukan memberi label kumpulan hasil terbatas sebagai semua data yang tersedia.

Setiap halaman sukses dapat menimbulkan biaya. Kelima operasi ini ditagihkan berdasarkan hasil yang dikembalikan, bukan biaya permintaan tetap. Balasan bertingkat dan rekaman lain yang dikembalikan dapat memengaruhi jumlah yang ditagihkan; jangan perkirakan biaya hanya dari panjang array tingkat atas. Periksa [harga terkini](https://openapi.felo.ai/api/v1/data/prices) dan penggunaan di konsol. Bidang objek lengkap ada di [skema OpenAPI](https://openapi.felo.ai/api/v1/data/openapi.json).
