Una API de búsqueda de Twitter gratuita que devuelve JSON, con los operadores de búsqueda de X

Una API de búsqueda de Twitter gratuita que devuelve JSON, con los operadores de búsqueda de X
Unif Cookbooks team
Unif Cookbooks team

Actualizado

Busca posts públicos recientes de X como JSON desde un script o agente AI sin API key: el endpoint, los operadores que funcionan, paginación y límites.

En resumen: GET https://unifapi.com/tools/x/search?q=<consulta> devuelve en JSON las publicaciones públicas de X que coinciden con una consulta. Es gratis, sin iniciar sesión, sin necesidad de cuenta ni clave de API, y con límite por visitante. Los operadores de búsqueda de X funcionan en q: from:, to:, since:, until:, min_faves:, min_retweets:, filter:media, filter:links, -filter:replies, lang: y frases entre comillas. Los resultados llegan de 20 en 20, los más recientes primero, con un nextCursor para paginar. El límite gratuito es de 20 unidades cada 10 minutos por visitante, impreso en los encabezados X-RateLimit-*, y una búsqueda cuesta 2 unidades porque es la llamada más cara aguas arriba, así que son 10 búsquedas. Sin fechas obtienes las publicaciones más recientes; añade since: y until: y la misma búsqueda llega hasta 2006.

De todo lo que la gente quiere de X sin cuenta (y que busca como "buscar tweets sin cuenta", "api de búsqueda de twitter gratis" o "buscar en twitter sin iniciar sesión"), la búsqueda es lo único que no tiene una buena respuesta gratuita. Las APIs de vistas previas de enlaces (FxTwitter, vxTwitter) leen publicaciones sueltas. El endpoint de sindicación lee publicaciones sueltas. Nitter tenía búsqueda, y la mayoría de las instancias públicas de Nitter han desaparecido o están bloqueadas por motivos legales. Quedaba o bien una cuenta de desarrollador con un plan de pago, o bien un navegador headless manejando x.com/search, que es lento, frágil y va contra los términos.

Esto es lo que hace el endpoint de búsqueda gratuito, cómo consultarlo y dónde se detiene.

La solicitud

curl -s "https://unifapi.com/tools/x/search?q=from%3Anasa%20filter%3Amedia"
{
  "query": "from:nasa filter:media",
  "posts": {
    "items": [
      {
        "id": "2107566197579341846",
        "text": "After delivering science and supplies to the @Space_Station earlier this year, Northrop Grumman's Cygnus XL cargo spacecraft is scheduled to depart on Friday…",
        "createdAt": "2026-10-06T20:18:32.000Z",
        "url": "https://x.com/NASA/status/2107566197579341846",
        "author": { "handle": "NASA", "name": "NASA", "verified": true, "followers": 92373839 },
        "metrics": {
          "likes": 2195,
          "reposts": 302,
          "replies": 114,
          "quotes": 20,
          "bookmarks": 104,
          "views": 1520159
        },
        "media": [
          {
            "kind": "photo",
            "url": "https://pbs.twimg.com/media/…jpg",
            "width": 1920,
            "height": 1280
          }
        ]
      }
    ],
    "hasMore": true,
    "nextCursor": "DAACCgACHUAq4qFAJxAKAAMd…"
  }
}

La misma solicitud en la página para personas es https://unifapi.com/tools/x-search?q=from:nasa filter:media, y añadir &format=json a esa URL devuelve el JSON de arriba. Añade format=md en su lugar, o envía Accept: text/markdown, para obtener las publicaciones en Markdown, que cabe mejor en la ventana de contexto de un modelo que el JSON.

Operadores que funcionan

La consulta va a la búsqueda de X tal cual se escribe, así que los operadores que X documenta para su propio cuadro de búsqueda funcionan aquí. Estos son los que más usamos:

OperadorEjemploQué hace
from:from:nasaPublicaciones de una cuenta
to:to:nasaRespuestas dirigidas a una cuenta
@handle@nasaPublicaciones que mencionan a una cuenta
#tag#Formula1Publicaciones con un hashtag
"phrase""crew-12"Frase exacta
since: / until:since:2026-10-01Límites de fecha (días completos)
min_faves:min_faves:100Al menos N me gusta
min_retweets:min_retweets:50Al menos N reposts
filter:mediafrom:nasa filter:mediaSolo publicaciones con fotos o video
filter:linksfilter:linksSolo publicaciones con un enlace
-filter:replies#Formula1 -filter:repliesExcluir respuestas
-filter:retweetsfrom:nasa -filter:retweetsExcluir reposts
lang:lang:jaCódigo de idioma
ORnasa OR esaCualquiera de los dos términos

Se combinan. "Publicaciones de la NASA de la última semana con al menos 100 me gusta y una foto, sin respuestas" es:

from:nasa since:2026-09-30 min_faves:100 filter:media -filter:replies

La página de búsqueda tiene un filtro para cada uno de los cinco más habituales (cuenta, fecha, me gusta, medios, respuestas) e imprime la consulta que construyen, que es la misma cadena que recibe la API.

Más recientes, no Destacados

La búsqueda de X tiene dos ordenaciones: "Destacados" (Top), que mezcla relevancia y antigüedad y sin ningún reparo abre con una publicación de 2009, y "Más recientes" (Latest), estrictamente las más nuevas primero. El endpoint gratuito pide "Más recientes". Para monitorizar, para las reacciones a un evento y para cualquier cosa con un límite since:, es la que quieres. Si quieres "las publicaciones con más me gusta sobre X esta semana", ordena tú mismo los resultados de "Más recientes" por metrics.likes o añade min_faves: para recortar la cola.

Paginación

Toda lista de la API gratuita es { items, hasMore, nextCursor }. Para continuar, devuelve el cursor:

curl -s "https://unifapi.com/tools/x/search?q=%23Formula1&cursor=DAACCgACHUAq4qFAJxAKAAMd…"

Los cursores son cadenas opacas; no los analices. hasMore es true exactamente cuando nextCursor está presente. Una página de búsqueda son 20 publicaciones, así que tres solicitudes leen unas 60 publicaciones por 6 de tus 20 unidades.

Límites, en la respuesta

HTTP/2 200
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 16
X-RateLimit-Reset: 1791357984

El plan gratuito es de 20 unidades cada 10 minutos por visitante entre todos los endpoints /tools/x/*, y una búsqueda cuesta 2. Cuando se agota, la respuesta es un 429 con Retry-After y un cuerpo JSON que indica dónde levantar el tope:

{
  "error": {
    "type": "rate_limited",
    "message": "Free limit of 20 requests per 10 minutes reached. Retry after 412s, or use a UnifAPI workspace key (pay as you go) for uncapped access.",
    "retryAfterSeconds": 412,
    "upgrade": "https://unifapi.com/apis/twitter"
  }
}

Un agente bien educado lee X-RateLimit-Remaining antes de decidir si pagina, y duerme lo que diga Retry-After en lugar de reintentar en bucle.

Lo que no hace

  • Relevancia. Los resultados solo se ordenan de más reciente a más antiguo. Las publicaciones antiguas se pueden alcanzar con fechas (from:jack until:2006-04-01 devuelve publicaciones de marzo de 2006), pero nada pone primero lo mejor de un periodo, y X traza los límites de día de since:/until: en su propia zona horaria, así que un rango puede desbordarse unas horas por cualquiera de los dos lados.
  • Cuentas protegidas. Solo se devuelven publicaciones públicas.
  • Recuentos. No hay un número de "cuántas publicaciones coincidieron"; X no expone uno para la búsqueda.
  • Garantías. El plan gratuito es infraestructura compartida con un tope por visitante. Un flujo de trabajo que necesite volumen o un SLA pasa a la API con medición de uso, donde los nombres de campo son los mismos.

Un bucle de monitorización en veinte líneas

import requests, time

BASE = "https://unifapi.com/tools/x/search"
seen = set()

def poll(query):
    r = requests.get(BASE, params={"q": query}, headers={"Accept": "application/json"})
    if r.status_code == 429:
        time.sleep(int(r.headers.get("Retry-After", "60")))
        return []
    r.raise_for_status()
    fresh = [p for p in r.json()["posts"]["items"] if p["id"] not in seen]
    seen.update(p["id"] for p in fresh)
    return fresh

while True:
    for post in poll('"unifapi" -filter:replies'):
        print(post["createdAt"], post["author"]["handle"], post["metrics"]["likes"], post["url"])
    time.sleep(600)

Una búsqueda cada 10 minutos son 2 de las 20 unidades gratuitas; el bucle nunca tropieza con el límite y, aun así, maneja el caso del 429.

Preguntas frecuentes

¿Existe una API de búsqueda de Twitter gratuita en 2026?

Sí, esta: gratis, sin iniciar sesión y sin clave de API, con límite por visitante de 10 búsquedas cada 10 minutos. La API oficial de X no tiene un plan gratuito de búsqueda; su plan gratuito solo permite publicar.

¿Funcionan los operadores de la búsqueda avanzada de Twitter?

Sí. La consulta se pasa a la búsqueda de X sin cambios, así que from:, since:, until:, min_faves:, filter:media, -filter:replies, lang: y las frases entre comillas funcionan todos.

¿Hasta cuándo llega hacia atrás la búsqueda?

Hasta 2006. Sin fechas obtienes primero las publicaciones más recientes; añade since: y until: para saltar a un periodo, por ejemplo from:jack until:2006-04-01.

¿Puedo obtener los resultados en Markdown en lugar de JSON?

Sí. Añade format=md o envía Accept: text/markdown. La versión en Markdown lista cada publicación con autor, texto, métricas y URL.