# X 데이터

X 프로필을 가져오고, 사용자를 검색하고, 게시물과 답글을 페이지네이션하며 조회합니다.

필요한 데이터에 맞는 작업을 선택하세요. 이 다섯 개의 엔드포인트는 모두 POST를 사용하며, 공통 `data` 래퍼 없이 JSON을 루트에서 반환합니다.

모든 예시는 [개요](https://openapi.felo.ai/ko/docs/data-api/guides/felo-overview.md)의 `FELO_API_KEY`를 사용합니다. 호출은 Felo Pro 크레딧이 아니라 **플랫폼 잔액**을 사용합니다. 응답 예시는 설명용이며, 실제 콘텐츠와 선택적 필드는 달라질 수 있습니다.

## 작업 선택하기

| 필요 | 엔드포인트 |
|---|---|
| 알려진 사용자명에 대한 프로필 | `POST /api/v1/data/x/user/info` |
| 검색 쿼리로 사용자 찾기 | `POST /api/v1/data/x/user/search` |
| 한 사용자의 게시물 | `POST /api/v1/data/x/user/tweets` |
| 쿼리와 일치하는 게시물 | `POST /api/v1/data/x/tweet/search` |
| 알려진 게시물에 대한 답글 | `POST /api/v1/data/x/tweet/replies` |

## 1. 사용자 프로필 가져오기

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

| 필드 | 유형 | 필수 | 의미 |
|---|---|---|---|
| `usernames` | string array | 예 | 1–100개의 사용자명; `@` 없이 핸들을 보내세요 |

```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"]}'
```

응답에는 `users`와 `total`이 포함됩니다. 각 사용자는 `user_id`, `username`, `display_name`을 포함하며, 프로필 텍스트, 팔로워 수, 인증 여부 및 기타 메타데이터도 있을 수 있습니다. 한 배치에서 요청한 수보다 적은 프로필이 반환될 수 있습니다. 배열 위치가 아니라 사용자명 또는 ID로 일치시키세요.

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

## 2. 사용자 검색

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

| 필드 | 유형 | 필수 | 의미 |
|---|---|---|---|
| `query` | string | 예 | 1–1,000자 |
| `cursor` | string | 아니오 | 페이지네이션 커서, 최대 4,000자 |

```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"}'
```

응답에는 `users`, `total`, `has_next`, `next_cursor`가 포함됩니다. 이 작업에는 `limit` 매개변수가 없습니다.

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

## 3. 사용자 타임라인 가져오기

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

| 필드 | 유형 | 필수 | 의미 |
|---|---|---|---|
| `username` | string | 식별자 1개 필요 | 사용자 핸들, 최대 100자 |
| `x_user_id` | string | 식별자 1개 필요 | 사용자 ID, 최대 100자; `username`보다 우선합니다 |
| `limit` | integer | 아니오 | 1–1,000; 현재 구현은 최소 20을 사용하며 기본값은 20 |
| `cursor` | string | 아니오 | 페이지네이션 커서, 최대 4,000자 |
| `include_replies` | boolean | 아니오 | 중첩 답글 포함; 기본값 `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}'
```

응답에는 `tweets`, `total`, `has_next`, `next_cursor`가 포함됩니다. `limit`을 20 미만으로 설정해도 반환 항목 수가 줄거나 요금이 줄어든다는 보장은 없습니다. 답글을 포함하면 반환 데이터와 과금 대상 결과가 늘어날 수 있습니다.

### 결과 및 중첩 답글 제한

`limit`은 이 요청의 상위 게시물 목표 수이며, 보장된 결과 수가 아닙니다. 현재 구현은 최소 20의 목표를 사용합니다. 목표가 20이면 상위 1개 페이지를 읽고, 더 큰 목표는 최대 50페이지까지 자동으로 가져옵니다. 각 페이지를 읽기 전에 경과 시간을 확인하며, 60초를 초과하면 더 이상 페이지를 가져오지 않습니다. 이 검사는 전체 HTTP 요청이 60초 안에 끝난다는 보장은 아닙니다.

수집은 목표에 도달했거나, 상위 계층에 다음 페이지가 없거나, 페이지가 비어 있거나, 커서가 없을 때도 중단됩니다. 따라서 성공 응답에 `limit`보다 적은 게시물이 포함될 수 있습니다. 계속 진행할 수 있는 경우 `has_next`와 `next_cursor`를 사용하세요.

`include_replies=true`이면, 반환된 각 게시물마다 최대 5개의 추가 페이지와 최대 100개의 중첩 답글이 포함됩니다. 다음 페이지가 없거나, 페이지가 비어 있거나, 커서가 더 이상 진행할 수 없을 때 더 일찍 중단될 수 있습니다. 이러한 중첩 답글은 상위 수준의 `limit`과 `total` 범위 밖이지만, 과금 대상 결과를 늘릴 수 있습니다.

중첩 `replies`는 완전한 답글 아카이브가 아니며, 이 추가 수집용 별도 continuation cursor를 제공하지 않습니다. 답글을 독립적으로 페이지네이션하려면 Read replies 작업과 해당 반환 커서를 사용하세요. 답글에는 상위 게시물 커서를 재사용하지 마세요.

## 4. 게시물 검색

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

| 필드 | 유형 | 필수 | 의미 |
|---|---|---|---|
| `query` | string | 예 | 검색 텍스트, 1–1,000자 |
| `query_type` | string | 아니오 | `Latest`(기본값) 또는 `Top` |
| `limit` | integer | 아니오 | 1–1,000; 현재 구현은 최소 20을 사용하며 기본값은 20 |
| `cursor` | string | 아니오 | 페이지네이션 커서, 최대 4,000자 |
| `since_time` | integer or string | 아니오 | 시작 시간; 모호하지 않은 숫자 값을 위해 Unix 초를 사용하세요 |
| `until_time` | integer or string | 아니오 | 종료 시간; 밀리초가 아니라 Unix 초를 사용하세요 |

```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}'
```

응답에는 `tweets`, `total`, `has_next`, `next_cursor`가 포함됩니다. 게시물 객체에는 `id`, `content`, `author`, `created_at`, `metrics`가 포함되며, 답글과 인용/리트윗된 게시물이 중첩될 수 있습니다. ID는 문자열로 취급하세요.

### 결과 수 제한

`limit`은 보장값이 아니라 목표값입니다. 현재 구현은 최소 20의 목표를 사용합니다. 목표가 20이면 상위 1개 페이지를 읽고, 더 큰 목표는 최대 50페이지까지 자동으로 가져옵니다. 각 페이지를 읽기 전에 경과 시간을 확인하며, 60초를 초과하면 더 이상 페이지를 가져오지 않습니다. 진행 중인 상위 요청은 여전히 시간이 걸릴 수 있으므로, 이는 전체 HTTP 타임아웃이 아닙니다.

수집은 목표에 도달했거나, 상위 계층에 다음 페이지가 없거나, 페이지가 비어 있거나, 커서가 없을 때도 중단됩니다. `limit`보다 적은 게시물을 반환했다고 해서 요청이 실패한 것은 아니며, 모든 일치 게시물을 가져왔다는 뜻도 아닙니다. 계속하기 전에 `has_next`와 `next_cursor`를 확인하세요.

```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. 답글 읽기

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

| 필드 | 유형 | 필수 | 의미 |
|---|---|---|---|
| `tweet_ids` | string or string array | 예 | 게시물 ID 1개 또는 최대 20개 ID 배치 |
| `cursor` | string | 아니오 | 최대 4,000자; 게시물 ID 1개와 함께 사용 |
| `since_time` | integer | 아니오 | Unix 초 단위 시작 시간 |
| `until_time` | integer | 아니오 | Unix 초 단위 종료 시간 |

플레이스홀더를 실제 게시물 ID로 바꾸세요:

```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"]}'
```

타임라인 및 게시물 검색과 달리, 답글은 `results` 아래에 그룹화됩니다. 각 항목은 자체 페이지네이션 상태를 가집니다:

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

### 요청당 답글 제한

각 요청은 `tweet_id`당 상위 답글 페이지 1개를 읽고 최대 100개의 답글만 보존합니다. 모든 답글 페이지를 자동으로 가져오지는 않습니다. 최대 20개 ID 배치에서 100개 답글 제한은 각 `results` 항목에 별도로 적용됩니다. 실제 개수는 더 적을 수 있습니다.

각 항목의 `total`은 해당 항목에서 반환된 답글 수이며, 게시물의 전체 답글 수가 아닙니다. 계속하려면 해당 항목의 `next_cursor`를 사용하고, 다음 요청에는 그 단일 게시물 ID만 보내세요. 요청당 상한을 늘리는 `limit` 매개변수는 없습니다.

## 페이지네이션 및 비용 제어

`total`은 현재 응답의 해당 배열 수를 의미합니다. 게시물 쿼리에서는 최상위 게시물 수이고, 답글 쿼리에서는 각 결과 항목 내의 답글 수입니다. 전역 일치 수도 아니고, 게시물의 전체 답글 수도 아니며, 최종 과금 대상 수도 아닙니다.

1. `cursor` 없이 첫 요청을 보내세요.
2. 응답에서 `has_next`와 `next_cursor`를 읽으세요. 답글의 경우 각 결과 항목에서 읽으세요.
3. 다음 페이지가 있고 커서가 비어 있지 않으면, 같은 쿼리로 변경하지 않고 그대로 보내세요. 답글 배치의 경우 각 게시물을 별도로 계속하세요.
4. 다음 페이지가 없거나, 커서가 반복되거나, 자체 페이지 또는 지출 한도에 도달하면 중단하세요.

페이지네이션 메타데이터는 마지막 상위 응답을 반영하며, 반환된 컬렉션은 결과 상한에서 잘릴 수 있습니다. `has_next=false`라도 모든 X 기록이나 답글을 모두 가져왔다는 보장은 아닙니다. 제한된 결과 집합을 가능한 모든 데이터로 표시하지 말고, 실제 반환 수를 표시하세요.

성공한 각 페이지에는 요금이 발생할 수 있습니다. 이 다섯 작업은 고정 요청 요금이 아니라 반환 결과 기준으로 과금됩니다. 중첩 답글 및 기타 반환 레코드는 과금 대상 수에 영향을 줄 수 있으므로, 최상위 배열 길이만으로 비용을 추정하지 마세요. [현재 가격](https://openapi.felo.ai/api/v1/data/prices)과 콘솔의 사용량을 확인하세요. 완전한 객체 필드는 [OpenAPI 스키마](https://openapi.felo.ai/api/v1/data/openapi.json)에 있습니다.
