Por Sorsa Editorial

Actualizado en julio de 2026: agregada la opción inicial de 100 solicitudes gratis y refrescada la comparación de costos con el pago por uso de la API oficial de X.

Contenido

Conclusión clave {#key-takeaway}

El monitoreo de Twitter en tiempo real funciona sondeando un endpoint REST cada 5 a 30 segundos, comparando los IDs de tweets devueltos contra el último ID visto y enviando los tweets nuevos a un pipeline de alertas. Para rastrear muchas cuentas a la vez, agrupa hasta 5,000 en una Lista de X y sondea un único endpoint de lista.

Por qué el monitoreo de Twitter en tiempo real se volvió más difícil tras 2023 {#why-real-time-twitter-monitoring-got-harder-after-2023}

El monitoreo de Twitter en tiempo real solía significar una cosa: abrir una conexión persistente al filtered stream, definir unas reglas y dejar que los tweets fluyeran a tu aplicación conforme se publicaban. La reforma de precios de 2023 convirtió eso en una función del nivel Pro de $5,000 al mes, y a inicios de 2026 X fue más allá: cambió a un modelo de pago por uso donde cada post entregado se cobra y una carga de monitoreo continuo se va a los miles de dólares al mes antes de chocar con un tope de 2 millones de lecturas. Para la mayoría de los equipos (desarrolladores independientes, equipos de monitoreo de marca, bots de trading, redacciones, agencias de generación de leads), ese precio mató el proyecto. La alternativa práctica es extraer los datos tú mismo desde una API REST simple.

Esta guía construye ese patrón basado en extracción sobre Sorsa API, un proveedor alternativo de API de Twitter/X que devuelve datos frescos de tweets en cada solicitud, corre con una sola clave API sin flujo OAuth y sin cola de aprobación, permite 20 solicitudes por segundo en todos los planes y te deja plegar hasta 5,000 cuentas en una sola llamada /list-tweets. El acceso de lectura arranca desde $0.02 por cada 1,000 tweets (y desde $0.01 por cada 1,000 perfiles) en endpoints por lotes, y puedes probar todo con 100 solicitudes gratis, por única vez y sin tarjeta, que cubren los 40 endpoints. Con tiempos de respuesta de alrededor de 300ms y la elección de endpoint correcta, puedes detectar un tweet nuevo en segundos de que se publica, y para monitoreo intensivo en lecturas cuesta una fracción de lo que cobra la API oficial. Para la comparación más amplia de proveedores, revisa nuestra visión general de alternativas a la API de Twitter.

Una nota sobre terminología: este artículo usa "sondeo" (polling) de forma deliberada. No es un eufemismo de "con retraso". Bien hecho, un bucle de sondeo devuelve un tweet dentro del intervalo que elijas más el tiempo de respuesta de la API. Si tu bucle corre cada 5 segundos contra un endpoint de 300ms, tu latencia en el peor caso es de aproximadamente 5.3 segundos. Eso iguala o supera a la mayoría de los productos de streaming de nivel consumidor, y sobre todo funciona con un presupuesto REST de tarifa plana.

Sondeo vs streaming: qué enfoque encaja con tu caso {#polling-vs-streaming-which-approach-fits-your-case}

Hay dos formas de obtener datos de una plataforma social: basada en push (streaming, webhooks) o basada en pull (sondeo). La mayoría de quienes desarrollan opta por defecto por el streaming porque suena más rápido. En la práctica, la elección depende de tres cosas: cuántas cosas estás monitoreando, tu presupuesto de latencia y tu apetito por el estado de conexión.

FactorSondeo (REST)Streaming (WebSocket / filtered stream)
Latencia al primer tweetIntervalo + tiempo de respuesta de la APILatencia de conexión, normalmente de 1 a 3 segundos
Complejidad de montajeUna llamada a la API en un bucleConexión persistente, lógica de reconexión, manejo de backpressure
AutenticaciónClave API en un encabezadoOAuth o rotación de tokens
Recuperación ante caídaReanudar desde un cursor guardadoReconectar, buffer de reproducción, ventana de deduplicación
Modelo de costoPor solicitudPor recurso entregado o un contrato enterprise
Ideal para1 a 5,000 objetivos monitoreados, alertas con tolerancia de 1 a 30 sLatencia por debajo del segundo, ingesta del firehose completo, trading a escala de milisegundos

El streaming gana cuando necesitas alertas a nivel de milisegundos en un gran espacio de palabras clave y tienes capacidad de ingeniería para manejar reconexiones, recuperación de huecos y gestión de reglas. Para todo lo demás (escucha de marca, monitoreo de noticias, generación de leads, alertas de cumplimiento, señales de trading de frecuencia media, moderación de contenido), el sondeo es más simple, más barato y suficiente.

La otra ventaja subvalorada del sondeo: si tu script se cae, retoma donde se quedó en el siguiente ciclo. Los pipelines de streaming necesitan un buffer de reproducción separado para manejar caídas sin pérdida de datos. No lanzamos un producto de webhook administrado a propósito; el patrón de extracción mantiene el plano de control en tus manos, y el límite de tasa de 20 solicitudes por segundo da suficiente margen para bucles a escala de producción.

Elige el endpoint correcto para lo que monitoreas {#pick-the-right-endpoint-for-what-youre-monitoring}

La primera decisión de diseño es elegir el endpoint que encaja con la forma de tu objetivo. Cuatro endpoints cubren prácticamente toda necesidad de monitoreo en tiempo real.

Objetivo de monitoreoEndpointMétodoPor qué
Una sola cuenta/user-tweetsPOSTDevuelve los últimos tweets de la cronología de un usuario
Hasta 5,000 cuentas a la vez/list-tweetsGETUna solicitud cubre a cada miembro de una Lista de X
Una palabra clave, hashtag o consulta de búsqueda/search-tweetsPOSTSintaxis completa de operadores, admite order: latest para resultados cronológicos
@menciones de un usuario específico/mentionsPOSTHecho a medida para el rastreo de menciones con filtros de engagement

El endpoint que sorprende a la mayoría de los equipos es /list-tweets. Poner 50 cuentas en una sola Lista y sondear el endpoint de lista recorta el volumen de solicitudes en aproximadamente 50 veces comparado con sondear cada cuenta por separado. El mismo patrón escala a 500 o 5,000 cuentas sin cambio en el volumen de solicitudes, y la lista misma la creas en x.com.

Nivel 1: rastrea una sola cuenta {#level-1-track-a-single-account}

El caso más simple. Quieres saber el momento en que una cuenta publica: un competidor, un CEO, un regulador, un influencer. Útil para monitoreo de bajo volumen o para probar tu pipeline antes de escalar. Usa el endpoint /user-tweets.

Python

python
import requests
import time

API_KEY = "YOUR_API_KEY"
USERNAME = "elonmusk"
POLL_INTERVAL = 5  # seconds

URL = "https://api.sorsa.io/v3/user-tweets"
HEADERS = {"ApiKey": API_KEY, "Content-Type": "application/json"}

last_seen_id = None

print(f"Monitoring @{USERNAME}...")

while True:
    try:
        resp = requests.post(URL, headers=HEADERS, json={"username": USERNAME})
        resp.raise_for_status()
        tweets = resp.json().get("tweets", [])

        if tweets:
            # Tweet IDs are Snowflake strings. Cast to int for safe comparison
            # since lexicographic order can break across ID length boundaries.
            top_id = int(tweets[0]["id"])

            if last_seen_id is None:
                last_seen_id = top_id
                print(f"Baseline set: {last_seen_id}")
            else:
                new_tweets = [t for t in tweets if int(t["id"]) > last_seen_id]
                # Print in chronological order (oldest first).
                for tweet in reversed(new_tweets):
                    print(f"[NEW] @{USERNAME}: {tweet['full_text'][:140]}")
                if new_tweets:
                    last_seen_id = top_id

    except requests.exceptions.RequestException as e:
        print(f"Request error: {e}")
        time.sleep(POLL_INTERVAL * 2)
        continue

    time.sleep(POLL_INTERVAL)

JavaScript

javascript
const API_KEY = "YOUR_API_KEY";
const USERNAME = "elonmusk";
const POLL_INTERVAL = 5000;

let lastSeenId = null;
console.log(`Monitoring @${USERNAME}...`);

while (true) {
  try {
    const resp = await fetch("https://api.sorsa.io/v3/user-tweets", {
      method: "POST",
      headers: { "ApiKey": API_KEY, "Content-Type": "application/json" },
      body: JSON.stringify({ username: USERNAME }),
    });
    if (!resp.ok) throw new Error(`HTTP ${resp.status}`);

    const tweets = (await resp.json()).tweets || [];

    if (tweets.length > 0) {
      // BigInt comparison avoids precision loss on 64-bit Snowflake IDs.
      const topId = BigInt(tweets[0].id);

      if (lastSeenId === null) {
        lastSeenId = topId;
        console.log(`Baseline set: ${lastSeenId}`);
      } else {
        const newTweets = tweets.filter((t) => BigInt(t.id) > lastSeenId);
        for (const t of [...newTweets].reverse()) {
          console.log(`[NEW] @${USERNAME}: ${t.full_text.slice(0, 140)}`);
        }
        if (newTweets.length) lastSeenId = topId;
      }
    }
  } catch (err) {
    console.error(`Error: ${err.message}`);
    await new Promise((r) => setTimeout(r, POLL_INTERVAL * 2));
    continue;
  }
  await new Promise((r) => setTimeout(r, POLL_INTERVAL));
}

Dos detalles del código de arriba importan. Primero, los IDs de tweets son valores Snowflake y llegan como cadenas. Compararlos como cadenas funciona dentro de una sola ventana de tiempo pero es frágil a través de los límites de longitud de ID; conviértelos a int en Python o BigInt en JavaScript. Segundo, el bucle establece una línea base en la primera llamada exitosa en lugar de volcar la cronología entera. Eso evita una ráfaga de spam al arrancar.

Esto funciona, pero escala mal. Monitorear 50 cuentas significa 50 bucles de sondeo separados y 50 veces las solicitudes a la API. Ahí es donde entran las Listas de X.

Nivel 2: rastrea hasta 5,000 cuentas en una solicitud {#level-2-track-up-to-5000-accounts-in-one-request}

Las Listas de X son la herramienta más útil y más subutilizada para el monitoreo multi-cuenta. Una Lista es un grupo público de cuentas (hasta 5,000), y el endpoint /list-tweets devuelve los últimos tweets combinados de todos los miembros en una sola solicitud. Construye una Lista una vez, apunta tu sondeador a ella y habrás construido en efecto tu propio firehose personalizado sin pagar por el oficial.

Paso 1: crea una Lista pública de X

  1. Ve a Listas de X y crea una lista nueva.
  2. Agrega las cuentas que quieras monitorear (hasta 5,000).
  3. Pon la lista en Pública. Las listas privadas no son accesibles por la API.
  4. Copia el List ID de la URL. Para https://x.com/i/lists/1234567890 el ID es 1234567890.

Paso 2: sondea la lista

python
import requests
import time

API_KEY = "YOUR_API_KEY"
LIST_ID = "YOUR_LIST_ID"
POLL_INTERVAL = 5

URL = f"https://api.sorsa.io/v3/list-tweets?list_id={LIST_ID}"
HEADERS = {"ApiKey": API_KEY, "Accept": "application/json"}


def monitor_list(callback, interval=POLL_INTERVAL):
    """Poll an X List and call `callback` for each new tweet detected."""
    last_seen_id = None
    print(f"Monitoring List {LIST_ID} (interval: {interval}s)")

    while True:
        try:
            resp = requests.get(URL, headers=HEADERS, timeout=10)
            resp.raise_for_status()
            tweets = resp.json().get("tweets", [])

            if not tweets:
                time.sleep(interval)
                continue

            top_id = int(tweets[0]["id"])

            if last_seen_id is None:
                last_seen_id = top_id
                print(f"Baseline set: {last_seen_id}")
            else:
                new_tweets = [t for t in tweets if int(t["id"]) > last_seen_id]
                if new_tweets:
                    for tweet in reversed(new_tweets):
                        callback(tweet)
                    last_seen_id = top_id

        except requests.exceptions.RequestException as e:
            print(f"Request error: {e}. Retrying in {interval * 2}s")
            time.sleep(interval * 2)
            continue

        time.sleep(interval)


def on_new_tweet(tweet):
    user = tweet["user"]
    print(f"[NEW] @{user['username']}: {tweet['full_text'][:120]}")
    print(
        f"       Likes: {tweet.get('likes_count', 0)} | "
        f"RTs: {tweet.get('retweet_count', 0)} | "
        f"Views: {tweet.get('view_count', 'N/A')}\n"
    )


if __name__ == "__main__":
    monitor_list(on_new_tweet)

La ganancia de eficiencia es dramática. Monitorear 50 cuentas por separado a un intervalo de 10 segundos cuesta 432,000 solicitudes al día (50 bucles a 8,640 solicitudes cada uno). Poner esas mismas 50 cuentas en una Lista de X y sondear /list-tweets cuesta 8,640 solicitudes al día. Eso es una reducción de 50 veces sin pérdida de cobertura.

Un detalle a cuidar: /list-tweets devuelve hasta 20 tweets por página. Si tus miembros de Lista publican con tanta frecuencia que llegan más de 20 tweets nuevos dentro de un intervalo de sondeo, puedes perder algunos. Dos arreglos: baja el intervalo a 2 o 3 segundos, o pagina vía next_cursor hasta llegar a un ID visto antes. Para la mayoría de los casos de uso (monitoreo de marca, redacciones, investigación de audiencia), 20 tweets por cada 5 a 10 segundos es más que suficiente margen.

Nivel 3: rastrea palabras clave, hashtags y consultas de búsqueda {#level-3-track-keywords-hashtags-and-search-queries}

El monitoreo por cuenta atrapa lo que dicen las fuentes conocidas. El monitoreo por palabra clave atrapa lo que dice cualquiera sobre tu tema. Usa el endpoint /search-tweets con order: "latest" para obtener resultados cronológicos.

python
import requests
import time

API_KEY = "YOUR_API_KEY"
QUERY = '"your brand" OR @yourbrand lang:en'
POLL_INTERVAL = 10

URL = "https://api.sorsa.io/v3/search-tweets"
HEADERS = {"ApiKey": API_KEY, "Content-Type": "application/json"}


def monitor_keyword(query, callback, interval=10):
    last_seen_id = None
    print(f"Monitoring: {query} (interval: {interval}s)")

    while True:
        try:
            resp = requests.post(
                URL,
                headers=HEADERS,
                json={"query": query, "order": "latest"},
                timeout=10,
            )
            resp.raise_for_status()
            tweets = resp.json().get("tweets", [])

            if tweets:
                top_id = int(tweets[0]["id"])
                if last_seen_id is None:
                    last_seen_id = top_id
                    print(f"Baseline set: {last_seen_id}")
                else:
                    new_tweets = [t for t in tweets if int(t["id"]) > last_seen_id]
                    for tweet in reversed(new_tweets):
                        callback(tweet)
                    if new_tweets:
                        last_seen_id = top_id

        except requests.exceptions.RequestException as e:
            print(f"Error: {e}")
            time.sleep(interval * 2)
            continue

        time.sleep(interval)

El poder real vive en la cadena de consulta. La API admite el conjunto completo de operadores de la búsqueda avanzada de Twitter (una referencia no oficial está en igorbrigadir/twitter-advanced-search). Por ejemplo, para rastrear menciones en inglés de tu marca con alto engagement y saltar los retweets:

python
monitor_keyword('"your brand" min_faves:10 lang:en -filter:retweets', on_new_tweet)

Unos operadores que se ganan su lugar en el monitoreo en tiempo real:

  • min_faves:N, min_retweets:N para filtrar contenido que ya es tendencia.
  • -filter:retweets, -filter:replies para descartar ruido.
  • from:user1 OR from:user2 para monitorear un puñado de cuentas sin una Lista.
  • (keyword1 OR keyword2) (problem OR issue OR broken) para atrapar menciones cargadas de sentimiento.
  • near:"san francisco" within:25mi para monitoreo acotado por geografía.

Los flujos de palabras clave en 2026 son más ruidosos de lo que solían: respuestas automatizadas, cuentas de estafa y spam generado por IA se apilan sobre cualquier término popular. Los umbrales de engagement son tu filtro más barato en la fuente. Un piso como min_faves:5 o min_replies:2 quita la mayor parte del ruido desechable antes de que llegue a tu callback, así que conservas posts con al menos algo de tracción. Si estás específicamente vigilando menciones de un usuario en lugar de palabras clave abiertas, la API de menciones de Twitter expone el conjunto de filtros más rico (min_likes, min_replies, min_retweets, límites de fecha) para exactamente este tipo de limpieza.

Si tu cadena de consulta empieza a sentirse difícil de manejar, el playground constructor de búsquedas te deja armar una de forma visual y ver el conjunto completo de operadores sobre la marcha.

Envía tweets nuevos a Slack, Discord o cualquier endpoint HTTP {#push-new-tweets-to-slack-discord-or-any-http-endpoint}

El bucle de sondeo es el productor. El callback es donde decides qué le pasa a cada tweet nuevo. Como el callback es solo una función, el mismo monitor puede enrutar a cualquier cosa que hable HTTP. Slack primero porque es el destino más común, luego unas variantes rápidas.

Slack vía Incoming Webhook

python
import requests

SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"


def send_to_slack(tweet):
    user = tweet["user"]
    text = (
        f"*New tweet from @{user['username']}*\n"
        f"{tweet['full_text']}\n"
        f"Likes: {tweet.get('likes_count', 0)} | "
        f"RTs: {tweet.get('retweet_count', 0)} | "
        f"Views: {tweet.get('view_count', 'N/A')}\n"
        f"https://x.com/{user['username']}/status/{tweet['id']}"
    )
    requests.post(SLACK_WEBHOOK_URL, json={"text": text})


# Plug into any monitor:
monitor_list(send_to_slack)
# or: monitor_keyword("bitcoin lang:en min_faves:50", send_to_slack)

Configura la URL del Incoming Webhook de Slack en la configuración de tu app de Slack (documentación oficial de Slack). El mismo patrón para Discord, Telegram o cualquier endpoint interno.

Discord

python
DISCORD_WEBHOOK_URL = "https://discord.com/api/webhooks/YOUR/WEBHOOK"


def send_to_discord(tweet):
    user = tweet["user"]
    content = (
        f"**@{user['username']}** just tweeted:\n"
        f"{tweet['full_text']}\n"
        f"https://x.com/{user['username']}/status/{tweet['id']}"
    )
    requests.post(DISCORD_WEBHOOK_URL, json={"content": content})

El montaje de webhooks de Discord está documentado en discord.com/developers/docs/resources/webhook.

Telegram

python
TELEGRAM_BOT_TOKEN = "YOUR_BOT_TOKEN"
TELEGRAM_CHAT_ID = "YOUR_CHAT_ID"


def send_to_telegram(tweet):
    user = tweet["user"]
    text = (
        f"New tweet from @{user['username']}\n\n"
        f"{tweet['full_text']}\n\n"
        f"https://x.com/{user['username']}/status/{tweet['id']}"
    )
    requests.post(
        f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage",
        json={"chat_id": TELEGRAM_CHAT_ID, "text": text},
    )

Cualquier endpoint HTTP personalizado

python
def send_to_internal_api(tweet):
    requests.post(
        "https://internal.example.com/events/twitter",
        json={
            "tweet_id": tweet["id"],
            "username": tweet["user"]["username"],
            "text": tweet["full_text"],
            "metrics": {
                "likes": tweet.get("likes_count", 0),
                "retweets": tweet.get("retweet_count", 0),
                "views": tweet.get("view_count", 0),
            },
            "url": f"https://x.com/{tweet['user']['username']}/status/{tweet['id']}",
        },
        headers={"Authorization": "Bearer YOUR_INTERNAL_TOKEN"},
        timeout=5,
    )

Lo que has construido es, en efecto, tu propio relevo de webhooks. La API provee los datos; tu callback decide quién se entera de cada tweet nuevo. La ventaja de ser dueño de ese relevo tú mismo es que mantienes todas las reglas de enrutamiento en tu código (filtrado, límite de tasa, distribución a varios canales, política de reintento) en lugar de que vivan dentro de un panel de proveedor.

¿Cada cuánto sondear y cuánto cuesta? {#how-often-should-you-poll-and-what-does-it-cost}

Cada ciclo de tu bucle cuesta una solicitud, y una solicitud de Sorsa es una unidad de tu plan sin importar qué endpoint toque. El intervalo que elijas impulsa tu uso mensual directamente, y con precio de tarifa plana por solicitud mapea limpio a un plan.

IntervaloSolicitudes / horaSolicitudes / díaSolicitudes / 30 díasPlan para un bucle
1 segundo3,60086,4002,592,000Personalizado (arriba de Enterprise)
5 segundos72017,280518,400Personalizado (justo arriba de Enterprise)
10 segundos3608,640259,200Enterprise ($899/mes)
30 segundos1202,88086,400Pro ($199/mes)
1 minuto601,44043,200Pro ($199/mes)

Las cifras son para un solo bucle continuo; correr varios bucles en paralelo suma sus conteos de solicitudes. Las cuotas de los planes son Starter 10K, Pro 100K y Enterprise 500K solicitudes al mes, con cuotas personalizadas por encima.

Unas cuantas pautas prácticas de correr estos bucles en producción:

  • Escucha de marca, monitoreo de noticias, generación de leads: de 10 a 30 segundos alcanza de sobra. Atrapas cualquier tweet nuevo dentro de medio minuto de su publicación, y la huella mensual es chica.
  • Detección de señales financieras, bots de noticias de última hora, flujos de trading: de 1 a 5 segundos. Quemarás más solicitudes pero el presupuesto de latencia lo justifica.
  • Cumplimiento, auditoría, investigación de movimiento lento: de 1 a 5 minutos. El tiempo real es exagerado para casos de uso donde la ventana de acción se mide en horas.

Una cadencia de 30 segundos a 1 minuto sobre una sola Lista cabe dentro del plan Pro a $199 al mes. Apretar a un bucle de 10 segundos (unas 259,000 solicitudes) te mueve a Enterprise a $899, e incluso un bucle de 1 segundo sobre un objetivo de alta prioridad se queda muy por debajo de lo que cobra la API oficial de X por acceso comparable en tiempo real.

Endurecimiento de producción: cinco cosas que arreglar antes de salir en vivo {#production-hardening-five-things-to-fix-before-going-live}

Los ejemplos de arriba son deliberadamente mínimos. Antes de apuntar uno de estos a tráfico de producción, atiende estas cinco preocupaciones.

1. Persiste last_seen_id entre reinicios

Si tu script se cae y reinicia sin recordar su punto de control, dos cosas salen mal: o reprocesa tweets viejos (alertas duplicadas a tu canal de Slack) o fija una línea base fresca y salta el hueco en silencio. Guarda el punto de control en un archivo, Redis o tu base de datos.

python
import json
import os

STATE_FILE = "monitor_state.json"


def load_state():
    if os.path.exists(STATE_FILE):
        with open(STATE_FILE) as f:
            return json.load(f).get("last_seen_id")
    return None


def save_state(last_seen_id):
    with open(STATE_FILE, "w") as f:
        json.dump({"last_seen_id": last_seen_id}, f)

Carga al arrancar, guarda tras cada sondeo exitoso que actualice el cursor.

2. Retroceso exponencial ante errores

Problemas de red, respuestas 5xx transitorias y golpes de límite de tasa (HTTP 429) pasan. En lugar de reintentar de inmediato y empeorar las cosas, retrocede de forma gradual con un tope.

python
retry_delay = POLL_INTERVAL
MAX_DELAY = 60

while True:
    try:
        resp = requests.get(URL, headers=HEADERS, timeout=10)
        if resp.status_code == 429:
            print(f"Rate limited. Backing off {retry_delay}s")
            time.sleep(retry_delay)
            retry_delay = min(retry_delay * 2, MAX_DELAY)
            continue
        resp.raise_for_status()
        retry_delay = POLL_INTERVAL  # reset on success
        # process tweets
    except requests.exceptions.RequestException as e:
        print(f"Error: {e}")
        time.sleep(retry_delay)
        retry_delay = min(retry_delay * 2, MAX_DELAY)
        continue

    time.sleep(POLL_INTERVAL)

Retrocede de forma gradual, pon un tope al retraso y reinicia a tu intervalo normal en el primer éxito para que un 429 breve no deje tu monitor atado a una cadencia lenta.

3. Desacopla el sondeo del procesamiento

No corras operaciones costosas (puntuación de sentimiento, escrituras a base de datos, llamadas a APIs externas, clasificación con IA) de forma síncrona dentro del bucle de sondeo. Si un sistema río abajo se ralentiza, tu bucle se atrasa y la latencia se dispara. Empuja los tweets nuevos a una cola y procésalos en un worker separado.

python
from collections import deque
import threading

tweet_queue = deque()


def polling_loop():
    """Fast loop: poll and enqueue. No heavy work here."""
    # standard polling code, but instead of calling the callback directly:
    # tweet_queue.append(tweet)
    pass


def processing_worker():
    """Separate thread: dequeue and dispatch."""
    while True:
        if tweet_queue:
            tweet = tweet_queue.popleft()
            send_to_slack(tweet)
            save_to_database(tweet)
        else:
            time.sleep(0.1)


threading.Thread(target=processing_worker, daemon=True).start()
polling_loop()

Para cargas más pesadas, cambia el deque en memoria por Redis, RabbitMQ, SQS o cualquier broker de mensajes que tu stack ya corra.

4. Comprobaciones de salud y monitorear el monitor

Registra cada ciclo de sondeo: marca de tiempo, conteo de tweets nuevos, tiempo de respuesta, errores. Alerta si el monitor no ha completado un sondeo exitoso en los últimos N minutos. Las fallas silenciosas son las más caras, sobre todo en pipelines de alertas donde la ausencia de alertas significa "no pasó nada" hasta que alguien nota el hueco de datos. Puedes revisar el estado operativo de la API en la página de estado de Sorsa para descartar problemas de plataforma antes de depurar tu propio código.

5. Maneja los casos límite que dan problemas en producción

  • Tweets borrados: si un tweet se borra entre que lo obtuviste y que se dispara tu callback, la URL dará 404. Trátalo como esperado, no como un error.
  • Cuentas protegidas: si un usuario rastreado se vuelve privado, /user-tweets devolverá una lista vacía. Registra y continúa.
  • Tweets fijados: el primer tweet en una respuesta de /user-tweets suele ser el tweet fijado, no el más reciente. Ordena por created_at si te importa el orden cronológico estricto.
  • Retweets vs tweets originales: tweet["retweeted_status"] está poblado para los retweets. Decide si quieres ambos o solo los originales.
  • Respuestas limitadas por tasa: is_replies_limited indica que el autor restringió las respuestas. Señal útil para algunos casos de uso de monitoreo.

En la práctica: una migración de monitoreo de marca {#in-practice-a-brand-monitoring-migration}

Una empresa SaaS con la que trabajamos venía corriendo monitoreo de marca sobre el filtered stream oficial desde 2018. Su montaje rastreaba aproximadamente 200 reglas de palabras clave y 60 cuentas prioritarias, y para inicios de 2024 costaba $5,000 al mes en el nivel Pro. El argumento interno fue directo: corta el stream, ahorra el dinero y confía en que nada se rompa.

La migración tomó dos semanas. Fusionamos las reglas de palabras clave en dos workers compuestos de /search-tweets (las reglas se colapsaron en consultas booleanas con operadores OR) sondeando cada 30 segundos, y reemplazamos el seguimiento de 60 cuentas con una Lista de X sondeada cada 15 segundos. La huella combinada llegó a unas 350,000 solicitudes al mes, cómodamente dentro del plan Enterprise a $899 al mes contra los $5,000 que venían pagando. La latencia de alerta de extremo a extremo pasó de aproximadamente 2 segundos en el filtered stream a aproximadamente 15 segundos en el percentil 90. Para un equipo de relaciones públicas respondiendo a menciones de marca en Slack, el cambio de latencia fue invisible. El cambio de factura no.

Casos de uso donde este enfoque se gana su lugar {#use-cases-where-this-approach-earns-its-keep}

Cinco patrones que vemos con más frecuencia.

Escucha de marca y CRM social. Sondea /search-tweets por el usuario de tu marca más palabras clave de nombres de producto, cada 15 a 30 segundos. Enruta a Slack con pistas de sentimiento integradas en el mensaje, y el equipo de relaciones públicas responde en minutos. Este es el núcleo de cualquier montaje de escucha de marca y social listening.

Detección de noticias y señales. Construye una Lista de usuarios de noticias de última hora (Reuters, AP, Bloomberg, medios regionales, reporteros de fuente) y sondéala cada 5 segundos. Distribuye a un servidor de Discord o a un panel de trading. Esta es la versión más barata de un "firehose de noticias" que puedes construir en 2026.

Inteligencia competitiva. Una Lista de cuentas competidoras más sus CEOs y líderes de producto, sondeada cada 30 segundos. Los tweets nuevos aterrizan en un canal compartido, y tu equipo de marketing de producto obtiene un feed de inteligencia gratis sin que nadie tenga que abrir 40 perfiles. Esta es la capa en vivo de un montaje continuo de seguimiento de competidores.

Generación de leads. Sondea /search-tweets por consultas de planteamiento de problema: "any recommendations for" (CRM OR analytics OR transcription), "looking for an alternative to", "we just churned from". Enruta a un canal de Slack revisado por ventas. La mayoría de los equipos que corren esto atrapan de 5 a 15 leads calificados por semana por grupo de consultas. Es el motor en tiempo real detrás de la generación de leads en Twitter a escala.

Señales de KOL cripto. Construye una Lista de influencers cripto y cuentas de proyectos, sondea a 2 a 5 segundos y opcionalmente pondera las señales por calidad de audiencia usando los endpoints de Sorsa Score.

Costo vs la API oficial de X para monitoreo en tiempo real {#cost-vs-the-official-x-api-for-real-time-monitoring}

Divulgación: Sorsa es nuestro producto, así que trata esto como nuestra lectura y prueba cualquier opción contra tu propia carga. Los números de ambos lados son reales y vigentes a julio de 2026.

Los dos proveedores cobran en unidades completamente distintas. La API oficial de X cobra por recurso consultado: bajo el modelo de pago por uso vigente desde inicios de 2026, cada lectura de post cuesta $0.005 y el perfil del autor adjunto a un tweet es una lectura de usuario separada de $0.010. Sorsa cobra por solicitud, y una solicitud devuelve aproximadamente 20 tweets (o hasta 200 perfiles en endpoints de seguidores) con los datos del autor incluidos. Esa brecha estructural es lo que impulsa la diferencia de costo para el monitoreo.

API oficial de X (pago por uso, 2026)Sorsa
Modelo de preciosPor recurso consultadoDe tarifa plana por solicitud (1 llamada = 1 solicitud)
Lecturas de posts$0.005 por lectura de postIncluidas en la solicitud, sin cargo por post
Perfil del autor en un tweetSe cobra por separado, $0.010 por lectura de usuarioIncluido gratis en la respuesta del tweet
Monitoreo 24/7 (~1.7M lecturas de posts/mes)~$8,600/mesPlan Enterprise, $899/mes
Tope mensual de lectura2M lecturas de posts, luego se requiere EnterpriseCuota por plan, sin tope por post
Por encima del topeContrato Enterprise, históricamente ~$42,000+/mesPlan personalizado con cuota elevada
AutenticaciónOAuth 2.0 + Bearer tokenUna sola clave API en un encabezado
Límite de tasaVaría por endpoint20 solicitudes por segundo en todos los planes

El intercambio es la latencia: el filtered stream aterriza tweets en un segundo o dos, mientras que el sondeo los aterriza dentro de tu intervalo más unos 300ms de tiempo de respuesta. Para la mayoría de los casos de uso de monitoreo esa brecha es invisible. Para bots de trading por debajo del segundo, no lo es, y un stream de verdad es la herramienta correcta sin importar el proveedor. Pero para monitoreo intensivo en lecturas a escala de marca, noticias o competencia, pagar por post entregado suma rápido y choca con el muro de los 2 millones de lecturas, donde un plan de tarifa plana por solicitud no. Para el desglose completo de precios por caso de uso, revisa precios de la API de Twitter en 2026.

Preguntas frecuentes {#faq}

¿El sondeo REST es de verdad "en tiempo real"?

El sondeo REST es casi en tiempo real. El presupuesto de latencia es el intervalo de sondeo más el tiempo de respuesta de la API, que ronda los 300ms en un endpoint rápido. A un intervalo de 5 segundos, el peor caso es de aproximadamente 5.3 segundos desde que un tweet se publica hasta que se dispara tu callback. Para la enorme mayoría de los casos de uso de monitoreo eso cumple la definición práctica de tiempo real; solo el trading a escala de milisegundos y la subasta de eventos en vivo necesitan un stream de verdad.

¿Cuántas cuentas puedo monitorear con una clave API?

Con Sorsa, una clave API puede monitorear un número prácticamente ilimitado de cuentas a través de Listas de X. Una sola Lista contiene hasta 5,000 cuentas y cuenta como una solicitud /list-tweets por sondeo. Varias Listas corren en paralelo dentro del límite de 20 solicitudes por segundo, lo que deja espacio para cientos de trabajos de monitoreo concurrentes en una sola clave.

¿Qué pasa si llego al límite de tasa?

Sorsa devuelve una respuesta HTTP 429 cuando excedes su límite de 20 solicitudes por segundo. Retrocede un segundo, reintenta y el bucle continúa; no hay caja de castigo ni bloqueo. La mayoría de las cadencias de sondeo se quedan muy por debajo de 20 solicitudes por segundo, así que los monitores de producción rara vez ven un 429 siquiera, y hay límites más altos disponibles a pedido.

¿Cómo evito alertas duplicadas cuando mi script reinicia?

Para evitar alertas duplicadas, persiste el último ID de tweet visto en almacenamiento durable (un archivo, Redis o una base de datos) tras cada sondeo exitoso. Al arrancar, carga ese ID y úsalo como línea base para que el bucle solo despache tweets más nuevos que el punto de control. Sin persistencia, un reinicio o reproduce tweets viejos o salta el hueco en silencio.

¿Puedo monitorear cuentas privadas o protegidas?

Ninguna herramienta puede acceder a cuentas privadas o protegidas de Twitter/X, y Sorsa saca a la superficie solo datos públicos. Si una cuenta rastreada se vuelve privada a mitad del monitoreo, el endpoint devuelve una lista vacía y el bucle de sondeo continúa sin error. Esta es una regla de privacidad a nivel de plataforma, no una limitación específica de un proveedor.

¿Se admiten webhooks administrados?

Sorsa no lanza un producto de webhook administrado; la vía en tiempo real admitida es el patrón de sondeo de esta guía, donde tu propio callback enruta cada tweet nuevo. La ventaja es el control total sobre el filtrado, la distribución y la lógica de reintento en tu propio código. Los equipos que específicamente quieren entrega push alojada por el proveedor mirarían los webhooks de Account Activity de la API oficial de X en niveles enterprise.

¿Qué tan frescos son los datos devueltos?

Los datos son frescos en cada solicitud, sin capa de caché entre tu llamada y la plataforma. Si un tweet se publicó hace medio segundo, el siguiente sondeo lo recoge. Combinado con tiempos de respuesta de alrededor de 300ms, esa frescura es lo que hace viable el sondeo para monitoreo en lugar de solo analítica después de los hechos.

¿Puedo combinar monitoreo en tiempo real con relleno histórico?

Sí, y la mayoría de los pipelines de producción hacen ambas cosas. Los mismos endpoints usados para monitoreo (/user-tweets, /search-tweets, /list-tweets) aceptan un parámetro next_cursor para paginar hacia atrás por el historial en un relleno único, y luego cambias al bucle de sondeo para los datos nuevos de ahí en adelante. Revisa nuestra guía de datos históricos de Twitter para el lado del relleno.

Cómo empezar {#getting-started}

Para construir tu propio pipeline de monitoreo en tiempo real:

  1. Toma una clave API desde el panel de Sorsa. Una clave funciona en todos los endpoints, y cada cuenta arranca con 100 solicitudes gratis (por única vez, sin tarjeta) para que puedas armar un bucle antes de elegir un plan.
  2. Prueba de forma interactiva en el playground de la API: golpea /user-tweets o /list-tweets con un nombre de usuario o ID de lista conocido y confirma que ves resultados en vivo.
  3. Copia uno de los bucles de este artículo (una cuenta, Lista o palabra clave) y reemplaza la clave API.
  4. Agrega un callback que enrute a donde quieras las alertas (Slack, Discord, API interna, cola).
  5. Agrega el endurecimiento de producción (persistencia de estado, retroceso, procesamiento desacoplado) una vez que el bucle básico sea estable.

Estima tu uso mensual con la tabla de intervalos, elige un plan y despliega. La guía de inicio rápido recorre la primera llamada de principio a fin. Si necesitas límites de tasa más altos o volumen por encima de los planes estándar, habla con ventas y armaremos una cuota personalizada.


Revisado por Keksich, fundador de Sorsa, especialista en marketing e investigador de la API de X.

Esta guía la escribe y mantiene el equipo que construye y opera Sorsa, una API alternativa de Twitter/X que ha servido más de 5 mil millones de solicitudes desde 2022. Cada ejemplo de código corre contra los endpoints /user-tweets, /list-tweets y /search-tweets en vivo, y los patrones de sondeo, retroceso y persistencia salen de bucles de monitoreo que corremos en producción. La comparación de costos refleja el modelo de pago por uso de la API oficial de X vigente tras la actualización de abril de 2026, con los detalles de precio y límite de tasa verificados en julio de 2026. Más sobre el equipo en nuestra página Acerca de.