Por Sorsa Editorial
Actualizado en julio de 2026: reelaborada la comparación de costo en torno a tarifas por cada 1,000 tweets, agregada la opción inicial de 100 solicitudes gratis, refrescado el precio por lectura de la API oficial de X, y aclarado cuáles operadores el endpoint v2 descarta en silencio.
Conclusión clave
La API de búsqueda de Twitter deja a los desarrolladores consultar la cronología pública de X de forma programática con filtros de palabra clave y de operadores. En 2026 hay dos caminos prácticos: el endpoint de búsqueda reciente de la API oficial de X v2, cobrado por pago por uso con un conjunto de operadores limitado, y las APIs REST de terceros que pasan el conjunto completo de operadores web en planes mensuales de tarifa plana que empiezan con solicitudes gratis.
Para la búsqueda de solo lectura a escala, Sorsa API, un proveedor alternativo de API de Twitter/X, es la opción que recomendamos y la que cubrimos de principio a fin aquí. Su endpoint /search-tweets pasa el conjunto completo de operadores web, incluidos los filtros de engagement min_faves:, min_retweets:, y min_replies: que el endpoint oficial v2 descarta en silencio; corre a 20 solicitudes por segundo en todos los planes sin ventanas por endpoint; y empieza con 100 solicitudes gratis (sin tarjeta, los 40 endpoints) antes de pasar a planes mensuales de tarifa plana que salen en tan poco como $0.02 por cada 1,000 tweets cuando se hacen por lotes, sin aprobación de cuenta de desarrollador y con una configuración que toma minutos. La única cosa que no hace es escribir: publicar, dar like, y los DMs se quedan con la API oficial.
La barra de búsqueda web de X está bien cuando estás matando el tiempo. Es inútil cuando necesitas extraer 50,000 tweets que coinciden con una consulta booleana compleja, correrla con una programación, empujar los resultados a un almacén de Postgres, y que alguien en cumplimiento audite el pipeline el próximo trimestre. Para eso está la API de búsqueda de Twitter. Esta guía recorre cómo funciona en 2026, los operadores que de verdad se disparan, el código que maneja tráfico de producción real, y dónde encaja cada opción.
Hemos estado construyendo contra los endpoints de búsqueda de Twitter desde la era v1.1. A través de la revisión de precios de 2023, la migración a v2, y el cambio de 2026 al pago por uso basado en créditos, el modelo mental subyacente no ha cambiado mucho: envías una cadena de consulta, recibes JSON de vuelta, paginas con un cursor. Lo que ha cambiado es a qué proveedor pagas, cuánto pagas, y cuáles operadores se descartan en silencio antes de que tu consulta se ejecute. Esa última parte hace tropezar a la mayoría.
Tabla de contenidos
- ¿Por qué buscar tweets de forma programática?
- El panorama de la API de búsqueda de Twitter en 2026
- El endpoint
/search-tweets: anatomía de la solicitud - Qué hay en la respuesta
- Operadores de búsqueda que de verdad funcionan
- Dos conjuntos de operadores: búsqueda web vs la API oficial v2
- ¿Cómo buscas tweets por hashtag?
- Paginación: recolectar miles de tweets
- Código funcional: Python y JavaScript
- Plantillas de consulta del mundo real
- Buscar tweets vs. rastrear menciones: ¿qué endpoint?
- Cómo se compara la búsqueda de Sorsa con la API oficial de X
- Errores comunes y resolución de problemas
- Preguntas frecuentes
- Cómo empezar
¿Por qué buscar tweets de forma programática? {#why-search-tweets-programmatically}
Una API de búsqueda existe porque los casos de uso de abajo no pueden sobrevivir con refrescos manuales del navegador:
Escucha social y monitoreo de marca. Rastrea cada mención pública de tu producto o competidores con JSON estructurado entregado a Slack, un dashboard, o un pipeline de alertas. La señal está en el volumen y la tendencia, no en un solo tweet, que es toda la premisa de la escucha social a escala.
Inteligencia competitiva y de mercado. Extrae tweets filtrados por engagement de las cuentas de tus competidores, identifica qué publicaciones rindieron, y construye un benchmark de contenido para el rastreo de competidores continuo. Combina from:competitor min_faves:100 -filter:replies con ventanas de fecha para comparar trimestre contra trimestre.
Análisis de sentimiento. Alimenta el texto del tweet a un modelo transformer y puntúalo. La API de búsqueda te da el texto crudo más las métricas (likes, respuestas, vistas) que hacen doble función como pesos de confianza al agregar el sentimiento. Cubrimos el pipeline completo en nuestra guía de análisis de sentimiento de Twitter.
Generación de leads. Búsquedas como "looking for" (api OR tool) twitter hacen emerger a la gente que activamente está pidiendo lo que vendes. Una consulta bien elaborada es una lista de leads gratis, que es la base de la generación de leads en X.
Investigación académica y periodística. La investigación académica necesita consultas reproducibles y auditables contra una ventana de tiempo definida. Un endpoint de búsqueda con since: y until: es una fuente de datos primaria, y el archivo histórico se remonta al primer tweet en 2006.
Detección de tendencias. Corre la misma consulta en un cron de 5 minutos, guarda los conteos de resultados, y detecta picos. Así es como funcionan por debajo los sistemas de detección de eventos y los dashboards de sentimiento cripto, y es el patrón detrás del monitoreo en tiempo real construido sobre un bucle de sondeo.
El panorama de la API de búsqueda de Twitter en 2026 {#the-twitter-search-api-landscape-in-2026}
Ya no hay una sola «API de búsqueda de Twitter». Hay tres categorías, y la brecha entre ellas en precio y capacidad es más amplia de lo que la mayoría de los desarrolladores se dan cuenta.
La API oficial de X v2
Endpoint: /2/tweets/search/recent y /2/tweets/search/all. A partir de 2026, la API de X corre sobre un modelo de pago por uso basado en créditos: cada lectura de publicación cuesta aproximadamente $0.005, y cada lectura de usuario (autor) se cobra por separado a aproximadamente $0.010. No hay nivel gratuito ni asignación de crédito gratis, así que compras créditos por adelantado antes de que pase cualquier solicitud. La autenticación usa Bearer Tokens de OAuth 2.0.
El problema más difícil es la cobertura de operadores. El endpoint oficial v2 acepta un subconjunto mucho más pequeño de operadores que la barra de búsqueda web en x.com/search. Los filtros de engagement en los que confían los equipos de producción, incluidos min_faves:, min_retweets:, min_replies:, y within_time:, se ignoran en silencio si los incluyes en una consulta v2. Hemos visto equipos construir pipelines completos sobre filtros min_faves: antes de descubrir esto, y luego tener que refactorizar.
La búsqueda de archivo oficial está disponible pero tiene un precio para presupuestos enterprise. Para la mayoría de las cargas de trabajo de investigación y de monitoreo de solo lectura, los números no cuadran. Si quieres la cronología completa de cómo el precio de X llegó aquí, nuestro desglose de precios de la API de Twitter recorre cada cambio.
Scrapers de código abierto
Twikit, TweeterPy, y XActions siguen funcionales a mediados de 2026. Twint está muerto. twscrape y snscrape están rotos en la mayoría de las configuraciones. Las bibliotecas mantenidas funcionan para trabajos pequeños y puntuales, pero se sientan encima de la interfaz de búsqueda web pública y se rompen cada vez que X ajusta su frontend. Ninguna de ellas es realista para los pipelines de producción que necesitan garantías de uptime.
APIs de búsqueda de terceros
Esta es la categoría en la que se sitúa Sorsa: servicios que corren su propia infraestructura de scraping detrás de una API REST limpia, exponen el conjunto completo de operadores web, y cobran tarifas predecibles. Hay otros proveedores en este espacio, y si todo lo que quieres es el precio por llamada absolutamente más bajo aun a costa de la confiabilidad o la completitud, uno de esos puede encajar en un caso estrecho. Para un acceso de solo lectura confiable y completo a una tarifa plana justa, Sorsa es la que construimos, operamos, y recomendamos.
El razonamiento a favor de nuestro endpoint /search-tweets sobre las alternativas se reduce a cuatro cosas concretas: un plan mensual de tarifa plana que no multiplica los créditos por tipo de endpoint, el conjunto completo de operadores web pasado sin descartes silenciosos, las mismas 20 solicitudes por segundo en todos los planes, y una autenticación que es un encabezado (ApiKey: YOUR_KEY) sin flujo OAuth. Para un recorrido de extremo a extremo fuera de la API oficial, incluido un panorama más amplio de las opciones de solo lectura, revisa nuestra guía de migración de la API de Twitter.
El endpoint /search-tweets: anatomía de la solicitud {#the-search-tweets-endpoint-request-anatomy}
Envía una solicitud POST a:
POST https://api.sorsa.io/v3/search-tweets
La autenticación es un encabezado: ApiKey: YOUR_API_KEY (sensible a mayúsculas). Sin tokens Bearer, sin baile de OAuth, sin URLs de callback que registrar.
Cuerpo de la solicitud
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
query | string | Sí | Palabras clave de búsqueda. Admite el conjunto completo de operadores nativos de búsqueda de X. |
order | string | No | "popular" (predeterminado) coincide con la pestaña «Top» de la búsqueda de X. "latest" devuelve cronológico, más nuevo primero. |
next_cursor | string | No | Cursor de paginación de una respuesta previa. Omítelo en la primera solicitud. |
Ejemplo mínimo con cURL
curl -X POST https://api.sorsa.io/v3/search-tweets \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "artificial intelligence",
"order": "latest"
}'
¿Por qué POST y no GET?
Las consultas de búsqueda se alargan. Una consulta de monitoreo de marca del mundo real puede fácilmente pasar de los 200 caracteres una vez que agregas agrupaciones booleanas, exclusiones, filtros de idioma, y umbrales de engagement. Ponerlas en una URL significa codificar cada operador en la URL y rezar para que el proxy upstream no la trunque. Ponerlas en un cuerpo JSON evita el problema de la longitud de la URL y la codificación por completo. El endpoint de búsqueda oficial v2 toma el enfoque opuesto (un parámetro query codificado en la URL en una solicitud GET), que es parte de por qué las consultas largas de la API oficial chocan con el tope de caracteres del nivel de acceso (512 caracteres en la búsqueda reciente autoservicio) más rápido de lo que la gente espera.
Si quieres construir consultas de forma visual antes de escribir código, el constructor de búsqueda de Sorsa renderiza los mismos operadores como un formulario y produce la cadena de consulta que pegarías en tu script, y el playground interactivo corre solicitudes completas contra tu clave sin escribir ningún código de cliente. Ambos están enlazados en la sección Cómo empezar de abajo.
Qué hay en la respuesta {#whats-in-the-response}
El endpoint devuelve un objeto JSON con dos campos de nivel superior: un array de objetos de tweet y un cursor de paginación.
{
"tweets": [
{
"id": "2029914600217473314",
"full_text": "The latest breakthroughs in AI are reshaping automation.",
"created_at": "2026-03-06T13:38:49Z",
"lang": "en",
"likes_count": 142,
"retweet_count": 38,
"reply_count": 12,
"quote_count": 5,
"view_count": 28400,
"bookmark_count": 19,
"is_reply": false,
"is_quote_status": false,
"conversation_id_str": "2029914600217473314",
"entities": [],
"user": {
"id": "1422280682240450563",
"username": "tech_insider",
"display_name": "Tech Insider",
"description": "Breaking tech news and analysis.",
"followers_count": 84200,
"verified": true
}
}
],
"next_cursor": "DAABCgABGSmiaxkAAgoAAgjEJ..."
}
Unas cuantas cosas importan aquí.
El perfil completo del autor viaja dentro de cada tweet. A lo largo de las migraciones que hemos manejado, el mayor ahorro de tiempo de desarrollo rara vez es la baja de precio. Es no tener que hacer una consulta users/by/ids separada por cada autor de tweet. El endpoint oficial v2 requiere que agregues un parámetro expansions=author_id y luego recorras un array includes.users para emparejar los IDs de autor de vuelta a los tweets, y cobra cada una de esas lecturas de autor por separado. En esta respuesta, el objeto de usuario está incrustado directamente y sin costo extra. Una solicitud, tanto el contenido como la autoría.
Las métricas de engagement no son campos opcionales. Los likes, retweets, respuestas, citas, vistas, y guardados están siempre presentes en cada tweet. Sin tweet.fields=public_metrics que recordar.
next_cursor es la única señal de paginación que necesitas. Cuando el campo es una cadena, hay más resultados disponibles. Cuando es null o falta, has llegado al final del conjunto de resultados.
Para la referencia completa de campos de los objetos Tweet y User, consulta la referencia de formato de respuesta en los docs de la API.
Operadores de búsqueda que de verdad funcionan {#search-operators-that-actually-work}
La búsqueda web de X admite un gran conjunto de operadores, y el subconjunto de alto apalancamiento de abajo cubre aproximadamente el 90% de las cargas de trabajo reales. Mantenemos esta lista práctica a propósito; para el catálogo completo, incluidos los operadores de geo, los filtros de fuente, los filtros de card, y los casos límite de código de idioma, revisa nuestra guía completa de operadores de búsqueda de Twitter.
Palabras clave y frases
artificial intelligencecoincide con tweets que contienen cualquiera de estas palabras"artificial intelligence"coincide con la frase exacta- La derivación de palabras (stemming) está activada por defecto:
beartambién coincidirá conbears
Basados en usuario
from:elonmusktweets publicados por una cuentato:openaitweets respondiendo a una cuenta@sorsa_apptweets mencionando una cuenta
Filtros de engagement
min_faves:100al menos 100 likesmin_retweets:50al menos 50 retweetsmin_replies:10al menos 10 respuestas
Estos tres son los operadores que más vale la pena saber que existen. También son los que la API oficial de X v2 descarta en silencio, así que si migras código de un proveedor diferente puedes ver tu filtro de «baja calidad» dejar de funcionar sin un error.
Filtros de contenido
filter:media,filter:images,filter:videos,filter:links- Prefija con
-para excluir:-filter:retweets,-filter:replies,-filter:links
Idioma y fecha
lang:en(cualquier código ISO 639-1:es,fr,de,ja, y demás)since:2026-01-01en o después de esta fechauntil:2026-03-01antes de esta fecha (exclusivo)
Lógica booleana
(bitcoin OR ethereum) min_faves:100 lang:enparéntesis para gruposcrypto -scam -airdropexclusión con un prefijo de menos
Para la referencia de comportamiento de operadores, el repositorio igorbrigadir/twitter-advanced-search mantenido por la comunidad en GitHub es la fuente pública más exhaustiva.
Dos conjuntos de operadores: búsqueda web vs la API oficial v2 {#two-operator-sets-web-search-vs-the-official-v2-api}
Hay dos conjuntos de operadores distintos en X, y confundirlos es la razón individual más común por la que una consulta que «funciona» en un lugar no devuelve nada en otro. Nombra el conjunto al que apuntas antes de escribir la consulta.
Los operadores de búsqueda web son los que twitter.com/search, TweetDeck, y las APIs REST basadas en scraping aceptan. Este es el conjunto de la sección de arriba, y es lo que el endpoint /search-tweets de Sorsa pasa sin cambios.
Los operadores de la API oficial de X v2 son un subconjunto más pequeño con sintaxis diferente. En lugar de filter:media y -filter:retweets, el endpoint v2 usa has:media, has:links, is:retweet, y is:reply. Agrega place_country:US para geografía y context: para anotaciones de tema y de entidad, pero no acepta los filtros de engagement en absoluto. Si estás en el endpoint oficial, min_faves:, min_retweets:, min_replies:, within_time:, y filter:blue_verified simplemente se ignoran, sin ningún error devuelto.
Unos cuantos operadores son ampliamente malentendidos o poco confiables, en cualquier proveedor, en 2026:
| Operador | Qué se equivoca la gente |
|---|---|
filter:verified vs filter:blue_verified | filter:verified coincide con las cuentas verificadas legadas; filter:blue_verified coincide con las cuentas de pago de X Premium. Para la señal editorial usualmente quieres la primera, no la segunda. |
within_time:7d | Una ventana deslizante medida desde el momento de la consulta, así que la misma consulta devuelve un conjunto diferente mañana. Para datasets reproducibles usa fechas since: y until: explícitas en su lugar. |
from:user vs @user | from:user devuelve los tweets que la cuenta escribió; @user devuelve cualquier tweet que la mencione, incluidas respuestas y citas de otros. |
near:, within:, geocode: | El geoetiquetado de coordenadas exactas está en gran parte obsoleto, así que los operadores de geo ahora tienen cobertura reducida y no se debe confiar en ellos para la completitud. |
Saber en qué conjunto estás ahorra horas de depurar una consulta que es válida pero calladamente devuelve vacío.
¿Cómo buscas tweets por hashtag? {#how-do-you-search-tweets-by-hashtag}
Para buscar tweets por hashtag a través de una API, pasa el hashtag como un operador independiente en tu consulta, por ejemplo #worldcup. Un hashtag funciona por sí solo y se puede combinar con filtros de engagement, de idioma, y de fecha para acotar el conjunto de resultados, que es cómo conviertes un hashtag ruidoso en un dataset usable.
En el endpoint /search-tweets de Sorsa, el cuerpo se ve así:
{
"query": "#worldcup min_faves:50 lang:en -filter:retweets since:2026-06-01",
"order": "latest"
}
Eso devuelve tweets originales (no-retweet) en inglés que llevan #worldcup con al menos 50 likes, publicados en o después del 1 de junio. Quita el filtro de engagement para el volumen crudo, o súbelo para hacer emerger solo las publicaciones que viajaron.
La API oficial de X v2 también coincide con #hashtag como término de consulta, pero con dos salvedades que afectan a los proyectos de rastreo de hashtags: el piso de engagement (min_faves:) que evita que un hashtag popular te ahogue en ruido no está disponible, y la búsqueda reciente tiene un tope de aproximadamente los últimos siete días a menos que estés en un nivel de archivo de mayor compromiso. Si tu meta es «cada tweet con este hashtag por encima de N engagement, remontándose meses», el camino de tarifa plana con operadores web es el que de verdad lo hace. El conjunto completo de operadores adyacentes a hashtags (filter:hashtags, cashtags, y los códigos de idioma de solo multimedia) está cubierto en la guía de operadores de búsqueda enlazada antes.
Paginación: recolectar miles de tweets {#pagination-collecting-thousands-of-tweets}
Una sola solicitud de búsqueda devuelve una página de alrededor de 20 tweets. Para extraer datasets más grandes usas la paginación basada en cursor.
La lógica son cuatro pasos:
- Primera solicitud. Envía la consulta y el orden. No incluyas
next_cursor. - Lee el cursor. La respuesta contiene una cadena
next_cursor. - Siguiente solicitud. Envía la misma consulta, el mismo orden, más el valor
next_cursorque acabas de recibir. - Repite hasta que
next_cursorseanull, esté vacío, o ausente.
Esto es más confiable que la paginación basada en offset porque los tweets nuevos publicados entre tus solicitudes no causan duplicados ni resultados omitidos. El cursor codifica una posición en el conjunto de resultados, no un offset numérico.
Troceado por rango de fechas para paginación profunda
Hay un caso límite que vale la pena conocer antes de que confíes en un solo cursor para 100,000 tweets.
En una extracción de investigación de mercado de 200,000 tweets que coincidían con bitcoin lang:en, un solo bucle de cursor empezó a devolver duplicados contra páginas anteriores alrededor de la página 70 y dejó de avanzar por completo alrededor de la página 90. Esto no es específico de nuestra API: cualquier índice de búsqueda contra una cronología en movimiento tiene esta propiedad cuando lo recorres lo bastante profundo.
El arreglo es partir la consulta en trozos por rango de fechas. En lugar de una consulta sobre todo el tiempo, corre la misma consulta para cada semana:
import datetime as dt
import time
import requests
API_KEY = "YOUR_API_KEY"
URL = "https://api.sorsa.io/v3/search-tweets"
def search_in_window(base_query, since, until, max_pages=50):
"""Paginate within a since/until window."""
full_query = f"{base_query} since:{since} until:{until}"
cursor = None
out = []
for _ in range(max_pages):
body = {"query": full_query, "order": "latest"}
if cursor:
body["next_cursor"] = cursor
resp = requests.post(
URL,
headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
json=body,
)
resp.raise_for_status()
data = resp.json()
out.extend(data.get("tweets", []))
cursor = data.get("next_cursor")
if not cursor:
break
time.sleep(0.1)
return out
def search_chunked(base_query, start, end, days_per_chunk=7):
"""Walk a date range in chunks."""
all_tweets = []
cursor_date = start
while cursor_date < end:
next_date = min(cursor_date + dt.timedelta(days=days_per_chunk), end)
chunk = search_in_window(
base_query,
cursor_date.strftime("%Y-%m-%d"),
next_date.strftime("%Y-%m-%d"),
)
all_tweets.extend(chunk)
print(f"{cursor_date} -> {next_date}: {len(chunk)} tweets")
cursor_date = next_date
return all_tweets
tweets = search_chunked(
"bitcoin lang:en",
dt.date(2026, 1, 1),
dt.date(2026, 4, 1),
days_per_chunk=7,
)
Un trozo semanal en una consulta ruidosa como bitcoin lang:en típicamente rinde un recorrido de cursor limpio hasta completarse sin deriva de duplicados. Para consultas más tranquilas puedes estirar a trozos mensuales. Para consultas de muy alto volumen (piensa en lang:en sin otros filtros) quizá quieras diarios.
Para más sobre patrones de paginación y lógica de reintento consciente del límite de tasa, consulta nuestra guía de límites de tasa de la API de Twitter.
Código funcional: Python y JavaScript {#working-code-python-and-javascript}
Los ejemplos de abajo son patrones de producción que corremos contra el endpoint en vivo: paginación por cursor, backoff de 429 con reintentos exponenciales, y una pequeña brecha de lotes para respetar el techo de 20 solicitudes/s.
Python
import requests
import time
API_KEY = "YOUR_API_KEY"
URL = "https://api.sorsa.io/v3/search-tweets"
def search_tweets(query, order="popular", max_pages=5, max_retries=3):
"""
Search tweets with cursor pagination and 429 backoff.
Args:
query: Search string (X operators supported).
order: "popular" or "latest".
max_pages: Maximum pages to fetch.
max_retries: Retries on 429 before giving up on a page.
Returns:
List of tweet dicts.
"""
all_tweets = []
next_cursor = None
for page in range(max_pages):
body = {"query": query, "order": order}
if next_cursor:
body["next_cursor"] = next_cursor
for attempt in range(max_retries):
resp = requests.post(
URL,
headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
json=body,
)
if resp.status_code == 429:
wait = 2 ** attempt
print(f"Rate limited. Sleeping {wait}s.")
time.sleep(wait)
continue
resp.raise_for_status()
break
else:
print(f"Page {page + 1} failed after {max_retries} retries.")
break
data = resp.json()
tweets = data.get("tweets", [])
all_tweets.extend(tweets)
print(f"Page {page + 1}: {len(tweets)} tweets (total {len(all_tweets)})")
next_cursor = data.get("next_cursor")
if not next_cursor:
print("End of results.")
break
time.sleep(0.1)
return all_tweets
# Usage
tweets = search_tweets('"Sorsa API" min_faves:5 lang:en', max_pages=10)
for t in tweets:
u = t["user"]
print(f"@{u['username']} ({u['followers_count']} followers)")
print(f" {t['full_text'][:120]}")
print(f" L:{t['likes_count']} RT:{t['retweet_count']} V:{t.get('view_count', 'N/A')}")
JavaScript (Node.js)
const API_KEY = "YOUR_API_KEY";
const URL = "https://api.sorsa.io/v3/search-tweets";
async function searchTweets(query, order = "popular", maxPages = 5, maxRetries = 3) {
const allTweets = [];
let nextCursor = null;
for (let page = 0; page < maxPages; page++) {
const body = { query, order };
if (nextCursor) body.next_cursor = nextCursor;
let data;
for (let attempt = 0; attempt < maxRetries; attempt++) {
const resp = await fetch(URL, {
method: "POST",
headers: { "ApiKey": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (resp.status === 429) {
const wait = Math.pow(2, attempt) * 1000;
console.log(`Rate limited. Sleeping ${wait}ms.`);
await new Promise((r) => setTimeout(r, wait));
continue;
}
if (!resp.ok) throw new Error(`API error: ${resp.status}`);
data = await resp.json();
break;
}
if (!data) break;
const tweets = data.tweets || [];
allTweets.push(...tweets);
console.log(`Page ${page + 1}: ${tweets.length} tweets (total ${allTweets.length})`);
nextCursor = data.next_cursor;
if (!nextCursor) break;
await new Promise((r) => setTimeout(r, 100));
}
return allTweets;
}
(async () => {
const tweets = await searchTweets("bitcoin lang:en min_faves:50", "latest", 5);
for (const t of tweets) {
console.log(`@${t.user.username}: ${t.full_text.slice(0, 100)}`);
}
})();
Pipeline de exportación a CSV
Un patrón posterior común es de búsqueda a CSV, luego cargar en un notebook o una herramienta de BI:
import requests, time, csv
API_KEY = "YOUR_API_KEY"
URL = "https://api.sorsa.io/v3/search-tweets"
def search_to_csv(query, order="popular", max_pages=10, out="tweets.csv"):
fields = [
"tweet_id", "created_at", "full_text", "lang",
"likes", "retweets", "replies", "quotes", "views",
"username", "display_name", "followers_count", "verified",
]
with open(out, "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=fields)
w.writeheader()
cursor, total = None, 0
for _ in range(max_pages):
body = {"query": query, "order": order}
if cursor:
body["next_cursor"] = cursor
r = requests.post(
URL,
headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
json=body,
)
r.raise_for_status()
data = r.json()
for t in data.get("tweets", []):
u = t.get("user", {})
w.writerow({
"tweet_id": t["id"],
"created_at": t["created_at"],
"full_text": t["full_text"],
"lang": t.get("lang", ""),
"likes": t.get("likes_count", 0),
"retweets": t.get("retweet_count", 0),
"replies": t.get("reply_count", 0),
"quotes": t.get("quote_count", 0),
"views": t.get("view_count", 0),
"username": u.get("username", ""),
"display_name": u.get("display_name", ""),
"followers_count": u.get("followers_count", 0),
"verified": u.get("verified", False),
})
total += 1
cursor = data.get("next_cursor")
if not cursor:
break
time.sleep(0.1)
print(f"Exported {total} tweets to {out}")
search_to_csv(
'(bitcoin OR ethereum) lang:en min_faves:10 -filter:retweets',
order="latest",
max_pages=20,
out="crypto_tweets.csv",
)
A ~20 tweets por página, max_pages=50 te da ~1,000 tweets. Combinado con el troceado por rango de fechas, puedes escalar esto a seis o siete cifras sin reescribir el bucle, que es exactamente cómo ensamblas un dataset de Twitter para machine learning.
Plantillas de consulta del mundo real {#real-world-query-templates}
Copia estas, cambia las variables, envíalas.
Monitoreo de marca (solo menciones orgánicas)
("yourbrand" OR "@yourbrand") -from:yourbrand -filter:retweets lang:en
Atrapa lo que la gente dice de ti, excluye tus propias publicaciones y retweets, solo inglés. Corre en un cron de 5 minutos, canaliza a Slack.
Benchmark de contenido de competidores
(from:competitor1 OR from:competitor2 OR from:competitor3) min_faves:100 -filter:replies since:2026-01-01
Sus publicaciones originales de mejor desempeño en la ventana de fecha. Vuelca en una hoja de cálculo, ordena por engagement, aprende qué funciona. Nuestra guía de análisis de competencia en Twitter construye esto en un flujo de trabajo repetible.
Rastreo de sentimiento
(bitcoin OR $BTC) (bullish OR bearish OR moon OR crash OR pump OR dump) min_faves:20 lang:en
Tweets cargados de sentimiento por encima de un piso de calidad. Empareja con el pipeline de análisis de sentimiento enlazado arriba para la puntuación.
Minería de feedback de producto
"yourproduct" (bug OR broken OR issue OR love OR amazing OR hate) -filter:retweets
Feedback orgánico, ambos sabores. Útil para el soporte y la entrada al roadmap de producto.
Generación de leads
("looking for" OR "anyone recommend" OR "best tool for") (api OR scraping OR twitter data) -filter:retweets lang:en
Gente que activamente pregunta. Filtra más con min_faves:1 para descartar el tráfico de bots.
Ventana de reacción a un evento
"product launch" OR "announcement" from:yourbrand since:2026-05-01 until:2026-05-08
Reacciones a tu propio lanzamiento dentro de una ventana definida. Empareja from:yourbrand (tus publicaciones) con una consulta separada para la conversación circundante.
Buscar tweets vs. rastrear menciones: ¿qué endpoint? {#search-tweets-vs-track-mentions-which-endpoint}
Dos endpoints se solapan en las cargas de trabajo de rastreo de menciones. Cuál elegir:
/search-tweets es el endpoint de propósito general. Cualquier combinación de operadores, cualquier forma de consulta. Úsalo cuando necesites flexibilidad, cuando tu consulta no sea solo sobre un usuario, o cuando quieras mezclar menciones con filtros de engagement en una sola expresión booleana.
/mentions está construido para el propósito de rastrear las @-menciones de un solo usuario. Expone el conjunto de filtros más rico de nuestra API: min_likes, min_replies, min_retweets, since_date, until_date, todos como parámetros de primera clase en lugar de operadores en línea. Úsalo cuando tu flujo de trabajo sea específicamente «avísame de nuevas menciones de @brand por encima de X engagement».
Regla de decisión rápida: si tu consulta empieza con @handle y termina con filtros de engagement, usa /mentions. Si involucra varios términos, grupos booleanos, u operadores que no son de mención, usa /search-tweets.
Para una mirada más cercana al endpoint de menciones y los flujos de trabajo de monitoreo de marca, consulta nuestra guía de la API de menciones de Twitter.
Cómo se compara la búsqueda de Sorsa con la API oficial de X {#how-sorsa-search-compares-to-the-official-x-api}
Sorsa es nuestro producto, así que aquí está el lado a lado honesto con números reales para ambos, incluido dónde la API oficial todavía gana. Para la búsqueda de solo lectura pura, el problema del descarte silencioso de operadores y el cobro por lectura de autor son las dos razones prácticas por las que los equipos se mueven fuera de v2.
| Dimensión | Sorsa /search-tweets | API oficial de X v2 /2/tweets/search/recent |
|---|---|---|
| Modelo de precio | Planes mensuales de tarifa plana; desde $0.02 por cada 1,000 tweets por lotes | Pago por uso, ~$0.005 por lectura de publicación (unos $5.00 por cada 1,000) |
| Gratis para empezar | 100 solicitudes gratis, sin tarjeta, todos los endpoints | Sin crédito gratis; compra créditos antes de la primera llamada |
| Perfil de autor en la respuesta | Incrustado por defecto, sin cargo extra | Lectura de usuario separada, ~$0.010 cada una, vía expansions=author_id |
| Auth | Clave API en el encabezado ApiKey | Bearer Token de OAuth 2.0 |
| Aprobación de cuenta | Registro instantáneo, sin cola de aprobación | Registro en la Developer Console |
Operadores de engagement (min_faves:, min_retweets:, min_replies:) | Sí | Ignorados en silencio |
| Paridad de operadores web | Conjunto completo pasado | Solo un subconjunto, sintaxis diferente (has:, is:) |
| Archivo histórico | Hasta 2006 | ~7 días reciente; archivo completo solo en niveles de mayor compromiso |
| Límite de tasa | 20 solicitudes/s, todos los planes | Basado en créditos, varía |
| Monitoreo en tiempo real | Sondeo a 20 solicitudes/s | Filtered stream disponible |
| Acciones de escritura (publicar, like, DM) | Ninguna (solo lectura) | Sí |
En costo de lectura la brecha es grande. Leer 1,000 publicaciones en la API oficial de X sale alrededor de $5.00, y eso es antes del cargo separado de $0.010 por autor. En Sorsa los mismos 1,000 tweets cuestan alrededor de $0.10 a través del endpoint paginado /search-tweets (aproximadamente 20 tweets por solicitud) y bajan a alrededor de $0.02 cuando los mismos IDs se extraen a través del endpoint por lotes /tweet-info-bulk, perfiles de autor incluidos de cualquier forma. Sobre la base por lotes eso es hasta 50 veces más barato por cada 1,000 tweets, con los datos de autor que X cobra como una segunda lectura incluidos sin costo extra.
Dónde la API oficial es la elección correcta: el filtered stream para el verdadero tiempo real basado en push, y las acciones de escritura (publicar, dar like, seguir) que no ofrecemos en absoluto. Para todo lo de solo lectura, el camino de tarifa plana es tanto más barato como más simple de operar a cualquier volumen significativo.
En la práctica. Un equipo de analítica social de unas 12 personas con el que trabajamos se sentaba en la incómoda zona intermedia: estaban extrayendo entre 50,000 y unos pocos millones de lecturas de publicación al mes, muy pasados el punto donde el pago por uso se mantiene barato, pero para nada cerca del volumen que justifica un contrato enterprise. En la API oficial, los perfiles de autor duplicaban su costo por búsqueda porque el autor de cada tweet se cobraba como una lectura separada. Mover la carga de lectura a un plan de tarifa plana con los datos de autor incrustados recortó su factura de datos mensual en más de un orden de magnitud e hizo el número predecible, lo que importó más a su equipo de finanzas que el ahorro crudo. La migración que impulsó el cambio es la misma mapeada paso a paso en la guía de migración enlazada antes.
Errores comunes y resolución de problemas {#common-errors-and-troubleshooting}
Cosas que hacen tropezar a la gente, en orden aproximado de qué tan a menudo las vemos en soporte.
Resultados vacíos en una consulta que sabes que debería devolver algo. Los sospechosos usuales: un error de tipeo en un operador (min_likes en lugar de min_faves), una frase que necesita comillas dobles ("black cat" no black cat), o un -filter: que excluye demasiado. Reduce la consulta a una palabra clave, confirma que devuelve resultados, luego agrega los operadores de vuelta uno a la vez.
429 Too Many Requests. Superaste las 20 solicitudes por segundo en la clave. Retírate por un segundo y reintenta. Los ejemplos de Python y JavaScript de arriba implementan backoff exponencial para esto. El límite de 20 solicitudes/s es universal a lo largo de nuestros planes; si necesitas mayor rendimiento de forma sostenida, contáctanos sobre límites personalizados.
El cursor deja de avanzar o devuelve duplicados tras paginación profunda. Este es el problema cubierto en la sección de troceado por rango de fechas. Cualquier índice de búsqueda se vuelve inestable pasada cierta profundidad de paginación en consultas ruidosas. Cambia a trozos semanales since:/until:.
Operador ignorado en silencio. Si un filtro parece no tener efecto, probablemente estás enviando un operador de búsqueda web a la API oficial v2, que descarta los filtros de engagement. Confirma qué conjunto de operadores acepta tu proveedor antes de asumir que la consulta está mal.
Tope de operadores. El índice de búsqueda de X parece fallar en silencio las consultas con más de aproximadamente 22 a 23 operadores, y la búsqueda reciente autoservicio en la API oficial limita la cadena de consulta a 512 caracteres. Si tu consulta tiene más agrupaciones que eso y devuelve vacío, simplifícala o pártela en varias solicitudes.
El objeto user falta o está parcial. El autor fue suspendido, borrado, o hizo su cuenta protegida entre el momento en que se creó el tweet y el momento en que lo solicitaste. El tweet todavía existe en el índice pero el autor ya no es enumerable públicamente. Maneja esto con defaults tweet.get("user", {}) en tu código.
Resultados de idioma inesperados a pesar de lang:en. El detector de idioma de X no es perfecto, especialmente en tweets cortos con hashtags o escrituras mezcladas. Para las cargas de trabajo de analítica, post-filtra con una biblioteca de detección de idioma (como langdetect o fasttext-langdetect) sobre el campo full_text.
Las cuentas privadas y con shadowban no aparecen. Las cuentas protegidas no están en el índice de búsqueda. Las cuentas suspendidas y bloqueadas también están ocultas. No hay operador para hacerlas emerger. El shadowban es una pregunta de diagnóstico separada de la visibilidad de búsqueda y no es algo que el índice de búsqueda pueda responder.
Preguntas frecuentes {#frequently-asked-questions}
¿Cómo busco tweets sin la API oficial de Twitter?
Usa una API de búsqueda de terceros o un scraper de código abierto. Las APIs REST de terceros envuelven su propia infraestructura de scraping detrás de una clave API sin OAuth y con soporte completo de operadores web; Sorsa es una de esas APIs alternativas de Twitter/X, con un endpoint /search-tweets de tarifa plana que pasa cada operador. Las bibliotecas de código abierto como Twikit funcionan para trabajos pequeños y puntuales pero no son lo bastante estables para producción.
¿Cómo busco tweets por hashtag usando la API?
Pasa el hashtag como un término de consulta, por ejemplo #worldcup, y combínalo con filtros para controlar el volumen: #worldcup min_faves:50 lang:en -filter:retweets devuelve tweets originales populares en inglés que llevan ese hashtag. La API oficial de X v2 también coincide con #hashtag pero no puede aplicar pisos de engagement y limita la búsqueda reciente a unos siete días, así que para un historial de hashtag más profundo una API de tarifa plana con operadores web es la ruta más capaz.
¿Puedo buscar tweets más viejos que 7 días?
Sí, en las APIs de terceros. El endpoint /search-tweets de Sorsa cubre el archivo histórico completo hasta 2006 con los operadores since: y until:. La búsqueda reciente de la API oficial de X v2 está limitada a unos 7 días; la búsqueda de archivo completo en la API oficial está restringida a los niveles de mayor compromiso.
¿Cuántos tweets obtengo por solicitud de búsqueda?
Una sola solicitud a /search-tweets devuelve una página de alrededor de 20 tweets. Para extraer más, usa la paginación por cursor con next_cursor. Para datasets por encima de unos pocos miles de tweets, combina la paginación por cursor con el troceado por rango de fechas para evitar la deriva del cursor en recorridos largos.
¿Cuáles son los operadores de búsqueda de Twitter más útiles para desarrolladores?
Los operadores de alto apalancamiento en el código de producción son from:, to:, min_faves:, min_retweets:, since:, until:, lang:, y las exclusiones -filter:retweets y -filter:replies. Los filtros de engagement son particularmente valiosos porque quitan el ruido de baja calidad sin perder el contenido relevante, y porque no funcionan en la API oficial de X v2.
¿La API de búsqueda de Twitter admite lógica booleana (AND, OR, NOT)?
Sí. Los términos separados por espacios implican AND. OR en mayúsculas es un OR explícito. Los paréntesis agrupan expresiones. Un prefijo de menos excluye términos: crypto -scam. Un ejemplo completo es (bitcoin OR ethereum) min_faves:100 -filter:retweets lang:en.
¿Cuánto cuesta buscar tweets por API en 2026?
La API oficial de X v2 cuesta alrededor de $0.005 por lectura de publicación en pago por uso, más aproximadamente $0.010 por lectura de perfil de autor, lo que llega a aproximadamente $5.00 por cada 1,000 tweets antes de los datos de autor. Sorsa es de tarifa plana mensual y empieza con 100 solicitudes gratis, sin tarjeta requerida. Por lotes a través de /tweet-info-bulk, los datos de tweet salen en aproximadamente $0.02 por cada 1,000 tweets en el plan Pro (desde $0.049 en Starter hasta $0.018 en Enterprise), perfiles de autor incluidos; a través del endpoint paginado /search-tweets a alrededor de 20 tweets por solicitud está más cerca de $0.10 por cada 1,000.
¿Puedo buscar tweets en tiempo real?
Prácticamente sí, a través del sondeo. Con un límite de tasa de 20 solicitudes/s y order: "latest", puedes sondear una consulta cada pocos segundos y obtener tweets nuevos en segundos de la publicación. Para el streaming verdadero basado en push, el filtered stream de la API oficial de X es la única opción que entrega sin sondeo. Para la mayoría de las cargas de trabajo de monitoreo, sondear a intervalos de 30 a 60 segundos es suficiente y más barato de operar.
Cómo empezar {#getting-started}
Puedes probar el endpoint antes de escribir una línea de código de cliente. El playground interactivo de la API corre solicitudes reales contra tu clave desde el navegador, y el constructor visual de consultas de búsqueda te da un formulario para operadores y produce el cuerpo JSON exacto a enviar.
Cuando estés listo para conseguir una clave: las primeras 100 solicitudes son gratis sin tarjeta y cubren los 40 endpoints, el registro toma minutos sin aprobación de cuenta de desarrollador, y cada plan corre sobre las mismas 20 solicitudes por segundo. Por lotes, los planes de tarifa plana salen en tan poco como $0.02 por cada 1,000 tweets. Regístrate en el dashboard de Sorsa y sigue la guía de quickstart para la configuración de cinco minutos. Si te estás moviendo fuera de la API oficial, la guía de migración enlazada antes mapea cada endpoint v2 a su equivalente de Sorsa con código de ambos lados.
Revisado por Keksich, fundador de Sorsa, especialista en marketing e investigador de la API de X.
Cómo se armó esta guía: se apoya en nuestro trabajo práctico construyendo y operando la infraestructura de búsqueda de Sorsa, probada en vivo contra el endpoint /search-tweets, y en una comparación directa con el endpoint de búsqueda reciente de la API oficial de X v2. El comportamiento de los operadores se revisó contra la referencia igorbrigadir/twitter-advanced-search mantenida por la comunidad y la documentación oficial de la API de X; el precio refleja las tarifas por lectura de la API oficial de X vigentes al 8 de julio de 2026. Los detalles de los endpoints vienen de los docs de Sorsa API. Más sobre quién publica este blog está en nuestra página Acerca de.