Ir al contenido

Cómo migrar desde la API de Twitter/X

Migrar desde la API oficial de X requiere cinco cambios de código: asignar cada endpoint v2 a su nueva ruta, cambiar OAuth por una clave de API, quitar campos y expansiones, reescribir el análisis del JSON y cambiar el token de paginación.

Respuesta corta: Lo que conviene migrar son las lecturas: la API oficial de X cobra $0.005 por post y $0.010 por usuario, y desde el 22 de noviembre de 2026 cada autor devuelto con un post suma $0.010. Para migrarlas, usa Sorsa API: un solo encabezado ApiKey, 20 tweets por solicitud de búsqueda desde $0.07 por 1,000 y 100 solicitudes gratis para probar el mapa.

Endpoint
POST /search-tweets
Tamaño de página
20 tweets por solicitud
Precio
desde $0.07 por 1,000

#Qué cambió en la API oficial de X desde 2023

El código escrito para la API oficial de X en su mayor parte sigue funcionando; lo que cambió desde 2023 es qué puede llamar, qué recibe de vuelta y cuánto cuesta cada respuesta. La lista con fechas de abajo sale del changelog (se abre en una pestaña nueva) de X y de los avisos de su foro de desarrolladores, con la parte de una integración que alcanza cada cambio.

FechaCambio en la API oficial de XQué le hace a tu código
30 mar 2023Los niveles de pago sustituyen al acceso gratuito; Free pasa a ser solo de escrituraLas lecturas en una app gratuita devuelven errores
26 jun 2023Se eliminan los endpoints de follows de Basic y ProLas llamadas de seguidores y seguidos se detienen en esos planes
28 sep 2023search/tweets y users/search de la v1.1 quedan obsoletosEl código de búsqueda de la v1.1 necesita un endpoint nuevo
19 ene 2026min_likes, min_replies, min_reposts se eliminan de la búsquedaLas consultas que los usaban tuvieron que quitarlos hasta el 4 de mayo
6 feb 2026El pago por uso pasa a ser el modelo; créditos comprados por adelantadoLas llamadas se bloquean cuando el saldo llega a cero
23 feb 2026Las respuestas programáticas solo se permiten cuando el autor te invocaLos bots de respuestas son rechazados
20 abr 2026Seguir, dar me gusta y citar posts se quitan del autoservicioEsas llamadas de escritura dejan de funcionar
4 may 2026La búsqueda pasa a un índice nuevo; los retweets salen de los resultados por palabra claveLa misma consulta devuelve menos posts
1 jun y 1 sep 2026Los planes heredados Basic, y luego Pro, pasan al pago por usoUn tope mensual se convierte en una factura por recurso
22 nov 2026Se cobran las expansiones: $0.010 por autor, $0.005 por elemento multimediaexpansions=author_id puede triplicar el costo de un post
  • 30 mar 2023

    Cambio en la API oficial de X
    Los niveles de pago sustituyen al acceso gratuito; Free pasa a ser solo de escritura
    Qué le hace a tu código
    Las lecturas en una app gratuita devuelven errores
  • 26 jun 2023

    Cambio en la API oficial de X
    Se eliminan los endpoints de follows de Basic y Pro
    Qué le hace a tu código
    Las llamadas de seguidores y seguidos se detienen en esos planes
  • 28 sep 2023

    Cambio en la API oficial de X
    search/tweets y users/search de la v1.1 quedan obsoletos
    Qué le hace a tu código
    El código de búsqueda de la v1.1 necesita un endpoint nuevo
  • 19 ene 2026

    Cambio en la API oficial de X
    min_likes, min_replies, min_reposts se eliminan de la búsqueda
    Qué le hace a tu código
    Las consultas que los usaban tuvieron que quitarlos hasta el 4 de mayo
  • 6 feb 2026

    Cambio en la API oficial de X
    El pago por uso pasa a ser el modelo; créditos comprados por adelantado
    Qué le hace a tu código
    Las llamadas se bloquean cuando el saldo llega a cero
  • 23 feb 2026

    Cambio en la API oficial de X
    Las respuestas programáticas solo se permiten cuando el autor te invoca
    Qué le hace a tu código
    Los bots de respuestas son rechazados
  • 20 abr 2026

    Cambio en la API oficial de X
    Seguir, dar me gusta y citar posts se quitan del autoservicio
    Qué le hace a tu código
    Esas llamadas de escritura dejan de funcionar
  • 4 may 2026

    Cambio en la API oficial de X
    La búsqueda pasa a un índice nuevo; los retweets salen de los resultados por palabra clave
    Qué le hace a tu código
    La misma consulta devuelve menos posts
  • 1 jun y 1 sep 2026

    Cambio en la API oficial de X
    Los planes heredados Basic, y luego Pro, pasan al pago por uso
    Qué le hace a tu código
    Un tope mensual se convierte en una factura por recurso
  • 22 nov 2026

    Cambio en la API oficial de X
    Se cobran las expansiones: $0.010 por autor, $0.005 por elemento multimedia
    Qué le hace a tu código
    expansions=author_id puede triplicar el costo de un post

Dos de estos cambios alteraron los resultados sin cambiar una sola línea de código. Desde que el nuevo índice de búsqueda (se abre en una pestaña nueva) entró en funcionamiento el 4 de mayo, una búsqueda por palabra clave que funcionaba bien en abril devuelve resultados sin retweets. Y desde el 22 de noviembre, la misma solicitud con expansions=author_id que costaba $5.00 por 1,000 posts cuesta hasta $15.00, porque el aviso de expansiones (se abre en una pestaña nueva) de X cobra cada autor devuelto como una lectura de usuario.

Los planes también cambiaron bajo el código en ejecución. X terminó las suscripciones de Basic heredado (se abre en una pestaña nueva) en sus fechas de transición posteriores al 1 de junio de 2026, y las de Pro heredado (se abre en una pestaña nueva) después del 1 de septiembre; a una cuenta mensual de Pro se le cargó un crédito de $5,000 en la transición, con la recarga automática activada. Ahora cada lectura descuenta créditos a $0.005 por post y $0.010 por usuario o seguidor, hasta 3M de lecturas de posts al mes, y la tarifa completa está en nuestro desglose de los precios de la API de X.

#Qué pasa a Sorsa API y qué se queda en X

Toda lectura de datos públicos puede migrarse: búsqueda, timelines, consultas de posts y usuarios, seguidores, listas, citas, quienes hicieron retweet, respuestas, Spaces, comunidades y tendencias. Sorsa API, una API y scraper de Twitter (X) en producción desde 2022, con más de 6 mil millones de solicitudes procesadas, devuelve todo eso con una sola clave, sin OAuth y, como explica la guía de la API de Twitter sin cuenta de desarrollador, sin cuenta de desarrollador de X. Es de solo lectura por diseño, así que las llamadas que escriben se quedan donde están.

Deja estas en la API oficial de X:

  • Publicar, responder, borrar y subir contenido multimedia.
  • Mensajes directos, y me gusta, follows, marcadores y bloqueos, ya sean acciones o listas de la actividad de tu propia cuenta.
  • Quién dio me gusta a un post, y cualquier cosa de cuentas protegidas.
  • Filtered stream, firehose, webhooks y la API X Activity: Sorsa API se consulta por sondeo, no recibe envíos (el patrón de sondeo está más abajo).
  • Conteos de posts, Community Notes y la API de Ads.

Tu cuenta de X no participa en las lecturas, porque Sorsa API nunca pide tu usuario ni tus cookies. Después de la separación, la API oficial de X solo cobra las escrituras, por solicitud: $0.015 por post creado y $0.20 por un post con un enlace.

Las lecturas son donde se va el dinero. En lecturas de búsqueda y de timelines, 1M de tweets cuestan $5,000 en la API oficial de X antes de cobrar los autores, y desde $70 en Sorsa API, que devuelve el autor de cada tweet dentro de él sin costo adicional. Las consultas por ID rinden más: POST /tweet-info-bulk devuelve 100 tweets por solicitud, desde $0.014 por 1,000.

Tweets leídos por búsqueda

API oficial de X

$5,000

para 1M tweets

$0.005 por post, sin autores

Sorsa API

desde$70

para 1M tweets

desde $0.07 por 1,000, autor incluido

#Migra a Sorsa API en seis pasos

Seis pasos llevan una integración v2 desde el inventario hasta el cambio definitivo. Los primeros cinco son ediciones de tu código; el último dura unos días, mientras ambas API responden las mismas lecturas.

  1. Lista cada llamada que hace tu código. Busca en el código api.x.com/2, api.twitter.com/2 y los nombres de método de tu cliente, como search_recent_tweets de Tweepy o posts.search_recent de xdk. Exporta el uso del último mes por recurso en la Developer Console de X y marca cada llamada como lectura o escritura.

  2. Consigue una clave y envía una solicitud. Regístrate, copia la clave del panel y llama al endpoint que reemplaza tu lectura más usada.

    Terminal
    curl -X POST "https://api.sorsa.io/v3/search-tweets" \
      -H "ApiKey: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query": "from:mira_moves_reads", "order": "latest"}'
    
    Respuesta200 OK
    {
      "tweets": [
        {
          "id": "1852331946812457001",
          "full_text": "Read path moved. Writes stay where they were.",
          "created_at": "2026-10-30T14:05:12Z",
          "lang": "en",
          "likes_count": 41,
          "retweet_count": 6,
          "reply_count": 3,
          "quote_count": 1,
          "view_count": 2380,
          "conversation_id_str": "1852331946812457001",
          "is_reply": false,
          "user": {
            "id": "1592041833471827968",
            "username": "mira_moves_reads",
            "display_name": "Mira Moves Reads",
            "followers_count": 912,
            "verified": false
          }
        }
      ],
      "next_cursor": "DAADDAABCgABGbHk7m4WYAEKAAIZsd"
    }
    
  3. Asigna cada lectura a su endpoint. La tabla y el conversor de la sección siguiente emparejan cada lectura v2 con su ruta y sus parámetros en Sorsa API.

  4. Cambia OAuth, campos y expansiones por un solo encabezado. En las llamadas de lectura, elimina el bearer token o la firma OAuth 1.0a y envía ApiKey: YOUR_API_KEY en su lugar. Quita tweet.fields, user.fields y expansions: todos los campos y el autor llegan por defecto.

  5. Reescribe el análisis y la paginación. Lee tweets o users donde leías data e includes, renombra los campos que difieren y envía next_cursor de vuelta hasta que llegue vacío.

  6. Ejecuta en paralelo y luego cambia. Envía una copia de tus lecturas a Sorsa API durante unos días, compara los resultados, mueve el tráfico por etapas y conserva la clave de X para las escrituras.

#Asigna cada endpoint de la API v2 de X a Sorsa API

Cada lectura pública que una integración probablemente llame tiene un endpoint de Sorsa API. La tabla empareja cada ruta v2, tal como está escrita en la especificación OpenAPI (se abre en una pestaña nueva) de X, con su reemplazo y con cuánto devuelve una solicitud; Sorsa API cobra por solicitud, no por elemento, así que la última columna fija el precio.

Llamada de la API v2 de XEndpoint de Sorsa APIUna solicitud devuelve
GET /2/tweets/search/recentPOST /search-tweets (se abre en una pestaña nueva)unos 20 tweets
GET /2/tweets/search/allPOST /search-tweets con since: y until:unos 20 tweets
GET /2/tweets/:idPOST /tweet-info (se abre en una pestaña nueva)1 tweet
GET /2/tweets (por IDs)POST /tweet-info-bulk (se abre en una pestaña nueva)hasta 100 tweets
GET /2/users/:id/tweetsPOST /user-tweets (se abre en una pestaña nueva)unos 20 tweets
GET /2/users/:id/mentionsPOST /mentions (se abre en una pestaña nueva)unos 20 tweets
GET /2/tweets/:id/quote_tweetsPOST /quotes (se abre en una pestaña nueva)unos 20 tweets
GET /2/tweets/:id/retweeted_byPOST /retweeters (se abre en una pestaña nueva)una página de perfiles
Búsqueda con conversation_id:POST /comments (se abre en una pestaña nueva)unas 20 respuestas
GET /2/users/by/username/:usernameGET /info (se abre en una pestaña nueva)1 perfil
GET /2/users y GET /2/users/byGET /info-batch (se abre en una pestaña nueva)hasta 100 perfiles
GET /2/users/:id/followersGET /followers (se abre en una pestaña nueva)hasta 200 perfiles
GET /2/users/:id/followingGET /follows (se abre en una pestaña nueva)hasta 200 perfiles
GET /2/users/searchPOST /search-users (se abre en una pestaña nueva)una página de perfiles
GET /2/lists/:id/membersGET /list-members (se abre en una pestaña nueva)una página de perfiles
GET /2/lists/:id/followersGET /list-followers (se abre en una pestaña nueva)una página de perfiles
GET /2/lists/:id/tweetsGET /list-tweets (se abre en una pestaña nueva)unos 20 tweets
GET /2/spaces/:idGET /spaces (se abre en una pestaña nueva)1 Space
GET /2/communities/:idPOST /community-info (se abre en una pestaña nueva)1 comunidad
GET /2/communities/searchPOST /search-communities (se abre en una pestaña nueva)una página de comunidades
GET /2/trends/by/woeid/:woeidGET /trends (se abre en una pestaña nueva)las tendencias de 1 ubicación
GET /2/usage/tweetsGET /key-usage-info (se abre en una pestaña nueva)tu saldo, sin costo

Cuatro hábitos cambian con las rutas. Los endpoints de tweets usan POST con un cuerpo JSON, mientras que las consultas de usuarios, listas y utilidades siguen siendo GET. Un nombre de usuario sirve donde la v2 pedía un ID numérico, así que desaparece la consulta extra antes de cada llamada de timeline. tweet_link acepta la URL completa de un post o un ID simple. Y POST /user-tweets sigue paginando más allá de los 3,200 posts más recientes, donde se detiene el timeline de usuario de X.

Algunas lecturas de la v2 no tienen equivalente, porque Sorsa API devuelve solo lo que cualquiera puede ver en un perfil público: usuarios que dieron me gusta, los me gusta y marcadores de un usuario, conteos de posts, el timeline de inicio y todos los streams. Sorsa API también responde preguntas que la v2 no puede: POST /check-follow (se abre en una pestaña nueva) indica en una solicitud si una cuenta sigue a otra, y GET /about (se abre en una pestaña nueva) devuelve el país de una cuenta y el historial de sus nombres de usuario.

El conversor de abajo convierte una llamada v2 a la vez en su solicitud de Sorsa API, con los campos que cambian y el precio de 1,000 resultados de cada lado.

Antes: API oficial de X v2
curl -G "https://api.x.com/2/tweets/search/recent" \
  -H "Authorization: Bearer $X_BEARER_TOKEN" \
  --data-urlencode "query=from:mira_moves_reads" \
  -d "max_results=100" \
  -d "expansions=author_id" \
  -d "tweet.fields=created_at,public_metrics"
Después: Sorsa API
curl -X POST "https://api.sorsa.io/v3/search-tweets" \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "from:mira_moves_reads", "order": "latest"}'
Endpoint de Sorsa API
POST /search-tweets
Una solicitud devuelve
unos 20 tweets
API oficial de X, 1,000 resultados
$5.00, más hasta $10.00 por los autores
Sorsa API, 1,000 resultados
desde $0.07

Paginación: next_token pasa a ser next_cursor en el cuerpo JSON. La misma consulta busca hasta 2006, no solo 7 días, y cada tweet trae a su autor.

Elige la llamada v2 que hace tu código para ver la misma solicitud en Sorsa API y cuánto cuestan 1,000 resultados en cada una.

Si tu código usa filtered stream o webhooks

Sorsa API no tiene stream ni webhook, así que una regla de filtered stream se convierte en una consulta de búsqueda que consultas por sondeo. Envía la regla como consulta de POST /search-tweets con "order": "latest", agrega since_id: con el ID más reciente que tengas guardado y sigue next_cursor para que un minuto movido con más de 20 posts nuevos no pierda ninguno.

poll.py
import os
import time
import requests

URL = "https://api.sorsa.io/v3/search-tweets"
HEADERS = {"ApiKey": os.environ.get("SORSA_API_KEY", "YOUR_API_KEY")}
RULE = '"open data" lang:en'


def new_tweets(since_id):
    body = {"query": f"{RULE} since_id:{since_id}", "order": "latest"}
    found = []
    while True:
        r = requests.post(URL, headers=HEADERS, json=body, timeout=30)
        if r.status_code == 429:
            time.sleep(1)
            continue
        r.raise_for_status()
        page = r.json()
        found += page.get("tweets", [])
        if not page.get("next_cursor"):
            return found
        body["next_cursor"] = page["next_cursor"]


newest = "1852331946812457001"
while True:
    tweets = new_tweets(newest)
    for t in sorted(tweets, key=lambda t: int(t["id"])):
        print(t["id"], t["user"]["username"], t["full_text"][:60])
    if tweets:
        newest = max((t["id"] for t in tweets), key=int)
    time.sleep(15)

Una clave funciona a 20 solicitudes por segundo en todos los planes, es decir, 1,200 sondeos de una página por minuto compartidos entre tus reglas. La programación, las alertas y la deduplicación para tareas de monitoreo están en la guía de monitoreo de Twitter en tiempo real.

#Reescribe el análisis de la respuesta

Sorsa API envía cada tweet como un solo objeto con su autor adentro, así que desaparece la unión entre data e includes y el trabajo que queda es renombrar campos.

API oficial de X v2 Sorsa API GET /2/tweets/search/recent { "data": [{ "id": "18523319…", "text": "Read path moved…", "author_id": "15920418…", "public_metrics": { "like_count": 41 } }], "includes": {"users": [{ "id": "15920418…", "username": "mira_moves_reads" }]}, "meta": {"next_token": "b26v8…"} } 1 2 3 4 3 5 POST /search-tweets { "tweets": [{ "id": "18523319…", "full_text": "Read path moved…", "user": { "id": "15920418…", "username": "mira_moves_reads" }, "likes_count": 41 }], "next_cursor": "DAADDAAB…" } 1 2 3 4 5 El autor viaja dentro de cada tweet: sin fields ni expansions que pedir.
La API v2 de X separa un tweet de su autor y pagina con next_token; Sorsa API pone el autor dentro del tweet y pagina con next_cursor.

Los nombres de campo de abajo salen del diccionario de datos de X y de la referencia en vivo de Sorsa API, leídos el 2 de noviembre de 2026. La mayoría de los cambios son aplanar: una métrica sale de public_metrics y conserva su nombre, y unos pocos son renombres.

Campo de la API v2 de XCampo de Sorsa API
data[]tweets[], o users[] para listas de cuentas
text y note_tweet.textfull_text
author_id con includes.users[]user, el perfil completo
public_metrics.like_countlikes_count
public_metrics.impression_countview_count
public_metrics.retweet_count, reply_count, quote_count, bookmark_countlos mismos nombres, un nivel más arriba
conversation_idconversation_id_str
referenced_tweets con includes.tweets[]quoted_status, retweeted_status, in_reply_to_tweet_id
attachments.media_keys con includes.media[]entities[] con type, link, preview
name en un usuariodisplay_name
public_metrics.following_count, tweet_count en un usuariofollowings_count, tweets_count
meta.next_token y pagination_tokennext_cursor, en ambas direcciones
errors[] con title y detail{"message": "..."}
  • data[]

    Campo de Sorsa API
    tweets[], o users[] para listas de cuentas
  • text y note_tweet.text

    Campo de Sorsa API
    full_text
  • author_id con includes.users[]

    Campo de Sorsa API
    user, el perfil completo
  • public_metrics.like_count

    Campo de Sorsa API
    likes_count
  • public_metrics.impression_count

    Campo de Sorsa API
    view_count
  • public_metrics.retweet_count, reply_count, quote_count, bookmark_count

    Campo de Sorsa API
    los mismos nombres, un nivel más arriba
  • conversation_id

    Campo de Sorsa API
    conversation_id_str
  • referenced_tweets con includes.tweets[]

    Campo de Sorsa API
    quoted_status, retweeted_status, in_reply_to_tweet_id
  • attachments.media_keys con includes.media[]

    Campo de Sorsa API
    entities[] con type, link, preview
  • name en un usuario

    Campo de Sorsa API
    display_name
  • public_metrics.following_count, tweet_count en un usuario

    Campo de Sorsa API
    followings_count, tweets_count
  • meta.next_token y pagination_token

    Campo de Sorsa API
    next_cursor, en ambas direcciones
  • errors[] con title y detail

    Campo de Sorsa API
    {"message": "..."}

Los IDs siguen siendo cadenas y las fechas siguen en ISO 8601, así que los datos guardados conservan su forma. La paginación se reduce a un solo nombre: envía next_cursor como parámetro de consulta en los endpoints GET o en el cuerpo JSON en los endpoints POST, y detente cuando llegue vacío. El control de límites también se simplifica. Las ventanas de 15 minutos y los encabezados x-rate-limit-* que describe nuestra guía de límites de solicitudes de la API de X dan paso a un solo límite de 20 solicitudes por segundo por clave: un 429 significa esperar un segundo y reintentar, y un 403 significa que falta la clave o que se agotaron las solicitudes del mes.

Para tener en cuenta

El tamaño de las páginas no es fijo. Una página de búsqueda contiene hasta 20 tweets y puede contener menos mientras quedan más páginas, así que haz el ciclo con next_cursor, nunca con la cantidad de elementos, o una página corta terminará el trabajo antes de tiempo.

#Código de Tweepy y xdk, antes y después

Tweepy y xdk son librerías gratuitas; la factura viene de la API oficial de X que hay detrás, así que la migración cambia el cliente, no el lenguaje. Aquí está la misma búsqueda con autores, paginada hasta el final, en Tweepy y luego en Python simple sobre Sorsa API:

import tweepy

client = tweepy.Client(bearer_token="X_BEARER_TOKEN")

for page in tweepy.Paginator(
        client.search_recent_tweets,
        query="from:mira_moves_reads",
        tweet_fields=["created_at", "public_metrics"],
        expansions=["author_id"],
        user_fields=["username", "name"],
        max_results=100):
    users = {u.id: u for u in page.includes.get("users", [])}
    for t in page.data or []:
        author = users[t.author_id]
        print(t.id, author.username, t.public_metrics["like_count"])

Las listas de campos, la unión con includes y el paginador salen del código; entra un solo encabezado. El código de xdk cambia igual: Client(bearer_token=...) y client.posts.search_recent(...) paginan los mismos data e includes, así que dan paso al ciclo de arriba. La consulta también llega más lejos tras la migración, porque POST /search-tweets busca hasta 2006 en todos los planes, mientras que la búsqueda reciente de la v2 cubre los últimos 7 días.

El código construido sobre el paquete twitter-api-v2 de Node.js se migra igual, a fetch y un solo encabezado:

Node.js
const URL = "https://api.sorsa.io/v3/search-tweets";
const headers = {
  ApiKey: process.env.SORSA_API_KEY ?? "YOUR_API_KEY",
  "Content-Type": "application/json",
};

const body = { query: "from:mira_moves_reads", order: "latest" };
do {
  const res = await fetch(URL, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
  });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  const page = await res.json();
  for (const t of page.tweets ?? []) {
    console.log(t.id, t.user.username, t.likes_count);
  }
  body.next_cursor = page.next_cursor;
} while (body.next_cursor);

Para el código de Tweepy que solo lee, pasa las lecturas a Sorsa API: la búsqueda devuelve 20 tweets por solicitud desde $0.07 por 1,000, los perfiles llegan 100 por solicitud desde $0.014 por 1,000 y no hace falta OAuth. Los reintentos, el procesamiento por lotes y un regulador de ritmo para 20 solicitudes por segundo están en la guía de la API de Twitter en Python.

#Traduce tus consultas de búsqueda

POST /search-tweets acepta la sintaxis de la búsqueda avanzada de X, el lenguaje del cuadro de búsqueda de x.com, así que las palabras clave, las frases entre comillas, from:, to:, lang:, conversation_id: y los hashtags pasan sin cambios. Lo que cambia son los operadores is: y has: de la v2 y sus parámetros de tiempo, que pasan a la consulta:

API v2 de XConsulta de Sorsa API
parámetros start_time y end_timesince:2026-10-01 y until:2026-11-01
parámetros since_id y until_idsince_id:ID y max_id:ID (inclusivo)
sort_order=recency o relevancy"order": "latest" o "popular" en el cuerpo
-is:retweetnada: los retweets quedan fuera por defecto
is:reply y -is:replyfilter:replies y -filter:replies
is:quotefilter:quote
has:media, has:images, has:linksfilter:media, filter:images, filter:links
has:video_linkfilter:native_video
min_likes:, min_reposts:, min_replies:min_faves:, min_retweets:, min_replies:
point_radius:geocode:
  • parámetros start_time y end_time

    Consulta de Sorsa API
    since:2026-10-01 y until:2026-11-01
  • parámetros since_id y until_id

    Consulta de Sorsa API
    since_id:ID y max_id:ID (inclusivo)
  • sort_order=recency o relevancy

    Consulta de Sorsa API
    "order": "latest" o "popular" en el cuerpo
  • -is:retweet

    Consulta de Sorsa API
    nada: los retweets quedan fuera por defecto
  • is:reply y -is:reply

    Consulta de Sorsa API
    filter:replies y -filter:replies
  • is:quote

    Consulta de Sorsa API
    filter:quote
  • has:media, has:images, has:links

    Consulta de Sorsa API
    filter:media, filter:images, filter:links
  • has:video_link

    Consulta de Sorsa API
    filter:native_video
  • min_likes:, min_reposts:, min_replies:

    Consulta de Sorsa API
    min_faves:, min_retweets:, min_replies:
  • point_radius:

    Consulta de Sorsa API
    geocode:

Tres detalles hacen tropezar a las consultas traducidas. Los retweets nativos quedan fuera salvo que agregues include:nativeretweets. geocode: toma primero la latitud, como en geocode:37.77,-122.41,5km, mientras que point_radius: de la v2 tomaba primero la longitud. Y max_id: incluye el propio ID, mientras que until_id de la v2 lo excluye. La lista completa de operadores, con recetas, está en nuestra guía de operadores de búsqueda de Twitter.

#Prueba con una ejecución en paralelo y luego cambia

Una ejecución en paralelo envía una copia de cada lectura a Sorsa API mientras la API oficial de X sigue atendiendo a tu app, de modo que los resultados se comparan antes de que algo dependa de ellos.

Etapa 1 Sombra La API de X sirve cada lectura; Sorsa API recibe una copia Lecturas API de X 100% Copia a Sorsa API Etapa 2 Comparar Cotejar IDs de posts, campos y errores de cada consulta Lecturas API de X 100% Copia a Sorsa API Etapa 3 Canary El 10% de lecturas viene de Sorsa API; vigila los errores Lecturas API de X 90% Sorsa API 10% Etapa 4 Cambio total Toda lectura corre en Sorsa API; borra el código de lectura viejo Lecturas Sorsa API 100% Writes API oficial de X en todas las etapas: posts, respuestas, DMs
Las lecturas se mueven en cuatro etapas; las escrituras nunca salen de la API oficial de X.

El script ejecuta una consulta sobre el mismo día cerrado en ambas API y compara los IDs de los posts. Ejecútalo para cada consulta y timeline de los que dependas; una ventana cerrada evita que los posts nuevos distorsionen el conteo.

shadow_run.py
import os
import requests

X_URL = "https://api.x.com/2/tweets/search/recent"
X_HEADERS = {"Authorization": "Bearer " + os.environ["X_BEARER_TOKEN"]}
S_URL = "https://api.sorsa.io/v3/search-tweets"
S_HEADERS = {"ApiKey": os.environ.get("SORSA_API_KEY", "YOUR_API_KEY")}


def x_ids(query, start, end):
    params = {"query": query, "start_time": start,
              "end_time": end, "max_results": 100}
    ids = set()
    while True:
        r = requests.get(X_URL, headers=X_HEADERS, params=params, timeout=30)
        r.raise_for_status()
        page = r.json()
        ids |= {t["id"] for t in page.get("data", [])}
        token = page.get("meta", {}).get("next_token")
        if not token:
            return ids
        params["next_token"] = token


def sorsa_ids(query, since, until):
    body = {"query": f"{query} since:{since} until:{until}",
            "order": "latest"}
    ids = set()
    while True:
        r = requests.post(S_URL, headers=S_HEADERS, json=body, timeout=30)
        r.raise_for_status()
        page = r.json()
        ids |= {t["id"] for t in page.get("tweets", [])}
        if not page.get("next_cursor"):
            return ids
        body["next_cursor"] = page["next_cursor"]


query = "from:mira_moves_reads"
a = x_ids(query, "2026-10-30T00:00:00Z", "2026-10-31T00:00:00Z")
b = sorsa_ids(query, "2026-10-30_00:00:00_UTC", "2026-10-31_00:00:00_UTC")
print(f"official X API {len(a)}, Sorsa API {len(b)}, shared {len(a & b)}")
print("only on X:", sorted(a - b)[:10])
print("only on Sorsa API:", sorted(b - a)[:10])

Espera pequeñas diferencias en lugar de cero: los posts borrados entre las dos llamadas desaparecen, y la búsqueda por palabra clave de X deja fuera los retweets desde el 4 de mayo de 2026. La búsqueda reciente de X llega 7 días hacia atrás, así que mantén la ventana dentro de la última semana. Cuando los IDs coincidan en las lecturas que más ejecutas, haz el cambio por etapas:

  • Pon ambos clientes detrás de una sola interfaz y un solo indicador de configuración, para que cualquier tipo de lectura pueda volver atrás con un solo valor.
  • Mueve el 10% de las lecturas, vigila los errores y GET /key-usage-info, que es gratis y nunca cuenta contra tus solicitudes, y luego mueve el resto.
  • Conserva la clave de la API oficial de X solo para escrituras, y baja su límite de gasto y el monto de recarga automática en la Developer Console.
  • Elimina las rutas de código de lectura, las listas de campos y la paginación antigua cuando haya pasado un ciclo de facturación completo.

#Saca tus lecturas de la API oficial de X

Una integración v2 de solo lectura pasa a Sorsa API, la API de Twitter hecha para leer datos públicos de X, con un solo encabezado, un endpoint por llamada y un analizador que pierde su unión. La búsqueda cuesta desde $0.07 por 1,000 tweets en lugar de $5.00, los seguidores desde $0.007 por 1,000 en lugar de $10.00, y todos los planes responden a 20 solicitudes por segundo. Empieza por tu lectura más cara, ejecútala en paralelo durante unos días y deja la API oficial de X solo para lo que escribe.

#Preguntas frecuentes

¿A qué API de Twitter debo migrar desde la API oficial de X?

Para leer datos públicos de X, migra a Sorsa API: cada lectura v2 se asigna a un endpoint, los tweets cuestan desde $0.014 por 1,000 por ID y desde $0.07 por búsqueda frente a $5.00 en la API oficial de X, todos los planes funcionan a 20 solicitudes por segundo y la búsqueda llega hasta 2006. Una clave de API reemplaza a OAuth. Sorsa API es de solo lectura, así que conserva la API oficial de X para publicar.

¿Cuánto tarda una migración desde la API oficial de X?

El cambio de código crece con la cantidad de llamadas v2 distintas, no con el volumen de tus datos: cada llamada se convierte en un endpoint, un encabezado y unos pocos campos renombrados. Suma una ejecución en paralelo de unos días en la que ambas API responden las mismas lecturas y comparas los IDs. Publicar, los DM y las demás escrituras se quedan en la API oficial de X, así que solo se mueve la ruta de lectura.

¿Puedo seguir publicando en X después de pasar las lecturas a Sorsa API?

Sí. Conserva la API oficial de X para publicar, responder y enviar DM, y manda las lecturas a Sorsa API. Sorsa API es de solo lectura por diseño: su clave no puede actuar sobre ninguna cuenta de X y nunca necesita tu usuario de X, así que las dos conviven sin conflicto. Si tu ruta de escritura todavía firma con tokens de usuario OAuth 1.0a, X permite desde el 21 de septiembre de 2026 que las apps los cambien por tokens OAuth 2.0.

¿Debo migrar primero de la v1.1 a la v2?

No. El código que todavía llama a lecturas de la v1.1 puede asignarse directamente a Sorsa API: statuses/user_timeline pasa a ser POST /user-tweets, statuses/show pasa a ser POST /tweet-info y users/show pasa a ser GET /info. X clasifica la v1.1 como heredada con soporte limitado y dejó obsoleta su búsqueda v1.1 en 2023, así que detenerte en la v2 significa reescribir para OAuth 2.0 y la facturación por uso antes de volver a migrar.

¿Qué pasó con los planes heredados Basic y Pro de la API de X?

X los pasó al pago por uso: las suscripciones de Basic heredado terminaron en sus fechas de transición posteriores al 1 de junio de 2026, y las de Pro después del 1 de septiembre de 2026. A una cuenta mensual de Pro se le cargó un crédito de $5,000 en la transición, con la recarga automática activada. Ahora las lecturas se cobran por recurso, $0.005 por post y $0.010 por usuario, mientras que los mismos tweets cuestan desde $0.07 por 1,000 por búsqueda en Sorsa API.

#Cómo lo verificamos

El 2 de noviembre de 2026 construimos el mapa de endpoints comparando la propia especificación OpenAPI de X (versión 2.173, 200 rutas) con la referencia en vivo de Sorsa API (45 endpoints), y comprobamos cada operador v2 con la lista de operadores de X y cada reemplazo con los operadores de búsqueda de Sorsa API. Ese mismo día leímos el changelog de X, su página de precios, su documentación de paginación y límites de solicitudes, la referencia del XDK de Python y el cliente de Tweepy 4.17.0, además de los avisos del foro de X sobre el índice de búsqueda, los planes heredados y el cobro de expansiones. No teníamos una clave de Sorsa API para esta revisión, así que la respuesta mostrada usa valores de demostración; ejecutamos los bloques de Python y Node.js contra un mock local que responde en las estructuras documentadas de ambas API.

Por el equipo de Sorsa API. Creamos y operamos Sorsa API, la API y scraper de Twitter/X de solo lectura, en producción desde 2022 (antes TweetScout API) y con más de 6 mil millones de solicitudes procesadas. Acerca de Sorsa API

Qué cambió
  • Reescrito desde cero como guía de migración: los cambios de X de 2023 a 2026 y qué rompe cada uno, un mapa de endpoints de la v2 a Sorsa API a partir de las especificaciones de ambas API, un conversor de solicitudes, los mapas de campos y operadores, código de Tweepy antes y después, sondeo en lugar de streams y un plan de pruebas en paralelo.
  • Primera publicación.