Por Sorsa Editorial
Atualizado em julho de 2026: reformulamos a comparação de custo em torno das tarifas por 1.000 tweets, adicionamos a opção inicial de 100 requisições grátis, atualizamos o preço por leitura da API oficial do X e esclarecemos quais operadores o endpoint v2 descarta em silêncio.
Em resumo:
A API de busca do Twitter deixa os desenvolvedores consultarem a linha do tempo pública do X programaticamente com filtros de palavra-chave e de operador. Em 2026 há dois caminhos práticos: o endpoint de busca recente da API oficial do X v2, cobrado por pagamento por uso com um conjunto limitado de operadores, e APIs REST de terceiros que repassam o conjunto completo de operadores da web em planos mensais fixos que começam com requisições grátis.
Para busca somente leitura em escala, a Sorsa API, um provedor alternativo de API do Twitter (X), é a opção que recomendamos e a que cobrimos de ponta a ponta aqui. O endpoint /search-tweets dela repassa o conjunto completo de operadores da web, incluindo os filtros de engajamento min_faves:, min_retweets: e min_replies: que o endpoint v2 oficial descarta em silêncio; ela roda a um fixo de 20 requisições por segundo em todo plano sem janelas por endpoint; e começa com 100 requisições grátis (sem cartão, todos os 40 endpoints) antes de passar para planos mensais fixos que dão até US$ 0,02 por 1.000 tweets quando em lote, sem aprovação de conta de desenvolvedor e com uma configuração que leva minutos. A única coisa que ela não faz é escrever: postar, curtir e DMs ficam com a API oficial.
A barra de busca da web do X serve quando você está matando tempo. Ela é inútil quando você precisa puxar 50.000 tweets que casam com uma consulta booleana complexa, rodá-la em uma programação, empurrar os resultados para um warehouse Postgres e ter alguém em compliance auditando o pipeline no próximo trimestre. É para isso que a API de busca do Twitter existe. Este guia percorre como ela funciona em 2026, os operadores que de fato disparam, o código que trata tráfego de produção real e onde cada opção se encaixa.
Construímos contra os endpoints de busca do Twitter desde a era da v1.1. Pela reformulação de preço de 2023, a migração para a v2 e a virada de 2026 para pagamento por uso baseado em crédito, o modelo mental subjacente não mudou muito: você envia uma query string, recebe JSON de volta, pagina com um cursor. O que mudou é qual provedor você paga, quanto você paga e quais operadores são descartados em silêncio antes de a sua consulta ser executada. Essa última parte pega a maioria das pessoas.
Índice
- Por que buscar tweets programaticamente?
- O cenário da API de busca do Twitter em 2026
- O endpoint
/search-tweets: anatomia da requisição - O que há na resposta
- Operadores de busca que de fato funcionam
- Dois conjuntos de operadores: busca da web contra a API v2 oficial
- Como buscar tweets por hashtag?
- Paginação: coletando milhares de tweets
- Código funcional: Python e JavaScript
- Templates de consulta do mundo real
- Buscar tweets contra acompanhar menções: qual endpoint?
- Como a busca da Sorsa se compara à API oficial do X
- Erros comuns e solução de problemas
- Perguntas frequentes
- Primeiros passos
Por que buscar tweets programaticamente? {#why-search-tweets-programmatically}
Uma API de busca existe porque os casos de uso abaixo não conseguem sobreviver em atualizações manuais de navegador:
Social listening e monitoramento de marca. Acompanhe cada menção pública do seu produto ou dos concorrentes com JSON estruturado entregue no Slack, em um painel ou em um pipeline de alertas. O sinal está no volume e na tendência, não em qualquer tweet isolado, que é a premissa inteira do social listening em escala.
Inteligência de concorrentes e de mercado. Puxe tweets filtrados por engajamento das contas dos seus concorrentes, identifique quais posts performaram e construa um benchmark de conteúdo para um acompanhamento de concorrentes contínuo. Combine from:competitor min_faves:100 -filter:replies com janelas de data para comparar trimestre a trimestre.
Análise de sentimento. Alimente o texto de tweet em um modelo transformer e o pontue. A API de busca te dá o texto bruto mais as métricas (curtidas, respostas, visualizações) que servem também de pesos de confiança ao agregar sentimento. Cobrimos o pipeline completo no nosso guia de análise de sentimento do Twitter.
Geração de leads. Buscas como "looking for" (api OR tool) twitter fazem emergir pessoas que estão ativamente pedindo o que você vende. Uma consulta bem elaborada é uma lista de leads gratuita, que é a base da geração de leads no X.
Pesquisa acadêmica e jornalística. A pesquisa acadêmica precisa de consultas reprodutíveis e auditáveis contra uma janela de tempo definida. Um endpoint de busca com since: e until: é uma fonte de dados primária, e o arquivo histórico volta até o primeiro tweet em 2006.
Detecção de tendência. Rode a mesma consulta em um cron de 5 minutos, armazene os contadores de resultado e detecte picos. É assim que os sistemas de detecção de eventos e os painéis de sentimento de cripto funcionam por baixo, e é o padrão por trás do monitoramento em tempo real construído sobre um loop de polling.
O cenário da API de busca do Twitter em 2026 {#the-twitter-search-api-landscape-in-2026}
Não existe mais uma única "API de busca do Twitter". Existem três categorias, e a diferença entre elas em preço e capacidade é mais ampla do que a maioria dos desenvolvedores percebe.
A API oficial do X v2
Endpoint: /2/tweets/search/recent e /2/tweets/search/all. A partir de 2026, a API do X roda em um modelo de pagamento por uso baseado em crédito: cada leitura de post custa cerca de US$ 0,005, e cada leitura de usuário (autor) é cobrada à parte a cerca de US$ 0,010. Não há plano gratuito e nem franquia de crédito grátis, então você compra créditos de antemão antes de qualquer requisição passar. A autenticação usa Bearer Tokens OAuth 2.0.
O problema mais difícil é a cobertura de operadores. O endpoint v2 oficial aceita um subconjunto muito menor de operadores do que a barra de busca da web em x.com/search. Filtros de engajamento com que as equipes de produção contam, incluindo min_faves:, min_retweets:, min_replies: e within_time:, são ignorados em silêncio se você os incluir em uma consulta v2. Já vimos equipes construírem pipelines inteiros em filtros min_faves: antes de descobrir isso, e depois terem de refatorar.
A busca de arquivo oficial está disponível mas precificada para orçamentos enterprise. Para a maioria das cargas de pesquisa e monitoramento somente leitura, a conta não fecha. Se você quer a linha do tempo completa de como o preço do X chegou aqui, o nosso detalhamento de preços da API do Twitter percorre cada mudança.
Scrapers de código aberto
Twikit, TweeterPy e XActions ainda são funcionais em meados de 2026. O Twint está morto. twscrape e snscrape estão quebrados na maioria das configurações. As bibliotecas mantidas funcionam para trabalhos pequenos e avulsos, mas ficam em cima da interface de busca da web pública e quebram sempre que o X mexe no frontend. Nenhuma delas é realista para pipelines de produção que precisam de garantias de uptime.
APIs de busca de terceiros
Esta é a categoria em que a Sorsa se encaixa: serviços que rodam a própria infraestrutura de scraping atrás de uma API REST limpa, expõem o conjunto completo de operadores da web e cobram tarifas previsíveis. Há outros provedores neste espaço, e se tudo que você quer é o menor preço por chamada absoluto mesmo ao custo de confiabilidade ou completude, um deles pode servir a um caso estreito. Para acesso confiável, completo e somente leitura a uma tarifa fixa justa, a Sorsa é a que construímos, operamos e recomendamos.
O raciocínio para o nosso endpoint /search-tweets sobre as alternativas se resume a quatro coisas concretas: um plano mensal fixo que não multiplica créditos por tipo de endpoint, o conjunto completo de operadores da web repassado sem descartes silenciosos, as mesmas 20 requisições por segundo em todo plano e autenticação que é um cabeçalho (ApiKey: YOUR_KEY) sem fluxo OAuth. Para um passo a passo de ponta a ponta saindo da API oficial, incluindo um levantamento mais amplo de opções somente leitura, veja nosso guia de migração da API do Twitter.
O endpoint /search-tweets: anatomia da requisição {#the-search-tweets-endpoint-request-anatomy}
Envie uma requisição POST para:
POST https://api.sorsa.io/v3/search-tweets
A autenticação é um cabeçalho: ApiKey: YOUR_API_KEY (sensível a maiúsculas). Sem Bearer tokens, sem dança de OAuth, sem URLs de callback para registrar.
Corpo da requisição
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
query | string | Sim | Palavras-chave de busca. Aceita o conjunto completo de operadores de busca nativos do X. |
order | string | Não | "popular" (padrão) corresponde à aba "Top" da busca do X. "latest" retorna cronológico, mais novo primeiro. |
next_cursor | string | Não | Cursor de paginação de uma resposta anterior. Omita na primeira requisição. |
Exemplo mínimo em cURL
curl -X POST https://api.sorsa.io/v3/search-tweets \
-H "ApiKey: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "artificial intelligence",
"order": "latest"
}'
Por que POST e não GET?
Consultas de busca ficam longas. Uma consulta real de monitoramento de marca pode facilmente passar de 200 caracteres assim que você adiciona agrupamentos booleanos, exclusões, filtros de idioma e limiares de engajamento. Colocá-las em uma URL significa fazer URL-encode de cada operador e rezar para o proxy upstream não truncar. Colocá-las em um corpo JSON evita o problema de comprimento e de encoding de URL por completo. O endpoint de busca v2 oficial toma a abordagem oposta (um parâmetro query com URL-encode em uma requisição GET), que é parte do porquê consultas longas na API oficial batem no teto de caracteres do nível de acesso (512 caracteres na busca recente de autoatendimento) mais rápido do que as pessoas esperam.
Se você quer construir consultas visualmente antes de escrever código, o construtor de busca da Sorsa renderiza os mesmos operadores como um formulário e emite a query string que você colaria no seu script, e o playground interativo roda requisições completas contra a sua chave sem escrever nenhum código de cliente. Ambos estão linkados na seção Primeiros Passos abaixo.
O que há na resposta {#whats-in-the-response}
O endpoint retorna um objeto JSON com dois campos de topo: um array de objetos de tweet e um cursor de paginação.
{
"tweets": [
{
"id": "2029914600217473314",
"full_text": "The latest breakthroughs in AI are reshaping automation.",
"created_at": "2026-03-06T13:38:49Z",
"lang": "en",
"likes_count": 142,
"retweet_count": 38,
"reply_count": 12,
"quote_count": 5,
"view_count": 28400,
"bookmark_count": 19,
"is_reply": false,
"is_quote_status": false,
"conversation_id_str": "2029914600217473314",
"entities": [],
"user": {
"id": "1422280682240450563",
"username": "tech_insider",
"display_name": "Tech Insider",
"description": "Breaking tech news and analysis.",
"followers_count": 84200,
"verified": true
}
}
],
"next_cursor": "DAABCgABGSmiaxkAAgoAAgjEJ..."
}
Algumas coisas importam aqui.
O perfil completo do autor vem dentro de cada tweet. Entre as migrações que tratamos, a maior economia de tempo de dev raramente é a queda de preço. É não ter de fazer uma consulta users/by/ids à parte para cada autor de tweet. O endpoint v2 oficial exige que você adicione um parâmetro expansions=author_id e depois percorra um array includes.users para casar IDs de autor de volta aos tweets, e cobra cada uma dessas leituras de autor à parte. Nesta resposta, o objeto de usuário é embutido diretamente e sem custo extra. Uma requisição, tanto conteúdo quanto autoria.
As métricas de engajamento não são campos opcionais. Curtidas, retweets, respostas, quotes, visualizações e salvamentos estão sempre presentes em cada tweet. Nenhum tweet.fields=public_metrics para lembrar.
next_cursor é o único sinal de paginação que você precisa. Quando o campo é uma string, mais resultados estão disponíveis. Quando ele é null ou está ausente, você chegou ao fim do conjunto de resultados.
Para a referência completa de campos dos objetos Tweet e User, veja a referência de formato de resposta na documentação da API.
Operadores de busca que de fato funcionam {#search-operators-that-actually-work}
A busca da web do X aceita um grande conjunto de operadores, e o subconjunto de alta alavancagem abaixo cobre cerca de 90% das cargas reais. Mantemos esta lista prática de propósito; para o catálogo completo, incluindo operadores de geo, filtros de fonte, filtros de card e os casos de borda de código de idioma, veja nossa folha de cola completa de operadores de busca do Twitter.
Palavras-chave e frases
artificial intelligencecorresponde a tweets contendo qualquer dessas palavras"artificial intelligence"corresponde à frase exata- O stemming de palavras está ligado por padrão:
beartambém vai corresponder abears
Baseados em usuário
from:elonmusktweets postados por uma contato:openaitweets respondendo a uma conta@sorsa_apptweets mencionando uma conta
Filtros de engajamento
min_faves:100pelo menos 100 curtidasmin_retweets:50pelo menos 50 retweetsmin_replies:10pelo menos 10 respostas
Estes três são os operadores que mais vale saber que existem. Também são os que a API oficial do X v2 descarta em silêncio, então se você migra código de um provedor diferente pode ver o seu filtro de "baixa qualidade" parar de funcionar sem um erro.
Filtros de conteúdo
filter:media,filter:images,filter:videos,filter:links- Prefixe com
-para excluir:-filter:retweets,-filter:replies,-filter:links
Idioma e data
lang:en(qualquer código ISO 639-1:es,fr,de,ja, e assim por diante)since:2026-01-01nesta data ou depoisuntil:2026-03-01antes desta data (exclusivo)
Lógica booleana
(bitcoin OR ethereum) min_faves:100 lang:enparênteses para gruposcrypto -scam -airdropexclusão com um prefixo de menos
Para a referência de comportamento dos operadores, o repositório mantido pela comunidade igorbrigadir/twitter-advanced-search no GitHub é a fonte pública mais completa.
Dois conjuntos de operadores: busca da web contra a API v2 oficial {#two-operator-sets-web-search-vs-the-official-v2-api}
Há dois conjuntos de operadores distintos no X, e confundi-los é a razão isolada mais comum de uma consulta que "funciona" em um lugar retornar nada em outro. Nomeie o conjunto que você está mirando antes de escrever a consulta.
Operadores de busca da web são o que o twitter.com/search, o TweetDeck e as APIs REST baseadas em scraping aceitam. Este é o conjunto na seção acima, e é o que o endpoint /search-tweets da Sorsa repassa sem mudança.
Operadores da API oficial do X v2 são um subconjunto menor com sintaxe diferente. Em vez de filter:media e -filter:retweets, o endpoint v2 usa has:media, has:links, is:retweet e is:reply. Ele adiciona place_country:US para geografia e context: para anotações de tópico e entidade, mas não aceita os filtros de engajamento de forma alguma. Se você está no endpoint oficial, min_faves:, min_retweets:, min_replies:, within_time: e filter:blue_verified são simplesmente ignorados, sem nenhum erro retornado.
Alguns operadores são amplamente mal compreendidos ou não confiáveis, em qualquer provedor, em 2026:
| Operador | O que as pessoas erram |
|---|---|
filter:verified contra filter:blue_verified | filter:verified corresponde a contas verificadas legadas; filter:blue_verified corresponde a contas pagas do X Premium. Para sinal editorial você geralmente quer o primeiro, não o segundo. |
within_time:7d | Uma janela móvel medida a partir do horário da consulta, então a mesma consulta retorna um conjunto diferente amanhã. Para datasets reprodutíveis use datas since: e until: explícitas em vez disso. |
from:user contra @user | from:user retorna tweets que a conta escreveu; @user retorna qualquer tweet mencionando ela, incluindo respostas e quotes de outros. |
near:, within:, geocode: | O geotagging por coordenada exata está bem depreciado, então os operadores de geo agora têm cobertura reduzida e não devem ser usados como base para completude. |
Saber em qual conjunto você está economiza horas de depurar uma consulta que é válida mas silenciosamente retornando vazia.
Como buscar tweets por hashtag? {#how-do-you-search-tweets-by-hashtag}
Para buscar tweets por hashtag por uma API, passe a hashtag como um operador avulso na sua consulta, por exemplo #worldcup. Uma hashtag funciona por conta própria e pode ser combinada com filtros de engajamento, idioma e data para estreitar o conjunto de resultados, que é como você transforma uma hashtag ruidosa em um dataset aproveitável.
No endpoint /search-tweets da Sorsa, o corpo fica assim:
{
"query": "#worldcup min_faves:50 lang:en -filter:retweets since:2026-06-01",
"order": "latest"
}
Isso retorna tweets em inglês, originais (não retweets) carregando #worldcup com pelo menos 50 curtidas, postados em 1º de junho ou depois. Descarte o filtro de engajamento para volume bruto, ou aumente-o para mostrar apenas os posts que viajaram.
A API oficial do X v2 também corresponde #hashtag como um termo de consulta, mas com duas ressalvas que mordem projetos de acompanhamento de hashtag: o piso de engajamento (min_faves:) que evita que uma hashtag popular te afogue em ruído não está disponível, e a busca recente é limitada a cerca dos últimos sete dias a menos que você esteja em um nível de arquivo de compromisso maior. Se o seu objetivo é "cada tweet com esta hashtag acima de N de engajamento, voltando meses", o caminho de operadores da web de tarifa fixa é o que de fato faz isso. O conjunto completo de operadores adjacentes a hashtag (filter:hashtags, cashtags e os códigos de idioma só de mídia) é coberto na folha de cola de operadores de busca linkada antes.
Paginação: coletando milhares de tweets {#pagination-collecting-thousands-of-tweets}
Uma única requisição de busca retorna uma página de cerca de 20 tweets. Para puxar datasets maiores você usa paginação baseada em cursor.
A lógica é de quatro passos:
- Primeira requisição. Envie query e order. Não inclua
next_cursor. - Leia o cursor. A resposta contém uma string
next_cursor. - Próxima requisição. Envie a mesma query, mesma order, mais o valor
next_cursorque você acabou de receber. - Repita até
next_cursorsernull, vazio ou ausente.
Isto é mais confiável do que a paginação baseada em offset porque novos tweets postados entre as suas requisições não causam duplicatas ou resultados pulados. O cursor codifica uma posição no conjunto de resultados, não um offset numérico.
Fragmentação por intervalo de data para paginação profunda
Há um caso de borda que vale conhecer antes de você confiar em um único cursor para 100.000 tweets.
Em uma extração de pesquisa de mercado de 200.000 tweets que casavam com bitcoin lang:en, um único loop de cursor começou a retornar duplicatas contra páginas anteriores por volta da página 70 e parou de avançar por completo por volta da página 90. Isto não é específico da nossa API: qualquer índice de busca contra uma linha do tempo em movimento tem essa propriedade quando você o percorre fundo o suficiente.
A correção é quebrar a consulta em fragmentos por intervalo de data. Em vez de uma consulta sobre todo o tempo, rode a mesma consulta para cada semana:
import datetime as dt
import time
import requests
API_KEY = "YOUR_API_KEY"
URL = "https://api.sorsa.io/v3/search-tweets"
def search_in_window(base_query, since, until, max_pages=50):
"""Paginate within a since/until window."""
full_query = f"{base_query} since:{since} until:{until}"
cursor = None
out = []
for _ in range(max_pages):
body = {"query": full_query, "order": "latest"}
if cursor:
body["next_cursor"] = cursor
resp = requests.post(
URL,
headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
json=body,
)
resp.raise_for_status()
data = resp.json()
out.extend(data.get("tweets", []))
cursor = data.get("next_cursor")
if not cursor:
break
time.sleep(0.1)
return out
def search_chunked(base_query, start, end, days_per_chunk=7):
"""Walk a date range in chunks."""
all_tweets = []
cursor_date = start
while cursor_date < end:
next_date = min(cursor_date + dt.timedelta(days=days_per_chunk), end)
chunk = search_in_window(
base_query,
cursor_date.strftime("%Y-%m-%d"),
next_date.strftime("%Y-%m-%d"),
)
all_tweets.extend(chunk)
print(f"{cursor_date} -> {next_date}: {len(chunk)} tweets")
cursor_date = next_date
return all_tweets
tweets = search_chunked(
"bitcoin lang:en",
dt.date(2026, 1, 1),
dt.date(2026, 4, 1),
days_per_chunk=7,
)
Um fragmento semanal em uma consulta ruidosa como bitcoin lang:en tipicamente rende um percurso de cursor limpo até o fim sem deriva de duplicatas. Para consultas mais quietas você pode esticar para fragmentos mensais. Para consultas de volume muito alto (pense em lang:en sem outros filtros) você pode querer diário.
Para mais sobre padrões de paginação e lógica de retry ciente de rate limit, veja nosso guia de rate limits da API do Twitter.
Código funcional: Python e JavaScript {#working-code-python-and-javascript}
Os exemplos abaixo são padrões de produção que rodamos contra o endpoint ao vivo: paginação por cursor, backoff de 429 com retries exponenciais e uma pequena folga de lote para respeitar o teto de 20 req/s.
Python
import requests
import time
API_KEY = "YOUR_API_KEY"
URL = "https://api.sorsa.io/v3/search-tweets"
def search_tweets(query, order="popular", max_pages=5, max_retries=3):
"""
Search tweets with cursor pagination and 429 backoff.
Args:
query: Search string (X operators supported).
order: "popular" or "latest".
max_pages: Maximum pages to fetch.
max_retries: Retries on 429 before giving up on a page.
Returns:
List of tweet dicts.
"""
all_tweets = []
next_cursor = None
for page in range(max_pages):
body = {"query": query, "order": order}
if next_cursor:
body["next_cursor"] = next_cursor
for attempt in range(max_retries):
resp = requests.post(
URL,
headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
json=body,
)
if resp.status_code == 429:
wait = 2 ** attempt
print(f"Rate limited. Sleeping {wait}s.")
time.sleep(wait)
continue
resp.raise_for_status()
break
else:
print(f"Page {page + 1} failed after {max_retries} retries.")
break
data = resp.json()
tweets = data.get("tweets", [])
all_tweets.extend(tweets)
print(f"Page {page + 1}: {len(tweets)} tweets (total {len(all_tweets)})")
next_cursor = data.get("next_cursor")
if not next_cursor:
print("End of results.")
break
time.sleep(0.1)
return all_tweets
# Usage
tweets = search_tweets('"Sorsa API" min_faves:5 lang:en', max_pages=10)
for t in tweets:
u = t["user"]
print(f"@{u['username']} ({u['followers_count']} followers)")
print(f" {t['full_text'][:120]}")
print(f" L:{t['likes_count']} RT:{t['retweet_count']} V:{t.get('view_count', 'N/A')}")
JavaScript (Node.js)
const API_KEY = "YOUR_API_KEY";
const URL = "https://api.sorsa.io/v3/search-tweets";
async function searchTweets(query, order = "popular", maxPages = 5, maxRetries = 3) {
const allTweets = [];
let nextCursor = null;
for (let page = 0; page < maxPages; page++) {
const body = { query, order };
if (nextCursor) body.next_cursor = nextCursor;
let data;
for (let attempt = 0; attempt < maxRetries; attempt++) {
const resp = await fetch(URL, {
method: "POST",
headers: { "ApiKey": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (resp.status === 429) {
const wait = Math.pow(2, attempt) * 1000;
console.log(`Rate limited. Sleeping ${wait}ms.`);
await new Promise((r) => setTimeout(r, wait));
continue;
}
if (!resp.ok) throw new Error(`API error: ${resp.status}`);
data = await resp.json();
break;
}
if (!data) break;
const tweets = data.tweets || [];
allTweets.push(...tweets);
console.log(`Page ${page + 1}: ${tweets.length} tweets (total ${allTweets.length})`);
nextCursor = data.next_cursor;
if (!nextCursor) break;
await new Promise((r) => setTimeout(r, 100));
}
return allTweets;
}
(async () => {
const tweets = await searchTweets("bitcoin lang:en min_faves:50", "latest", 5);
for (const t of tweets) {
console.log(`@${t.user.username}: ${t.full_text.slice(0, 100)}`);
}
})();
Pipeline de exportação para CSV
Um padrão downstream comum é buscar para CSV e depois carregar em um notebook ou ferramenta de BI:
import requests, time, csv
API_KEY = "YOUR_API_KEY"
URL = "https://api.sorsa.io/v3/search-tweets"
def search_to_csv(query, order="popular", max_pages=10, out="tweets.csv"):
fields = [
"tweet_id", "created_at", "full_text", "lang",
"likes", "retweets", "replies", "quotes", "views",
"username", "display_name", "followers_count", "verified",
]
with open(out, "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=fields)
w.writeheader()
cursor, total = None, 0
for _ in range(max_pages):
body = {"query": query, "order": order}
if cursor:
body["next_cursor"] = cursor
r = requests.post(
URL,
headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
json=body,
)
r.raise_for_status()
data = r.json()
for t in data.get("tweets", []):
u = t.get("user", {})
w.writerow({
"tweet_id": t["id"],
"created_at": t["created_at"],
"full_text": t["full_text"],
"lang": t.get("lang", ""),
"likes": t.get("likes_count", 0),
"retweets": t.get("retweet_count", 0),
"replies": t.get("reply_count", 0),
"quotes": t.get("quote_count", 0),
"views": t.get("view_count", 0),
"username": u.get("username", ""),
"display_name": u.get("display_name", ""),
"followers_count": u.get("followers_count", 0),
"verified": u.get("verified", False),
})
total += 1
cursor = data.get("next_cursor")
if not cursor:
break
time.sleep(0.1)
print(f"Exported {total} tweets to {out}")
search_to_csv(
'(bitcoin OR ethereum) lang:en min_faves:10 -filter:retweets',
order="latest",
max_pages=20,
out="crypto_tweets.csv",
)
A ~20 tweets por página, max_pages=50 te dá ~1.000 tweets. Combinado com a fragmentação por intervalo de data, você pode escalar isto para seis ou sete dígitos sem reescrever o loop, que é exatamente como você monta um dataset do Twitter para machine learning.
Templates de consulta do mundo real {#real-world-query-templates}
Copie estes, troque as variáveis, coloque-os no ar.
Monitoramento de marca (apenas menções orgânicas)
("yourbrand" OR "@yourbrand") -from:yourbrand -filter:retweets lang:en
Pega o que as pessoas dizem sobre você, exclui os seus próprios posts e retweets, só em inglês. Rode em um cron de 5 minutos, canalize para o Slack.
Benchmark de conteúdo de concorrente
(from:competitor1 OR from:competitor2 OR from:competitor3) min_faves:100 -filter:replies since:2026-01-01
Os posts originais de melhor desempenho deles na janela de data. Jogue em uma planilha, ordene por engajamento, aprenda o que funciona. Nosso guia de análise de concorrentes no Twitter transforma isto em um fluxo repetível.
Acompanhamento de sentimento
(bitcoin OR $BTC) (bullish OR bearish OR moon OR crash OR pump OR dump) min_faves:20 lang:en
Tweets carregados de sentimento acima de um piso de qualidade. Combine com o pipeline de análise de sentimento linkado acima para a pontuação.
Mineração de feedback de produto
"yourproduct" (bug OR broken OR issue OR love OR amazing OR hate) -filter:retweets
Feedback orgânico, dos dois sabores. Útil para suporte e entrada de roadmap de produto.
Geração de leads
("looking for" OR "anyone recommend" OR "best tool for") (api OR scraping OR twitter data) -filter:retweets lang:en
Pessoas pedindo ativamente. Filtre mais por min_faves:1 para descartar tráfego de bot.
Janela de reação a evento
"product launch" OR "announcement" from:yourbrand since:2026-05-01 until:2026-05-08
Reações ao seu próprio lançamento dentro de uma janela definida. Combine from:yourbrand (os seus posts) com uma consulta à parte para a conversa ao redor.
Buscar tweets contra acompanhar menções: qual endpoint? {#search-tweets-vs-track-mentions-which-endpoint}
Dois endpoints se sobrepõem em cargas de acompanhamento de menções. Qual escolher:
/search-tweets é o endpoint de propósito geral. Qualquer combinação de operador, qualquer formato de consulta. Use-o quando você precisa de flexibilidade, quando a sua consulta não é só sobre um @, ou quando você quer misturar menções com filtros de engajamento em uma única expressão booleana.
/mentions é feito para o propósito de acompanhar @-menções de um único @. Ele expõe o conjunto de filtros mais rico da nossa API: min_likes, min_replies, min_retweets, since_date, until_date, todos como parâmetros de primeira classe em vez de operadores inline. Use-o quando o seu fluxo é especificamente "me alerte sobre novas menções de @marca acima de X de engajamento".
Regra de decisão rápida: se a sua consulta começa com @handle e termina com filtros de engajamento, use /mentions. Se ela envolve vários termos, grupos booleanos ou operadores que não sejam de menção, use /search-tweets.
Para um olhar mais de perto no endpoint de menções e nos fluxos de monitoramento de marca, veja nosso guia da API de menções do Twitter.
Como a busca da Sorsa se compara à API oficial do X {#how-sorsa-search-compares-to-the-official-x-api}
A Sorsa é o nosso produto, então aqui está o lado a lado honesto com números reais para as duas, incluindo onde a API oficial ainda vence. Para busca somente leitura pura, o problema do descarte silencioso de operadores e a cobrança de autor por leitura são as duas razões práticas pelas quais as equipes saem da v2.
| Dimensão | Sorsa /search-tweets | API oficial do X v2 /2/tweets/search/recent |
|---|---|---|
| Modelo de preço | Planos mensais fixos; a partir de US$ 0,02 por 1.000 tweets quando em lote | Pagamento por uso, ~US$ 0,005 por leitura de post (cerca de US$ 5,00 por 1.000) |
| Grátis para começar | 100 requisições grátis, sem cartão, todos os endpoints | Sem crédito grátis; compre créditos antes da primeira chamada |
| Perfil do autor na resposta | Embutido por padrão, sem cobrança extra | Leitura de usuário à parte, ~US$ 0,010 cada, via expansions=author_id |
| Autenticação | Chave de API no cabeçalho ApiKey | Bearer Token OAuth 2.0 |
| Aprovação de conta | Cadastro instantâneo, sem fila de aprovação | Cadastro no Developer Console |
Operadores de engajamento (min_faves:, min_retweets:, min_replies:) | Sim | Ignorados em silêncio |
| Paridade de operadores da web | Conjunto completo repassado | Apenas subconjunto, sintaxe diferente (has:, is:) |
| Arquivo histórico | Volta até 2006 | ~7 dias recentes; arquivo completo só em níveis de compromisso maior |
| Rate limit | 20 req/s, todos os planos | Baseado em crédito, varia |
| Monitoramento em tempo real | Polling a 20 req/s | Stream filtrado disponível |
| Ações de escrita (postar, curtir, DM) | Nenhuma (somente leitura) | Sim |
No custo de leitura a diferença é grande. Ler 1.000 posts na API oficial do X sai cerca de US$ 5,00, e isso antes da cobrança à parte de US$ 0,010 por autor. Na Sorsa os mesmos 1.000 tweets custam cerca de US$ 0,10 pelo endpoint paginado /search-tweets (cerca de 20 tweets por requisição) e caem para cerca de US$ 0,02 quando os mesmos IDs são puxados pelo endpoint de lote /tweet-info-bulk, perfis de autor incluídos de qualquer forma. Na base em lote isso é até 50x mais barato por 1.000 tweets, com os dados de autor que o X cobra como uma segunda leitura incluídos sem custo extra.
Onde a API oficial é a escolha certa: stream filtrado para tempo real de verdade baseado em push, e ações de escrita (postar, curtir, seguir) que não oferecemos de forma alguma. Para tudo somente leitura, o caminho de tarifa fixa é ao mesmo tempo mais barato e mais simples de operar em qualquer volume significativo.
Na prática. Uma equipe de análise social de cerca de 12 pessoas com quem trabalhamos ficava na zona desconfortável do meio: eles estavam puxando entre 50.000 e alguns milhões de leituras de post por mês, bem além do ponto onde o pagamento por uso se mantém barato, mas nem perto do volume que justifica um contrato enterprise. Na API oficial, os perfis de autor dobravam o custo por busca deles porque o autor de cada tweet era cobrado como uma leitura à parte. Mover a carga de leitura para um plano fixo com dados de autor embutidos cortou a conta mensal de dados deles em mais de uma ordem de grandeza e tornou o número previsível, o que importou mais para o time financeiro deles do que a economia bruta. A migração que impulsionou a mudança é a mesma mapeada passo a passo no guia de migração linkado antes.
Erros comuns e solução de problemas {#common-errors-and-troubleshooting}
Coisas que mordem as pessoas, em ordem aproximada de com que frequência as vemos no suporte.
Resultados vazios em uma consulta que você sabe que deveria retornar algo. Suspeitos de sempre: um erro de digitação em um operador (min_likes em vez de min_faves), uma frase que precisa de aspas duplas ("black cat" e não black cat), ou um -filter: que exclui demais. Reduza a consulta a uma palavra-chave, confirme que ela retorna resultados, e depois adicione os operadores de volta um por vez.
429 Too Many Requests. Você excedeu 20 requisições por segundo na chave. Faça backoff por um segundo e tente de novo. Os exemplos em Python e JavaScript acima implementam backoff exponencial para isso. O limite de 20 req/s é universal em todos os nossos planos; se você precisa de vazão maior de forma sustentada, nos contate sobre limites customizados.
O cursor para de avançar ou retorna duplicatas após paginação profunda. Este é o problema coberto na seção de fragmentação por intervalo de data. Qualquer índice de busca fica instável além de uma certa profundidade de paginação em consultas ruidosas. Mude para fragmentos semanais since:/until:.
Operador ignorado em silêncio. Se um filtro parece não ter efeito, você provavelmente está enviando um operador de busca da web para a API v2 oficial, que descarta os filtros de engajamento. Confirme qual conjunto de operadores o seu provedor aceita antes de assumir que a consulta está errada.
Teto de operadores. O índice de busca do X parece falhar em silêncio consultas com mais de aproximadamente 22 a 23 operadores, e a busca recente de autoatendimento na API oficial limita a query string a 512 caracteres. Se a sua consulta tem mais agrupamentos do que isso e retorna vazia, simplifique-a ou divida-a em várias requisições.
O objeto user está ausente ou parcial. O autor foi suspenso, apagado ou tornou a conta protegida entre o momento em que o tweet foi criado e o momento em que você o requisitou. O tweet ainda existe no índice mas o autor não é mais publicamente enumerável. Trate isto com padrões tweet.get("user", {}) no seu código.
Resultados de idioma inesperados apesar de lang:en. O detector de idioma do X não é perfeito, especialmente em tweets curtos com hashtags ou scripts misturados. Para cargas de análise, pós-filtre com uma biblioteca de detecção de idioma (como langdetect ou fasttext-langdetect) no campo full_text.
Contas privadas e com shadowban não aparecendo. Contas protegidas não estão no índice de busca. Contas suspensas e travadas também ficam ocultas. Não há operador para mostrá-las. O shadowban é uma questão de diagnóstico separada da visibilidade de busca e não é algo que o índice de busca consiga responder.
Perguntas frequentes {#frequently-asked-questions}
Como buscar tweets sem a API oficial do Twitter?
Use uma API de busca de terceiros ou um scraper de código aberto. APIs REST de terceiros embrulham a própria infraestrutura de scraping atrás de uma chave de API sem OAuth e com suporte completo a operadores da web; a Sorsa é uma dessas APIs alternativas do Twitter (X), com um endpoint /search-tweets de tarifa fixa que repassa cada operador. Bibliotecas de código aberto como o Twikit funcionam para trabalhos pequenos e avulsos mas não são estáveis o suficiente para produção.
Como buscar tweets por hashtag usando a API?
Passe a hashtag como um termo de consulta, por exemplo #worldcup, e combine-a com filtros para controlar o volume: #worldcup min_faves:50 lang:en -filter:retweets retorna tweets originais populares em inglês carregando aquela hashtag. A API oficial do X v2 também corresponde #hashtag mas não consegue aplicar pisos de engajamento e limita a busca recente a cerca de sete dias, então para histórico de hashtag mais profundo uma API de operadores da web de tarifa fixa é a rota mais capaz.
Dá para buscar tweets com mais de 7 dias?
Sim, em APIs de terceiros. O endpoint /search-tweets da Sorsa cobre o arquivo histórico completo voltando até 2006 com os operadores since: e until:. A busca recente da API oficial do X v2 é limitada a cerca de 7 dias; a busca de arquivo completo na API oficial é restrita a níveis de compromisso maior.
Quantos tweets recebo por requisição de busca?
Uma única requisição /search-tweets retorna uma página de cerca de 20 tweets. Para puxar mais, use paginação por cursor com next_cursor. Para datasets acima de alguns milhares de tweets, combine paginação por cursor com fragmentação por intervalo de data para evitar deriva de cursor em percursos longos.
Quais são os operadores de busca do Twitter mais úteis para desenvolvedores?
Os operadores de alta alavancagem em código de produção são from:, to:, min_faves:, min_retweets:, since:, until:, lang: e as exclusões -filter:retweets e -filter:replies. Os filtros de engajamento são particularmente valiosos porque removem ruído de baixa qualidade sem perder conteúdo relevante, e porque não funcionam na API oficial do X v2.
A API de busca do Twitter aceita lógica booleana (AND, OR, NOT)?
Sim. Termos separados por espaço implicam AND. OR em maiúsculas é OR explícito. Parênteses agrupam expressões. Um prefixo de menos exclui termos: crypto -scam. Um exemplo completo é (bitcoin OR ethereum) min_faves:100 -filter:retweets lang:en.
Quanto custa buscar tweets via API em 2026?
A API oficial do X v2 custa cerca de US$ 0,005 por leitura de post no pagamento por uso, mais cerca de US$ 0,010 por leitura de perfil de autor, o que dá cerca de US$ 5,00 por 1.000 tweets antes dos dados de autor. A Sorsa é mensal fixa e começa com 100 requisições grátis, sem cartão. Em lote pelo /tweet-info-bulk, os dados de tweet dão cerca de US$ 0,02 por 1.000 tweets no plano Pro (de US$ 0,049 no Starter até US$ 0,018 no Enterprise), perfis de autor incluídos; pelo endpoint paginado /search-tweets a cerca de 20 tweets por requisição fica mais perto de US$ 0,10 por 1.000.
Dá para buscar tweets em tempo real?
Na prática, sim, por polling. Com um rate limit de 20 req/s e order: "latest", você pode fazer polling de uma consulta a cada poucos segundos e receber novos tweets em segundos após a postagem. Para streaming de verdade baseado em push, o stream filtrado da API oficial do X é a única opção que entrega sem polling. Para a maioria das cargas de monitoramento, o polling em intervalos de 30 a 60 segundos é suficiente e mais barato de operar.
Primeiros passos {#getting-started}
Você pode testar o endpoint antes de escrever uma linha de código de cliente. O playground interativo da API roda requisições reais contra a sua chave do navegador, e o construtor visual de consulta de busca te dá um formulário para operadores e emite o corpo JSON exato para enviar.
Quando estiver pronto para pegar uma chave: as primeiras 100 requisições são grátis sem cartão e cobrem todos os 40 endpoints, o cadastro leva minutos sem aprovação de conta de desenvolvedor, e todo plano roda nas mesmas 20 requisições por segundo fixas. Em lote, os planos fixos dão até US$ 0,02 por 1.000 tweets. Cadastre-se no painel da Sorsa e siga o guia de quickstart para a configuração de cinco minutos. Se você está saindo da API oficial, o guia de migração linkado antes mapeia cada endpoint v2 para o seu equivalente na Sorsa com código dos dois lados.
Revisado por Keksich, fundador da Sorsa, profissional de marketing e pesquisador da API do X.
Como este guia foi montado: ele se apoia no nosso trabalho prático construindo e operando a infraestrutura de busca da Sorsa, testado ao vivo contra o endpoint /search-tweets, e em uma comparação direta com o endpoint de busca recente da API oficial do X v2. O comportamento dos operadores foi checado contra a referência mantida pela comunidade igorbrigadir/twitter-advanced-search e a documentação oficial da API do X; o preço reflete as tarifas por leitura da API oficial do X vigentes em 8 de julho de 2026. Os detalhes de endpoint vêm da documentação da Sorsa API. Mais sobre quem publica este blog está na nossa página Sobre.