# Datos de X

Recupera perfiles de X, busca usuarios y publicaciones, y pagina cronologías y respuestas.

Elige la operación para los datos que necesitas. Los cinco endpoints usan POST y devuelven JSON en la raíz, sin un contenedor común `data`.

Todos los ejemplos usan `FELO_API_KEY` de la [vista general](https://openapi.felo.ai/es/docs/data-api/guides/felo-overview.md). Las llamadas usan **saldo de la plataforma**, no créditos Felo Pro. Los ejemplos de respuesta son ilustrativos; el contenido en vivo y los campos opcionales varían.

## Elige una operación

| Necesidad | Endpoint |
|---|---|
| Perfiles de nombres de usuario conocidos | `POST /api/v1/data/x/user/info` |
| Encontrar usuarios mediante una consulta de búsqueda | `POST /api/v1/data/x/user/search` |
| Publicaciones de un usuario | `POST /api/v1/data/x/user/tweets` |
| Publicaciones que coinciden con una consulta | `POST /api/v1/data/x/tweet/search` |
| Respuestas a publicaciones conocidas | `POST /api/v1/data/x/tweet/replies` |

## 1. Obtener perfiles de usuario

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

| Campo | Tipo | Requerido | Significado |
|---|---|---|---|
| `usernames` | arreglo de strings | Sí | De 1 a 100 nombres de usuario; envía los handles sin `@` |

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

La respuesta contiene `users` y `total`. Cada usuario incluye `user_id`, `username` y `display_name`; el texto del perfil, los conteos de seguidores, la verificación y otros metadatos también pueden estar presentes. Un lote puede devolver menos perfiles de los solicitados. Haz la coincidencia por nombre de usuario o ID, no por posición en el arreglo.

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

## 2. Buscar usuarios

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

| Campo | Tipo | Requerido | Significado |
|---|---|---|---|
| `query` | string | Sí | De 1 a 1.000 caracteres |
| `cursor` | string | No | Cursor de paginación, hasta 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"}'
```

La respuesta contiene `users`, `total`, `has_next` y `next_cursor`. No hay parámetro `limit` en esta operación.

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

## 3. Obtener la cronología de un usuario

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

| Campo | Tipo | Requerido | Significado |
|---|---|---|---|
| `username` | string | Se requiere un identificador | Handle del usuario, hasta 100 caracteres |
| `x_user_id` | string | Se requiere un identificador | ID del usuario, hasta 100 caracteres; tiene prioridad sobre `username` |
| `limit` | integer | No | De 1 a 1.000; la implementación actual usa al menos 20, con valor predeterminado 20 |
| `cursor` | string | No | Cursor de paginación, hasta 4.000 caracteres |
| `include_replies` | boolean | No | Incluye respuestas anidadas; valor predeterminado `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}'
```

La respuesta contiene `tweets`, `total`, `has_next` y `next_cursor`. Establecer `limit` por debajo de 20 no garantiza menos elementos devueltos ni una factura menor. Incluir respuestas puede añadir datos devueltos y resultados facturables.

### Límites de resultados y respuestas anidadas

`limit` es el número objetivo de publicaciones de nivel superior para esta solicitud, no un recuento de resultados garantizado. La implementación actual usa un objetivo de al menos 20: un objetivo de 20 lee una página upstream; objetivos mayores recuperan automáticamente hasta 50 páginas. Antes de cada página, comprueba el tiempo transcurrido y deja de recuperar más páginas una vez que supera los 60 segundos. Esta comprobación no garantiza que toda la solicitud HTTP termine en 60 segundos.

La recopilación también se detiene cuando se alcanza el objetivo, el upstream no tiene página siguiente, una página está vacía o falta el cursor. Por ello, una respuesta exitosa puede contener menos publicaciones que `limit`. Usa `has_next` y `next_cursor` para continuar cuando estén disponibles.

Con `include_replies=true`, cada publicación devuelta obtiene hasta 5 páginas extra y como máximo 100 respuestas anidadas. La recopilación puede detenerse antes si no hay página siguiente, una página está vacía o el cursor no puede avanzar. Estas respuestas anidadas están fuera del `limit` y `total` de nivel superior, pero pueden añadir resultados facturables.

Las `replies` anidadas no son un archivo completo de respuestas y no exponen un cursor de continuación separado para esta recopilación extra. Para paginar respuestas de forma independiente, usa la operación Leer respuestas y su cursor devuelto. No reutilices el cursor de publicaciones de nivel superior para las respuestas.

## 4. Buscar publicaciones

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

| Campo | Tipo | Requerido | Significado |
|---|---|---|---|
| `query` | string | Sí | Texto de búsqueda, de 1 a 1.000 caracteres |
| `query_type` | string | No | `Latest` (predeterminado) o `Top` |
| `limit` | integer | No | De 1 a 1.000; la implementación actual usa al menos 20, con valor predeterminado 20 |
| `cursor` | string | No | Cursor de paginación, hasta 4.000 caracteres |
| `since_time` | integer or string | No | Hora de inicio; usa segundos Unix para un valor numérico inequívoco |
| `until_time` | integer or string | No | Hora de fin; usa segundos Unix, no milisegundos |

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

La respuesta contiene `tweets`, `total`, `has_next` y `next_cursor`. Los objetos de publicación incluyen `id`, `content`, `author`, `created_at` y `metrics`; las respuestas y las publicaciones citadas o republicadas pueden estar anidadas. Trata los IDs como cadenas.

### Límites de recuento de resultados

`limit` es un objetivo, no una garantía. La implementación actual usa un objetivo de al menos 20: un objetivo de 20 lee una página upstream; objetivos mayores recuperan automáticamente hasta 50 páginas. El tiempo transcurrido se comprueba antes de cada página y no se recuperan más páginas una vez que supera los 60 segundos. Una solicitud upstream en curso aún puede tardar, por lo que esto no es un tiempo de espera HTTP global.

La recopilación también se detiene cuando se alcanza el objetivo, el upstream no tiene página siguiente, una página está vacía o falta el cursor. Devolver menos publicaciones que `limit` no significa que la solicitud falló o que se hayan recuperado todas las publicaciones coincidentes. Comprueba `has_next` y `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. Leer respuestas

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

| Campo | Tipo | Requerido | Significado |
|---|---|---|---|
| `tweet_ids` | string o arreglo de strings | Sí | Un ID de publicación o un lote de hasta 20 IDs |
| `cursor` | string | No | Hasta 4.000 caracteres; úsalo con un solo ID de publicación |
| `since_time` | integer | No | Hora de inicio en segundos Unix |
| `until_time` | integer | No | Hora de fin en segundos Unix |

Reemplaza el marcador de posición con un ID real de publicación:

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

A diferencia de la cronología y la búsqueda de publicaciones, las respuestas se agrupan bajo `results`. Cada entrada tiene su propio estado de paginación:

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

### Límites de respuestas por solicitud

Cada solicitud lee una página upstream de respuestas por cada `tweet_id` y conserva como máximo 100 respuestas; no recupera automáticamente cada página de respuestas. En un lote de hasta 20 IDs, el tope de 100 respuestas se aplica por separado a cada entrada de `results`. Los recuentos reales pueden ser menores.

El `total` de cada entrada es el número de respuestas devueltas en esa entrada, no el recuento completo de respuestas de la publicación. Para continuar, usa el `next_cursor` de esa entrada y envía solo su único ID de publicación en la siguiente solicitud. No existe un parámetro `limit` para aumentar el tope por solicitud.

## Paginación y control de costes

`total` cuenta el arreglo correspondiente en la respuesta actual: publicaciones de nivel superior para consultas de publicaciones, o respuestas dentro de cada entrada de resultado para consultas de respuestas. No es un recuento global de coincidencias, ni el recuento completo de respuestas de una publicación, ni el recuento final facturable.

1. Envía la primera solicitud sin `cursor`.
2. Lee `has_next` y `next_cursor` de la respuesta. Para respuestas, léelos en cada entrada de resultado.
3. Si existe otra página y el cursor no está vacío, envíalo sin cambios con la misma consulta. Para un lote de respuestas, continúa cada publicación por separado.
4. Detente cuando no haya página siguiente, cuando un cursor se repita o cuando se alcance tu propio límite de página o gasto.

Los metadatos de paginación reflejan la última respuesta upstream; la colección devuelta puede truncarse en un tope de resultados. Incluso `has_next=false` no garantiza que se haya recuperado todo el historial o las respuestas de X. Muestra el recuento real devuelto en lugar de etiquetar como todos los datos disponibles un conjunto de resultados limitado.

Cada página exitosa puede incurrir en un cargo. Estas cinco operaciones se facturan por resultados devueltos, no con una tarifa fija por solicitud. Las respuestas anidadas y otros registros devueltos pueden afectar el recuento facturado; no estimes el coste solo por la longitud del arreglo de nivel superior. Consulta los [precios actuales](https://openapi.felo.ai/api/v1/data/prices) y el uso en la consola. Los campos completos de los objetos están en el [esquema OpenAPI](https://openapi.felo.ai/api/v1/data/openapi.json).
