Em resumo: Migrar da API oficial do Twitter (X) para uma API REST de terceiros envolve quatro mudanças: substituir o OAuth por um cabeçalho de chave de API única, trocar a URL base e remapear os caminhos dos endpoints, achatar o parsing das respostas e mudar a paginação para um único campo de cursor. Uma migração do fluxo de leitura costuma levar de um a três dias.

Por Sorsa Editorial · Atualizado em 4 de julho de 2026: adicionado o caminho de começo gratuito (100 requisições grátis, sem cartão), preço movido para a base por 1.000 e remapeamento de endpoints reverificado contra a cobertura atual da Sorsa v3, de 40 endpoints.

Este é o passo a passo técnico para equipes que já decidiram sair e precisam da migração de fato: autenticação, mapeamento de endpoints, parsing de resposta, paginação, métodos HTTP e código funcional. Usamos a Sorsa API, uma API alternativa do Twitter (X) que construímos e operamos, como alvo de migração ao longo do texto, porque o mapeamento a partir dos endpoints v2 oficiais é um dos mais limpos disponíveis. Substituir o OAuth por um cabeçalho ApiKey, a cobrança fixa por requisição em que uma única chamada em lote retorna até 100 tweets ou perfis, o limite fixo de 20 requisições por segundo em todos os planos e a ausência de aprovação de conta de desenvolvedor para esperar são as razões práticas de uma migração do fluxo de leitura fechar em dias, não semanas. As leituras saem a partir de US$ 0,02 por 1.000 tweets e de US$ 0,01 por 1.000 perfis, e 100 requisições grátis (sem cartão, uma única vez) cobrem uma passada completa de teste com diff em paralelo antes de você decidir. Se você ainda está escolhendo um provedor, comece pela nossa comparação de alternativas à API do Twitter (X); este guia assume que essa decisão está tomada.

Rodamos essa migração para equipes desde 2022, ao longo de mais de 5 bilhões de requisições servidas, então os passos abaixo seguem uma lista de verificação fixa, e não um passeio. Os princípios valem para qualquer provedor REST somente leitura; os nomes de endpoint, campos de resposta e código são específicos da Sorsa.

Índice


O que envolve migrar da API do Twitter (X)? {#what-does-migrating-from-the-twitterx-api-involve}

Migrar da API oficial do Twitter (X) para uma API REST de taxa fixa é, na maior parte, subtração: você remove o OAuth, apaga as strings de seleção de campos, descarta os envelopes de resposta e remapeia um punhado de caminhos de endpoint. O trabalho central toca autenticação, caminhos de endpoint, parsing de resposta e paginação, e uma base de código moderada do fluxo de leitura se move em um a três dias.

Aqui está o conjunto completo de mudanças em resumo, antes do detalhe passo a passo:

  • Substitua Authorization: Bearer ... por um cabeçalho ApiKey.
  • Troque a URL base de https://api.x.com/2 para https://api.sorsa.io/v3.
  • Remapeie os caminhos dos endpoints (tabelas no Passo 2).
  • Troque os endpoints de tweet e busca de GET para POST (Passo 5).
  • Apague tweet.fields, user.fields e expansions: todos os campos vêm por padrão.
  • Achate os parsers: remova os envelopes data, includes e meta.
  • Renomeie campos: name para display_name, text para full_text, as métricas sobem para o nível superior.
  • Substitua pagination_token e next_token por next_cursor.
  • Simplifique o tratamento de erros: os erros voltam em um único campo de mensagem.

A tabela abaixo mapeia as diferenças relevantes para a migração. É a única comparação que importa aqui, porque decide quanto do seu código muda.

DimensãoAPI oficial do X v2Sorsa API
AutenticaçãoOAuth 2.0 bearer (1.0a para contexto de usuário)Um único cabeçalho ApiKey
URL basehttps://api.x.com/2https://api.sorsa.io/v3
Seleção de campostweet.fields, user.fields, expansionsTodos os campos por padrão
Formato da respostaEnvelopes data / includes / metaObjetos planos, autor embutido
Paginaçãopagination_token / next_tokennext_cursor
Método HTTP (tweets, busca)GETPOST
LoteLimitadoAté 100 tweets ou perfis por chamada
Rate limitsPor endpoint, janelas de 15 minutosFixo de 20 requisições por segundo, todos os planos
Unidade de cobrançaPor recurso buscadoPor requisição
Ações de escritaPostagem, DMs (follow, curtida, quote são só Enterprise)Somente leitura

Toda linha é uma simplificação, exceto uma: a API oficial pode escrever no X, e uma API de leitura com taxa fixa não. Se você posta, envia DMs ou roda anúncios, esse caminho fica na API oficial. Para ler dados públicos, a troca remove o OAuth, a camada de seleção de campos e as janelas de rate limit por endpoint, que é a maior parte da migração.


Passo 1: substitua o OAuth por uma chave de API {#step-1-replace-oauth-with-an-api-key}

A autenticação é a mudança que remove mais código. A API oficial usa bearer tokens OAuth 2.0 para requisições somente do app e OAuth 1.0a (consumer keys, access tokens, assinaturas HMAC por requisição) para qualquer coisa que precise de contexto de usuário. Um provedor de taxa fixa substitui tudo isso por uma chave em um cabeçalho.

Antes, na API oficial:

bash
curl -X GET "https://api.x.com/2/users/by/username/elonmusk" \
  -H "Authorization: Bearer AAAAAAAAAAAAAAAAAAAA..."

Depois:

bash
curl -X GET "https://api.sorsa.io/v3/info?username=elonmusk" \
  -H "ApiKey: YOUR_API_KEY"

Não há refresh de token, geração de assinatura nem URL de callback. Gere uma chave uma vez, guarde-a em uma variável de ambiente, e toda requisição carrega o mesmo cabeçalho ApiKey. A referência completa está na documentação de autenticação.


Passo 2: troque a URL base e remapeie os endpoints {#step-2-swap-the-base-url-and-remap-endpoints}

Cada caminho v2 oficial mapeia para um novo caminho. A maioria das chamadas muda apenas a URL e, para os endpoints de tweet, o método HTTP.

A URL base vira https://api.sorsa.io/v3. Os usuários mapeiam assim:

AçãoAPI oficial do X v2Sorsa API v3
Usuário por usernameGET /2/users/by/username/:usernameGET /info?username=:username
Usuário por IDGET /2/users/:idGET /info?user_id=:id
Múltiplos usuáriosGET /2/users?ids=...GET /info-batch?usernames=...
SeguidoresGET /2/users/:id/followersGET /followers?user_id=:id
SeguindoGET /2/users/:id/followingGET /follows?user_id=:id
Seguidores verificadosIndisponívelGET /verified-followers?user_id=:id
Metadados "about" da contaIndisponívelGET /about?username=:username

GET /info-batch aceita até 100 usernames ou IDs por chamada. GET /followers e GET /follows retornam até 200 perfis completos por página, onde o endpoint oficial retorna IDs que você depois reidrata com uma segunda chamada.

Tweets:

AçãoAPI oficial do X v2Sorsa API v3
Tweet únicoGET /2/tweets/:idPOST /tweet-info
Múltiplos tweetsGET /2/tweets?ids=...POST /tweet-info-bulk
Timeline do usuárioGET /2/users/:id/tweetsPOST /user-tweets
Quote tweetsGET /2/tweets/:id/quote_tweetsPOST /quotes
Quem deu retweetGET /2/tweets/:id/retweeted_byPOST /retweeters
Respostas (comentários)Sem endpoint dedicadoPOST /comments
Artigo de formato longoIndisponívelPOST /article

POST /tweet-info-bulk retorna até 100 tweets em uma requisição, onde iterar o /tweet-info custaria 100. POST /user-tweets não tem teto de 3.200 tweets: pagine com next_cursor até o primeiro post da conta. O campo de corpo tweet_link aceita uma URL completa ou apenas o ID numérico. Para padrões que cortam o número de requisições, veja o guia de otimização do uso da API.

Busca:

AçãoAPI oficial do X v2Sorsa API v3
Busca recente ou de arquivo completoGET /2/tweets/search/recentPOST /search-tweets
MençõesGET .../search/recent?query=@userPOST /mentions
Buscar usuáriosIndisponívelPOST /search-users

POST /search-tweets cobre a busca histórica no mesmo endpoint, e POST /mentions adiciona filtros de engajamento que a API oficial não expõe: min_likes, min_replies, min_retweets, since_date e until_date.

Listas, comunidades, verificação e analytics também mapeiam, e vários não têm equivalente na API oficial. As listas usam GET /list-members, GET /list-followers e GET /list-tweets. As comunidades, que a API oficial não expõe de forma alguma, usam POST /community-members, POST /community-tweets e POST /community-search-tweets. As verificações em uma chamada (POST /check-follow, GET /check-comment, POST /check-quoted, POST /check-retweet, POST /check-community-member) respondem uma pergunta de sim ou não que, de outro modo, exigiria varrer listas inteiras de seguidores ou de quem deu retweet. A tabela completa caminho por caminho está na referência de mapeamento de endpoints.


Passo 3: achate o parsing e remapeie os campos {#step-3-flatten-response-parsing-and-remap-fields}

Este passo toca mais código do que qualquer outro depois da autenticação. A API oficial divide uma resposta em data, includes e meta. Um provedor de taxa fixa retorna um objeto plano com o autor embutido dentro de cada tweet, então a lógica de junção de usuário some.

Um perfil de usuário, antes:

json
{
  "data": {
    "id": "44196397",
    "name": "Elon Musk",
    "username": "elonmusk",
    "public_metrics": {
      "followers_count": 100000000,
      "following_count": 500,
      "tweet_count": 30000
    }
  }
}

Depois:

json
{
  "id": "44196397",
  "username": "elonmusk",
  "display_name": "Elon Musk",
  "followers_count": 100000000,
  "followings_count": 500,
  "tweets_count": 30000,
  "verified": false,
  "created_at": "2009-06-02T20:12:29Z"
}

Os renomeios de campo são pequenos, mas fáceis de perder no teste. Mapeie-os uma vez e o resto segue:

API oficial do X v2Sorsa APINota
namedisplay_nameRenomeado
textfull_textRenomeado
public_metrics.followers_countfollowers_countAchatado
public_metrics.following_countfollowings_countAchatado, "s" a mais
public_metrics.tweet_counttweets_countAchatado, renomeado
public_metrics.like_countlikes_countAchatado, "s" a mais
public_metrics.retweet_countretweet_countAchatado, sem "s"
public_metrics.impression_countview_countAchatado, renomeado
conversation_idconversation_id_strRenomeado
in_reply_to_user_idin_reply_to_username@, não ID
author_id mais includes.users[]user (objeto completo embutido)Embutido
Tweets referenciados via includesquoted_status, retweeted_statusEmbutidos

Uma inconsistência a anotar para não custar tempo de depuração: curtidas e seguindo vão para o plural (likes_count, followings_count), enquanto retweet_count, reply_count e quote_count ficam no singular. O perfil do autor vive sob user em cada resposta de tweet, então a tabela de lookup includes.users que você mantinha na API oficial pode ser apagada de vez.


Passo 4: mude a paginação para um cursor {#step-4-switch-pagination-to-a-cursor}

A paginação encolhe para um único campo. A API oficial usa pagination_token na query e retorna meta.next_token; um provedor de taxa fixa usa next_cursor no nível superior da resposta.

Para endpoints GET, passe next_cursor como parâmetro de query. Para endpoints POST, inclua-o no corpo JSON:

bash
curl -X POST "https://api.sorsa.io/v3/search-tweets" \
  -H "ApiKey: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "query": "from:elonmusk", "next_cursor": "ABC123" }'

A resposta é plana, e um next_cursor ausente ou nulo significa que você chegou à última página:

json
{ "tweets": [], "next_cursor": "XYZ789" }

O padrão completo, incluindo a paginação de listas de seguidores, está na documentação de paginação por cursor.


Passo 5: troque GET por POST onde for preciso {#step-5-switch-get-to-post-where-required}

Essa é a mudança que as equipes esquecem e depois depuram por dez minutos. Na API oficial, as leituras de tweet e busca são GET. Em uma API REST de taxa fixa, qualquer coisa que receba um identificador de tweet ou uma consulta de busca vira POST, enquanto qualquer coisa que receba um identificador de usuário ou um ID de lista continua GET.

AçãoAPI oficialSorsa API
Obter um tweetGETPOST
Buscar tweetsGETPOST
Timeline do usuárioGETPOST
Quote tweets, quem deu retweetGETPOST
Respostas (comentários)n/aPOST
Perfil de usuárioGETGET
Seguidores, seguindoGETGET
ListasGETGET

A regra de bolso: um identificador de tweet ou uma consulta de busca significa POST; um identificador de usuário ou um ID de lista significa GET.


Passo 6: migre o código {#step-6-migrate-the-code}

Seguem três migrações representativas, cada uma em curl, Python e JavaScript. São os padrões que você repete por uma base de código do fluxo de leitura.

Obter um perfil de usuário

Antes:

python
import requests

r = requests.get(
    "https://api.x.com/2/users/by/username/elonmusk",
    params={"user.fields": "public_metrics,verified,created_at"},
    headers={"Authorization": f"Bearer {BEARER_TOKEN}"},
)
user = r.json()["data"]
followers = user["public_metrics"]["followers_count"]
name = user["name"]

Depois:

python
import requests

r = requests.get(
    "https://api.sorsa.io/v3/info",
    params={"username": "elonmusk"},
    headers={"ApiKey": API_KEY},
)
user = r.json()
followers = user["followers_count"]
name = user["display_name"]

A string de seleção de campos some e as métricas ficam no nível superior.

Buscar tweets

Antes, a junção do autor é obrigatória:

javascript
const params = new URLSearchParams({
  query: "from:elonmusk since:2024-01-01",
  "tweet.fields": "created_at,public_metrics",
  expansions: "author_id",
  "user.fields": "username,name",
});
const res = await fetch(`https://api.x.com/2/tweets/search/recent?${params}`, {
  headers: { Authorization: `Bearer ${BEARER_TOKEN}` },
});
const data = await res.json();
const users = Object.fromEntries((data.includes?.users || []).map(u => [u.id, u]));
for (const t of data.data || []) {
  console.log(t.text, "by", users[t.author_id].username);
}

Depois, cada tweet já carrega o autor:

javascript
const res = await fetch("https://api.sorsa.io/v3/search-tweets", {
  method: "POST",
  headers: { ApiKey: API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({ query: "from:elonmusk since:2024-01-01" }),
});
const data = await res.json();
for (const t of data.tweets) {
  console.log(t.full_text, "by", t.user.username);
}

A tabela de junção de usuário desaparece porque o autor está embutido em cada tweet.

Paginar todos os seguidores

python
def fetch_all_followers(user_id, api_key):
    url = "https://api.sorsa.io/v3/followers"
    headers = {"ApiKey": api_key}
    followers, next_cursor = [], None
    while True:
        params = {"user_id": user_id}
        if next_cursor:
            params["next_cursor"] = next_cursor
        data = requests.get(url, headers=headers, params=params).json()
        followers.extend(data.get("users", []))
        next_cursor = data.get("next_cursor")
        if not next_cursor:
            break
    return followers

Cada página retorna até 200 perfis totalmente hidratados, então uma extração de grafo de seguidores que exigia uma chamada de IDs mais uma de reidratação na API oficial vira uma única passada. Para detalhe por linguagem, nosso guia da API do Twitter em Python cobre o fluxo de leitura completo.


Passo 7: mantenha suas consultas de busca e trate erros {#step-7-keep-your-search-queries-and-handle-errors}

Suas consultas de busca migram sem mudança. Um provedor de taxa fixa que suporte os mesmos operadores da busca avançada do Twitter lê from:, to:, since:, until:, frases entre aspas, hashtags, OR e -is:retweet exatamente como o endpoint de busca recente oficial faz, então as strings de consulta existentes não precisam de edição.

Copie suas strings de consulta atuais; a referência de operadores de busca avançada lista o conjunto completo. O endpoint mentions também expõe filtros de engajamento (min_likes, min_replies, min_retweets, since_date, until_date), então qualquer lógica de "filtrar por piso de engajamento" do lado do cliente que você escreveu contra a API oficial pode ir para o lado do servidor.

O tratamento de erros também simplifica. Onde a API oficial retorna um array de erro estruturado, um provedor de taxa fixa retorna um único campo de mensagem com códigos de status padrão: 400, 401, 403, 404, 429 e 500. Para um 429, a política é esperar um segundo e repetir, porque o limite é fixo em 20 requisições por segundo em todos os endpoints e planos, sem janela por endpoint para rastrear. Um wrapper defensivo de retentativa:

python
import time, requests

def call_with_retry(method, url, max_retries=3, **kwargs):
    for attempt in range(max_retries):
        r = requests.request(method, url, **kwargs)
        if r.status_code == 429:
            time.sleep(2 ** attempt)
            continue
        r.raise_for_status()
        return r.json()
    raise RuntimeError(f"failed after {max_retries} retries")

A lista completa de códigos de status está na referência de códigos de erro.


Lista de verificação da migração {#migration-checklist}

Use isto como a lista de trabalho para uma migração do fluxo de leitura:

  1. Substitua Authorization: Bearer ... pelo cabeçalho ApiKey em todo lugar.
  2. Remova a lógica de assinatura OAuth 1.0a (consumer keys, access tokens, assinaturas).
  3. Atualize a URL base para https://api.sorsa.io/v3.
  4. Remapeie cada caminho de endpoint usando as tabelas do Passo 2.
  5. Troque GET por POST para os endpoints de tweet, busca, comentário, quote e quem deu retweet.
  6. Apague tweet.fields, user.fields e expansions.
  7. Remova o desembrulho de data / includes / meta.
  8. Renomeie os campos nos seus modelos (name, text, o bloco public_metrics).
  9. Substitua pagination_token e next_token por next_cursor.
  10. Atualize o tratamento de erros para o formato de campo de mensagem único.
  11. Ajuste a lógica de rate limit para um fixo de 20 requisições por segundo, sem janelas por endpoint.
  12. Teste os endpoints críticos no API Playground antes de implantar.
  13. Acompanhe o consumo da cota com o endpoint key-usage-info (veja a referência de uso de chave).
  14. Mantenha a chave oficial se você também escreve no X; só o fluxo de leitura migra.

Na prática: a migração de arquivo de um grupo acadêmico {#in-practice-an-academic-groups-archival-migration}

Um grupo de pesquisa acadêmica chegou até nós em meados de 2025 rodando um pipeline de coleta de tweets para um estudo longitudinal na API oficial. Dois problemas os travavam: o endpoint de timeline do usuário travava nos 3.200 tweets mais recentes por conta, o que quebrava a cobertura histórica, e o endpoint de seguidores retornava IDs nus que precisavam de uma segunda consulta para virar perfis utilizáveis.

A migração do fluxo de leitura levou cerca de dois dias para um pesquisador. POST /user-tweets removeu o teto de 3.200 tweets, paginando com next_cursor de volta ao primeiro post de cada conta, então a lacuna de arquivo fechou. A extração de seguidores encolheu para uma única passada porque GET /followers retorna até 200 perfis completos por página, o que praticamente cortou pela metade o número de requisições daquela parte do trabalho. O único atrito real foram os renomeios de campo (name para display_name, text para full_text e o pluralizado likes_count), pegos em algumas horas de teste, não de projeto. Os números exatos variam por carga; o formato da migração, não.


Perguntas frequentes {#frequently-asked-questions}

Dá para migrar da API do Twitter (X) um endpoint por vez?

Sim, e uma migração gradual costuma ser o caminho mais seguro. Coloque uma fina camada de abstração na frente das suas chamadas de dados, aponte um endpoint para o novo provedor, valide a saída dele contra a API oficial por alguns dias e então mova o próximo. O código de aplicação nunca precisa mudar em uma reescrita única e grande, e você pode reverter um endpoint de forma independente se algo parecer errado.

Como testar uma migração da API do Twitter (X) sem quebrar a produção?

Rode as duas APIs em paralelo e compare a saída processada antes de virar a chave. A opção mais leve é o playground do navegador, que envia requisições sem código de integração. Uma opção mais forte é um script lado a lado que chama as duas APIs e compara os resultados, e a mais completa é uma feature flag que roteia uma porcentagem do tráfego para o novo provedor, para você reverter na hora.

As consultas da busca avançada do Twitter ainda funcionam depois de migrar?

Sim, se o provedor suporta os mesmos operadores da busca avançada. Os endpoints search-tweets e mentions da Sorsa leem from:, to:, since:, until:, frases entre aspas, hashtags, OR e -is:retweet exatamente como o endpoint de busca recente oficial, então as strings de consulta existentes migram sem edição. O endpoint mentions adiciona filtros de engajamento, como min_likes e min_retweets, que a API oficial não expõe.

Como lidar com rate limits e erros depois de migrar?

O tratamento de erros fica mais simples. A Sorsa retorna cada erro como um único campo de mensagem, em vez do array de erro estruturado da API oficial, com códigos de status padrão (400, 401, 403, 404, 429 e 500). O rate limit é fixo em 20 requisições por segundo em todos os planos, sem janelas de 15 minutos por endpoint. Em um 429, espere um segundo e repita; não há cabeçalho de reset para rastrear.

Migrar remove o limite de 3.200 tweets da timeline?

Sim. O endpoint de timeline do usuário da v2 oficial trava nos 3.200 tweets mais recentes por conta. O POST /user-tweets da Sorsa não tem esse teto: pagine com next_cursor até a resposta parar de retornar um, e você chega ao primeiro post da conta. Para trabalho de arquivo, histórico de sentimento e dados de treinamento, essa costuma ser a própria razão de a migração acontecer.

Como continuar escrevendo no X se a alternativa é somente leitura?

Você mantém a API oficial do X para as ações de escrita e migra só o fluxo de leitura. Postagem, respostas, DMs, curtidas, follows e anúncios ficam todos na API oficial, que é o único sistema que pode agir em nome de um usuário. A maioria das equipes acaba com um híbrido: um pequeno orçamento de API oficial para escrita e uma API de leitura de taxa fixa para extrações de alto volume. A Sorsa é somente leitura por design, o que também remove uma classe de risco de permissão de escrita e de suspensão de conta.


Como verificamos este guia {#how-we-verified-this-guide}

Este passo a passo se apoia no nosso trabalho prático operando uma API alternativa do X desde 2022 e em migrações do fluxo de leitura que rodamos para equipes deixando a plataforma oficial. Caminhos de endpoint, nomes de parâmetros, campos de resposta e o cabeçalho ApiKey foram verificados contra a documentação da Sorsa API ao vivo, e o modelo de autenticação, os envelopes de resposta e as taxas de pagamento por uso da API oficial do X foram checados contra a documentação de desenvolvedor e a página de preços do X, refletindo a mudança de 20 de abril de 2026. Para o lado de custo da decisão, veja nossa análise atual de preços da API do X. Cada amostra de código foi escrita para rodar como mostrada. Verificado em 13 de junho de 2026.

Revisado por Keksich, fundador da Sorsa, profissional de marketing e pesquisador da API do X.


Primeiros passos {#getting-started}

Se o seu pipeline lê tweets, perfis, seguidores ou resultados de busca, a forma mais rápida de dimensionar uma migração é rodar algumas chamadas e comparar o formato da resposta com o seu parser atual. O início rápido da Sorsa API leva você à primeira requisição em minutos atrás de uma chave, e a documentação de dados históricos mostra como os endpoints de timeline alcançam 2006 sem o teto de 3.200 tweets. As primeiras 100 requisições são grátis, uma única vez, sem cartão e sem prazo de validade, o que cobre um teste completo de diff em paralelo antes de você pagar. Depois disso, as leituras saem a partir de US$ 0,02 por 1.000 tweets e de US$ 0,01 por 1.000 perfis, com planos a partir de US$ 49 por mês por 10.000 requisições, o mesmo limite fixo de 20 requisições por segundo em todos os níveis e nenhuma aprovação de conta de desenvolvedor entre você e a primeira chamada. Aponte um endpoint para ela atrás de uma flag, compare a saída e migre o resto.