# Dados do X

Recupere perfis do X, pesquise usuários e posts e pagine timelines e respostas.

Escolha a operação para os dados de que você precisa. Os cinco endpoints usam POST e retornam JSON na raiz, sem um wrapper comum `data`.

Todos os exemplos usam `FELO_API_KEY` a partir da [visão geral](https://openapi.felo.ai/pt-BR/docs/data-api/guides/felo-overview.md). As chamadas usam **saldo da plataforma**, não créditos Pro da Felo. Os exemplos de resposta são ilustrativos; o conteúdo ao vivo e os campos opcionais variam.

## Escolha uma operação

| Necessidade | Endpoint |
|---|---|
| Perfis para nomes de usuário conhecidos | `POST /api/v1/data/x/user/info` |
| Encontrar usuários por uma consulta de busca | `POST /api/v1/data/x/user/search` |
| Posts de um usuário | `POST /api/v1/data/x/user/tweets` |
| Posts correspondentes a uma consulta | `POST /api/v1/data/x/tweet/search` |
| Respostas a posts conhecidos | `POST /api/v1/data/x/tweet/replies` |

## 1. Obter perfis de usuários

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

| Campo | Tipo | Obrigatório | Significado |
|---|---|---|---|
| `usernames` | array de strings | Sim | 1–100 nomes de usuário; envie handles sem `@` |

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

A resposta contém `users` e `total`. Cada usuário inclui `user_id`, `username` e `display_name`; texto do perfil, contagens de seguidores, verificação e outros metadados também podem estar presentes. Um lote pode retornar menos perfis do que o solicitado. Faça correspondência por nome de usuário ou ID, não pela posição no array.

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

## 2. Buscar usuários

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

| Campo | Tipo | Obrigatório | Significado |
|---|---|---|---|
| `query` | string | Sim | 1–1.000 caracteres |
| `cursor` | string | Não | Cursor de paginação, até 4.000 caracteres |

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

A resposta contém `users`, `total`, `has_next` e `next_cursor`. Não há parâmetro `limit` nesta operação.

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

## 3. Obter a timeline de um usuário

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

| Campo | Tipo | Obrigatório | Significado |
|---|---|---|---|
| `username` | string | Um identificador obrigatório | Handle do usuário, até 100 caracteres |
| `x_user_id` | string | Um identificador obrigatório | ID do usuário, até 100 caracteres; tem precedência sobre `username` |
| `limit` | integer | Não | 1–1.000; a implementação atual usa no mínimo 20, com padrão 20 |
| `cursor` | string | Não | Cursor de paginação, até 4.000 caracteres |
| `include_replies` | boolean | Não | Inclui respostas aninhadas; padrão `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}'
```

A resposta contém `tweets`, `total`, `has_next` e `next_cursor`. Definir `limit` abaixo de 20 não garante menos itens retornados nem uma cobrança menor. Incluir respostas pode adicionar dados retornados e resultados cobrados.

### Limites de resultados e respostas aninhadas

`limit` é a quantidade-alvo de posts de nível superior para esta solicitação, não uma contagem garantida de resultados. A implementação atual usa uma meta de no mínimo 20: uma meta de 20 lê uma página upstream; metas maiores buscam automaticamente até 50 páginas. Antes de cada página, ela verifica o tempo decorrido e interrompe a busca por páginas adicionais assim que ele ultrapassa 60 segundos. Essa verificação não é uma garantia de que toda a solicitação HTTP será concluída em 60 segundos.

A coleta também para quando a meta é atingida, o upstream não tem próxima página, uma página está vazia ou o cursor está ausente. Uma resposta bem-sucedida pode, portanto, conter menos posts do que `limit`. Use `has_next` e `next_cursor` para continuar quando disponíveis.

Com `include_replies=true`, cada post retornado recebe até 5 páginas extras e no máximo 100 respostas aninhadas. A coleta pode parar antes quando não houver próxima página, uma página estiver vazia ou o cursor não puder avançar. Essas respostas aninhadas ficam fora do `limit` e do `total` de nível superior, mas podem adicionar resultados cobrados.

As `replies` aninhadas não são um arquivo completo de respostas e não expõem um cursor de continuação separado para essa coleta extra. Para paginar respostas independentemente, use a operação Ler respostas e o cursor retornado por ela. Não reutilize o cursor do post de nível superior para respostas.

## 4. Buscar posts

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

| Campo | Tipo | Obrigatório | Significado |
|---|---|---|---|
| `query` | string | Sim | Texto de busca, 1–1.000 caracteres |
| `query_type` | string | Não | `Latest` (padrão) ou `Top` |
| `limit` | integer | Não | 1–1.000; a implementação atual usa no mínimo 20, com padrão 20 |
| `cursor` | string | Não | Cursor de paginação, até 4.000 caracteres |
| `since_time` | integer or string | Não | Hora de início; use segundos Unix para um valor numérico inequívoco |
| `until_time` | integer or string | Não | Hora de término; use segundos Unix, não milissegundos |

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

A resposta contém `tweets`, `total`, `has_next` e `next_cursor`. Os objetos de post incluem `id`, `content`, `author`, `created_at` e `metrics`; respostas e posts citados/retuitados podem estar aninhados. Trate os IDs como strings.

### Limites de quantidade de resultados

`limit` é uma meta, não uma garantia. A implementação atual usa uma meta de no mínimo 20: uma meta de 20 lê uma página upstream; metas maiores buscam automaticamente até 50 páginas. O tempo decorrido é verificado antes de cada página, e nenhuma página adicional é buscada quando ele ultrapassa 60 segundos. Uma solicitação upstream em andamento ainda pode levar tempo, então isso não é um timeout HTTP geral.

A coleta também para quando a meta é atingida, o upstream não tem próxima página, uma página está vazia ou o cursor está ausente. Retornar menos posts do que `limit` não significa que a solicitação falhou ou que cada post correspondente foi recuperado. Verifique `has_next` e `next_cursor` antes de continuar.

```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. Ler respostas

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

| Campo | Tipo | Obrigatório | Significado |
|---|---|---|---|
| `tweet_ids` | string ou array de strings | Sim | Um ID de post ou um lote de até 20 IDs |
| `cursor` | string | Não | Até 4.000 caracteres; use com um único ID de post |
| `since_time` | integer | Não | Hora de início em segundos Unix |
| `until_time` | integer | Não | Hora de término em segundos Unix |

Substitua o espaço reservado por um ID real de post:

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

Ao contrário da timeline e da busca de posts, as respostas são agrupadas em `results`. Cada entrada tem seu próprio estado de paginação:

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

### Limites de respostas por solicitação

Cada solicitação lê uma página upstream de respostas por `tweet_id` e mantém no máximo 100 respostas; ela não busca automaticamente todas as páginas de respostas. Em um lote de até 20 IDs, o limite de 100 respostas se aplica separadamente a cada entrada `results`. As contagens reais podem ser menores.

O `total` de cada entrada é o número de respostas retornadas nessa entrada, não a contagem completa de respostas do post. Para continuar, use o `next_cursor` dessa entrada e envie apenas o ID do post único na próxima solicitação. Não há parâmetro `limit` para aumentar o teto por solicitação.

## Paginação e controle de custo

`total` conta o array correspondente na resposta atual: posts de nível superior para consultas de post, ou respostas dentro de cada entrada de resultado para consultas de respostas. Ele não é uma contagem global de correspondências, nem a contagem completa de respostas de um post, nem a contagem final cobrável.

1. Envie a primeira solicitação sem `cursor`.
2. Leia `has_next` e `next_cursor` da resposta. Para respostas, leia-os em cada entrada de resultado.
3. Se houver outra página e o cursor não estiver vazio, envie-o inalterado com a mesma consulta. Para um lote de respostas, continue cada post separadamente.
4. Pare quando não houver próxima página, quando um cursor se repetir ou quando seu próprio limite de páginas ou de gastos for atingido.

Os metadados de paginação refletem a última resposta upstream; a coleção retornada pode ser truncada por um limite de resultados. Mesmo `has_next=false` não é garantia de que todo o histórico do X ou todas as respostas foram recuperados. Exiba a contagem real retornada em vez de rotular um conjunto de resultados limitado como todos os dados disponíveis.

Cada página bem-sucedida pode gerar uma cobrança. Essas cinco operações são cobradas por resultados retornados, não por uma taxa fixa por solicitação. Respostas aninhadas e outros registros retornados podem afetar a contagem cobrada; não estime o custo apenas pelo tamanho do array de nível superior. Consulte os [preços atuais](https://openapi.felo.ai/api/v1/data/prices) e o uso no console. Os campos completos dos objetos estão no [esquema OpenAPI](https://openapi.felo.ai/api/v1/data/openapi.json).
