Twitter/X Scraper - Tweets, Profiles & Trends
Pricing
from $10.00 / 1,000 tweet scrapeds
Twitter/X Scraper - Tweets, Profiles & Trends
Scrape Twitter/X: tweets, user profiles, followers, hashtags, and trending topics.
Pricing
from $10.00 / 1,000 tweet scrapeds
Rating
5.0
(4)
Developer
viralanalyzer
Maintained by CommunityActor stats
0
Bookmarked
121
Total users
4
Monthly active users
4 days ago
Last modified
Categories
Share
Twitter/X Scraper 🐦
🔗 View on Apify Store | 🇺🇸 English | 🇧🇷 Português
Scrape tweets, profiles, and engagement metrics from Twitter/X. Bring your own X API v2 Bearer Token for reliable access (recommended — X blocks anonymous timeline access), or use the anonymous fallback with configurable proxies.
🇺🇸 English
What does it do?
This actor extracts public tweets and engagement metrics from any Twitter/X profile or search query. Get real data for social media analysis, brand monitoring, and competitive intelligence.
Features
- Profile scraping — Get latest tweets from any public profile
- Search scraping — Find tweets matching any keyword or hashtag
- Full metrics — Views, likes, retweets, replies, quotes, bookmarks
- Media extraction — Each attachment as
{ type, url }, from the anonymous strategies - Thread detection — Identifies if a tweet is part of a thread
- Author info — Username, display name, follower count, verification status
- Date filtering —
dateFrom/dateTorestrict results to a date range (UTC, both bounds inclusive), applied to each tweet'screated_atbefore billing - Reply/Retweet filters — Include or exclude replies and retweets
- Replies mode — pass
tweetUrls(orconversationIds) and get one row per reply of a post, with the author and the badge - Newest first — the batch is ordered by
created_atand the pinned tweet is excluded before the cut, somaxTweets: 1returns the most recent tweet, not a pinned one from years ago - Verification badge —
author.verifiedType(blue|business|government|none),author.isBlueVerifiedand the legacyauthor.verified - No invented values — a metric the source did not expose is
null, never0/false
Capabilities & Limits
Built here — measured 2026-09-23, read this before choosing a path:
- No token needed for the common case. The actor reads the server-rendered x.com page, which embeds the profile's 5 newest tweets with view counts, the pinned marker and reposts. Measured 2026-09-23: a profile whose syndication widget stopped in 2023 came back with its 2025 posts here, with
viewsfilled. - More than ~5 tweets falls back to X's syndication widget (up to 100 per profile). That widget orders by likes, not by date, has no view count and hides retweets and replies — the actor sorts by date anyway and the run log warns when the newest tweet delivered is over 30 days old.
- Replies come from the post's own page (the first few, with author and badge). With an X API token the actor uses recent search instead, which covers the last 7 days.
- With your X API token the official API is used first: it paginates, sends your
dateFrom/dateToasstart_time/end_time(so you do not pay for reads the filter would throw away), asks for media expansions and reads the pinned post id. X bills your own plan at $0.005 per post read, with minimums of 5 posts per timeline request and 10 per search. - Optional unblocking fallback. If x.com refuses the ordinary request, and only then, the actor can fetch the same page through Bright Data Web Unlocker — billed per request, capped by
maxUnlockerRequests(default 3). LeavebrightDataApiTokenempty to skip it.
What this actor can and cannot accept as a seed, based on the real input schema:
| Discover by | Supported | Notes |
|---|---|---|
| Handle / username | ✅ Yes | profiles array (without @) |
| Hashtag | ⚠️ Partial | No dedicated field — pass it inside searchQuery (e.g. #tech); search mode needs the X API Bearer Token |
| Keyword / search | ⚠️ Partial | searchQuery works only with an X API v2 Bearer Token (X removed anonymous search); recent tweets only |
| Profile URL | ✅ Yes | startUrls or seeds + seedType: "url"; x.com/home, /search and /i/... are rejected and named in the log |
| Tweet URL (replies) | ✅ Yes | tweetUrls — returns the replies of that post, one row each |
| Subreddit | ❌ N/A | Not a Reddit actor |
Output includes: tweet text ✅, views ✅, likes ✅, retweets ✅, replies count ✅, quotes ✅, bookmarks ✅, hashtags ✅, media ✅, author (username, displayName, followers, verified) ✅, created_at (ISO 8601) ✅, language ✅, is_thread / is_reply / is_retweet ✅.
| Not in the output | Why | |
|---|---|---|
| Reply / comment text | ⚠️ replies mode | in timeline mode only the reply count is returned. Pass tweetUrls to get the text of each reply — with an X API token: without one, X answered the anonymous conversation request with HTTP 404 (measured 2026-09-23) and the run returns a diagnostic without charging |
thumbnail on media items | ❌ | a media entry is { type, url } — X's own media URL. No separate thumbnail or :small variant is emitted |
| Impressions on the syndication fallback | ⚠️ | the widget carries no view count, so views is null for tweets that came from it. The x.com page (used first) does carry views |
Input
| Field | Type | Default | Description |
|---|---|---|---|
profiles | string[] | — | Twitter/X usernames (with or without @). With no profile, search or tweet URL the run returns a diagnostic instead of scraping a default account |
tweetUrls | string[] | — | Replies mode: URLs (or ids) of the posts whose replies you want |
includePinned | boolean | false | Keep the pinned tweet in the results (it is excluded by default because it is often years old) |
brightDataApiToken | string | — | Optional unblocking fallback, billed per request. Empty = never used |
maxUnlockerRequests | integer | 3 | Hard cap on that paid fallback per run |
searchQuery | string | — | Search term (alternative to profiles) |
maxTweets | integer | 20 | Max tweets per profile/search (1-100) |
includeReplies | boolean | false | Include reply tweets |
includeRetweets | boolean | false | Include retweets |
dateFrom | string | — | Inclusive lower bound on created_at. YYYY-MM-DD (= 00:00:00.000Z UTC) or full ISO-8601 |
dateTo | string | — | Inclusive upper bound on created_at. YYYY-MM-DD (= 23:59:59.999Z UTC, whole day included) or full ISO-8601 |
Date range (dateFrom / dateTo) - exact behavior
Both fields are optional and independent; leaving one empty leaves that side unbounded, and leaving both empty disables the filter entirely.
- Where it runs. With an X API token the bounds are sent to the API as
start_time/end_time, so you are not billed for posts the filter would discard (the API accepts dates from 2010-11-06 on the timeline; recent search only covers the last 7 days). The anonymous strategies have no date parameter, so there the comparison happens locally on each tweet'screated_at— a narrow or old range can return fewer items thanmaxTweets, or nothing at all. - Inclusive, UTC. A tweet is kept when
dateFrom <= created_at <= dateTo.YYYY-MM-DDindateFrommeans00:00:00.000Zof that day; indateToit means23:59:59.999Z, sodateFrom = dateTo = 2026-01-20returns that whole day. A full ISO-8601 timestamp is used exactly as given. - Billing. The filter runs before the tweet is stored and before the Pay Per Event counter is incremented. You are never charged for a tweet the date filter discards.
- Tweets with no date. A few anonymous fallback paths return a tweet whose
created_atisnull. While any bound is set, such a tweet is dropped - its membership in the range cannot be verified, so it is neither returned nor charged. The run log reports how many were dropped for this reason. - Invalid input. An unreadable
dateFrom/dateTo, or a range wheredateFromis afterdateTo, stops the run with a labeled_dataQuality: "diagnostic"item explaining the problem, and charges nothing. The filter is never silently ignored. - Nothing in range. If tweets were found but all fell outside the range, the run succeeds with a diagnostic item stating how many were discarded - again with no charge.
Output Example
{"tweet_id": "1891234567890123456","url": "https://x.com/elikifreitasdev/status/1891234567890123456","text": "🚀 Launched the new version! Performance 3x better #tech #automation","author": {"username": "elikifreitasdev","displayName": "Eliki Freitas | Dev","followers": 12500,"verified": false,"isBlueVerified": true,"verifiedType": "blue"},"created_at": "2026-01-20T14:30:00.000Z","views": 45200,"likes": 892,"retweets": 156,"replies": 43,"quotes": 12,"bookmarks": 234,"hashtags": ["tech", "automation"],"media": [{"type": "image","url": "https://pbs.twimg.com/media/example.jpg"}],"is_thread": false,"is_reply": false,"is_retweet": false,"is_pinned": false,"conversation_id": "1891234567890123456","in_reply_to_id": null,"language": "en"}
Use Cases
- Brand Monitoring — Track mentions and sentiment about your brand
- Competitor Analysis — Monitor competitor tweet performance
- Influencer Research — Evaluate engagement rates before partnerships
- Trend Detection — Discover viral topics and hashtags
- Content Strategy — Analyze what tweet formats get the most engagement
FAQ
Does it require a Twitter API key?
Recommended. X blocks anonymous (guest) access to timelines, so for reliable results provide your own twitterBearerToken (X API v2 — your own plan/quota at https://developer.x.com). Search/keyword mode (searchQuery) requires the Bearer Token (X removed anonymous search). Without a token, the actor tries anonymous strategies (subject to blocking) and, if nothing is extracted, returns a diagnostic guide without charging PPE.
Why did dateFrom / dateTo return fewer tweets than maxTweets?
Because the range is applied locally, to the tweets the actor was able to fetch (the most recent ones a strategy exposes), not as a remote query parameter. Tweets outside the range — and, while a bound is set, tweets with no readable created_at — are dropped before being stored, and are not charged. See "Date range — exact behavior" above.
Why did I get an old tweet / when is views null?
The syndication widget returns a profile's tweets ordered by engagement, not by date, and the old build pushed whatever came first — that is why a 2022 post was returned for maxTweets: 1. The actor now reads the x.com page first (newest tweets, with view counts), orders everything by created_at and drops the pinned tweet before cutting. views is null only for tweets that came from the syndication fallback, which has no impression count — never a fabricated 0.
What do verified, isBlueVerified and verifiedType mean?
verifiedType is X's own value: blue, business, government or none. isBlueVerified is true only for the blue badge. verified is the legacy flag. Any of them is null when the source did not say — null means unknown, false means the source said no.
How do I read the replies of a post?
Set tweetUrls: ["https://x.com/nasa/status/123..."]. Without a token the actor reads the post's own page and returns the first replies X renders there (3 in the measurements, each with author and badge) — enough to sample a conversation, not to export all of it. With an X API token it uses recent search with the conversation_id operator instead, which returns the whole thread for the last 7 days (older threads need X's full-archive access).
Can it scrape protected/private accounts? No. Only public profiles and public tweets are accessible.
What about rate limits? The actor handles rate limiting automatically with built-in delays and retries.
How many tweets can I get per run? Up to 100 tweets per profile or search query per run.
🇧🇷 Português
O que faz?
Este actor extrai tweets públicos e métricas de engajamento de qualquer perfil ou busca no Twitter/X. Dados reais para análise de redes sociais, monitoramento de marca e inteligência competitiva.
Funcionalidades
- Scraping de perfil — Últimos tweets de qualquer perfil público
- Scraping de busca — Encontre tweets por palavra-chave ou hashtag
- Métricas completas — Visualizações, curtidas, retweets, respostas, citações, bookmarks
- Extração de mídia — Cada anexo como
{ type, url }, vindo das estratégias anônimas - Detecção de thread — Identifica se o tweet faz parte de uma thread
- Info do autor — Username, nome, seguidores, verificação
- Filtro por data —
dateFrom/dateTorestringem os resultados a um período (UTC, ambos os limites inclusivos), aplicados aocreated_atde cada tweet antes da cobrança - Filtros de resposta/retweet — Inclua ou exclua respostas e retweets
- Modo replies — informe
tweetUrls(ouconversationIds) e receba uma linha por resposta do post, com o autor e o selo - Mais recente primeiro — o lote é ordenado por
created_ate o tweet fixado é excluído antes do corte, entãomaxTweets: 1devolve o tweet mais recente, não um fixado de anos atrás - Selo de verificação —
author.verifiedType(blue|business|government|none),author.isBlueVerifiede oauthor.verifiedlegado - Sem valor inventado — métrica que a fonte não expôs vem
null, nunca0/false
Capacidades e Limites
Medido em 2026-09-23, leia antes de escolher o caminho:
- Sem token no caso comum. O actor lê a página do x.com renderizada no servidor, que já traz os 5 tweets mais recentes com contagem de visualizações, o marcador de fixado e as repostagens. Medido em 2026-09-23: um perfil cujo widget de syndication parava em 2023 voltou aqui com posts de 2025, com
viewspreenchido. - Acima de ~5 tweets entra o widget de syndication (até 100 por perfil). Esse widget ordena por curtidas, não por data, não tem visualizações e esconde retweets e respostas — o actor ordena por data mesmo assim, e o log avisa quando o tweet mais recente tem mais de 30 dias.
- Respostas vêm da página do próprio post (as primeiras, com autor e selo). Com token da API do X o actor usa a busca recente, que cobre os últimos 7 dias.
- Com o seu token da API do X a API oficial vem primeiro: pagina, envia
dateFrom/dateTocomostart_time/end_time, pede as expansões de mídia e lê o id do fixado. O X cobra do seu plano US$ 0,005 por post lido, com mínimos de 5 posts por requisição de timeline e 10 por busca. - Fallback opcional de desbloqueio. Se o x.com recusar a requisição comum, e só nesse caso, o actor pode buscar a mesma página pelo Web Unlocker da Bright Data — cobrado por requisição, limitado por
maxUnlockerRequests(padrão 3). DeixebrightDataApiTokenvazio para não usar.
O que este actor aceita ou não como semente, conforme o input schema real:
| Descobre por | Suportado | Observações |
|---|---|---|
| Handle / username | ✅ Sim | Array profiles (sem @) |
| Hashtag | ⚠️ Parcial | Sem campo dedicado — passe dentro de searchQuery (ex.: #tech); o modo de busca exige o Bearer Token da API do X |
| Palavra-chave / busca | ⚠️ Parcial | searchQuery funciona apenas com Bearer Token da API X v2 (o X removeu a busca anônima); somente tweets recentes |
| URL de perfil | ✅ Sim | startUrls ou seeds + seedType: "url"; x.com/home, /search e /i/... são rejeitados e nomeados no log |
| URL de tweet (replies) | ✅ Sim | tweetUrls — devolve as respostas daquele post, uma por linha |
| Subreddit | ❌ N/A | Não é um actor de Reddit |
A saída inclui: texto do tweet ✅, visualizações ✅, curtidas ✅, retweets ✅, contagem de respostas ✅, citações ✅, bookmarks ✅, hashtags ✅, mídia ✅, autor (username, displayName, seguidores, verificado) ✅, created_at (ISO 8601) ✅, idioma ✅, is_thread / is_reply / is_retweet ✅.
| Não sai na saída | Motivo | |
|---|---|---|
| TEXTO das respostas/comentários | ⚠️ modo replies | no modo timeline só a contagem é retornada. Informe tweetUrls para obter o texto de cada resposta — com token da API do X: sem token, o X respondeu 404 à consulta anônima de conversa (medido em 2026-09-23) e o run devolve diagnóstico sem cobrar |
thumbnail nos itens de mídia | ❌ | cada anexo é { type, url } — a própria URL de mídia do X. Não há thumbnail separado nem variante :small |
| Visualizações no fallback de syndication | ⚠️ | o widget não traz contagem de views, então views vem null nos tweets vindos dele. A página do x.com, usada primeiro, traz views |
Entrada
| Campo | Tipo | Padrão | Descrição |
|---|---|---|---|
profiles | string[] | — | Usernames do Twitter/X (com ou sem @). Sem perfil, busca ou URL de tweet, o run devolve diagnóstico em vez de raspar uma conta padrão |
tweetUrls | string[] | — | Modo replies: URLs (ou ids) dos posts cujas respostas você quer |
includePinned | boolean | false | Mantém o tweet fixado nos resultados (por padrão ele sai, porque costuma ser antigo) |
brightDataApiToken | string | — | Fallback opcional de desbloqueio, cobrado por requisição. Vazio = nunca usado |
maxUnlockerRequests | inteiro | 3 | Teto do fallback pago por execução |
searchQuery | string | — | Termo de busca (alternativa aos perfis) |
maxTweets | integer | 20 | Máx tweets por perfil/busca (1-100) |
includeReplies | boolean | false | Incluir tweets de resposta |
includeRetweets | boolean | false | Incluir retweets |
dateFrom | string | — | Limite inferior inclusivo sobre created_at. YYYY-MM-DD (= 00:00:00.000Z UTC) ou ISO-8601 completo |
dateTo | string | — | Limite superior inclusivo sobre created_at. YYYY-MM-DD (= 23:59:59.999Z UTC, dia inteiro incluído) ou ISO-8601 completo |
Intervalo de datas (dateFrom / dateTo) - comportamento exato
Os dois campos são opcionais e independentes: deixar um vazio deixa aquele lado sem limite, e deixar os dois vazios desliga o filtro.
- Onde roda. Com token da API do X os limites vão para a API como
start_time/end_time, então você não paga por posts que o filtro descartaria (a API aceita datas a partir de 2010-11-06 na timeline; a busca recente cobre só os últimos 7 dias). As estratégias anônimas não têm parâmetro de data, então ali a comparação é local sobre ocreated_at— um intervalo estreito ou antigo pode devolver menos itens quemaxTweets, ou nenhum. - Inclusivo, em UTC. O tweet é mantido quando
dateFrom <= created_at <= dateTo.YYYY-MM-DDemdateFromsignifica00:00:00.000Zdaquele dia; emdateTosignifica23:59:59.999Z, entãodateFrom = dateTo = 2026-01-20devolve o dia inteiro. Um timestamp ISO-8601 completo é usado exatamente como informado. - Cobrança. O filtro roda antes de o tweet ser gravado e antes de o contador do Pay Per Event ser incrementado. Você nunca é cobrado por um tweet descartado pelo filtro de data.
- Tweets sem data. Alguns caminhos anônimos de fallback devolvem tweet com
created_atigual anull. Com qualquer limite ativo, esse tweet é descartado - não dá para verificar se ele pertence ao intervalo, então ele não é devolvido nem cobrado. O log do run informa quantos caíram por esse motivo. - Entrada inválida.
dateFrom/dateToilegível, ou intervalo em quedateFromé posterior adateTo, interrompe o run com um item_dataQuality: "diagnostic"explicando o problema, sem cobrar nada. O filtro nunca é ignorado em silêncio. - Nada no intervalo. Se tweets foram encontrados mas todos ficaram fora do intervalo, o run termina com sucesso e um item de diagnóstico dizendo quantos foram descartados - também sem cobrança.
Exemplo de Saída
{"tweet_id": "1891234567890123456","url": "https://x.com/elikifreitasdev/status/1891234567890123456","text": "🚀 Lançamos a nova versão! Performance 3x melhor #tech #automation","author": {"username": "elikifreitasdev","displayName": "Eliki Freitas | Dev","followers": 12500,"verified": false,"isBlueVerified": true,"verifiedType": "blue"},"created_at": "2026-01-20T14:30:00.000Z","views": 45200,"likes": 892,"retweets": 156,"replies": 43,"quotes": 12,"bookmarks": 234,"hashtags": ["tech", "automation"],"media": [{"type": "image","url": "https://pbs.twimg.com/media/example.jpg"}],"is_thread": false,"is_reply": false,"is_retweet": false,"is_pinned": false,"conversation_id": "1891234567890123456","in_reply_to_id": null,"language": "pt"}
Casos de Uso
- Monitoramento de Marca — Acompanhe menções e sentimento sobre sua marca
- Análise de Concorrência — Monitore performance de tweets de concorrentes
- Pesquisa de Influenciadores — Avalie taxas de engajamento antes de parcerias
- Detecção de Tendências — Descubra tópicos virais e hashtags
- Estratégia de Conteúdo — Analise quais formatos de tweet geram mais engajamento
FAQ
Precisa de chave de API do Twitter?
Recomendado. O X bloqueia acesso anônimo a timelines; informe seu twitterBearerToken (X API v2, plano/quota próprios — https://developer.x.com) para extração confiável. Sem token, o actor tenta estratégias anônimas (sujeitas a bloqueio) e, se nada for extraído, devolve um guia de diagnóstico sem cobrar PPE.
Por que dateFrom / dateTo devolveram menos tweets que maxTweets?
Porque o intervalo é aplicado localmente, sobre os tweets que o actor conseguiu buscar (os mais recentes que a estratégia expõe), e não como parâmetro remoto de consulta. Tweets fora do intervalo — e, com um limite ativo, tweets sem created_at legível — são descartados antes de serem gravados, e não são cobrados. Veja "Intervalo de datas — comportamento exato" acima.
Por que veio um tweet antigo / quando views vem null?
O widget de syndication devolve os tweets ordenados por engajamento, não por data, e a versão antiga gravava o primeiro que viesse — foi por isso que um post de 2022 saiu com maxTweets: 1. Agora o actor lê primeiro a página do x.com (mais recentes, com visualizações), ordena tudo por created_at e tira o fixado antes do corte. views só vem null nos tweets vindos do fallback de syndication, que não tem esse número — nunca um 0 inventado.
O que significam verified, isBlueVerified e verifiedType?
verifiedType é o valor do próprio X: blue, business, government ou none. isBlueVerified só é verdadeiro no selo azul. verified é a flag legada. Qualquer um deles vem null quando a fonte não disse — null é desconhecido, false é a fonte dizendo que não.
Como leio as respostas de um post?
Use tweetUrls: ["https://x.com/nasa/status/123..."]. Sem token o actor lê a página do próprio post e devolve as primeiras respostas que o X renderiza ali (3 nas medições, cada uma com autor e selo) — dá para amostrar uma conversa, não para exportá-la inteira. Com token da API do X ele usa a busca recente com o operador conversation_id, que devolve a thread dos últimos 7 dias (mais antigas exigem o acesso full-archive do X).
Pode scraper contas protegidas/privadas? Não. Apenas perfis públicos e tweets públicos são acessíveis.
E sobre limites de requisição? O actor gerencia rate limiting automaticamente com delays e retentativas.
Quantos tweets posso obter por execução? Até 100 tweets por perfil ou busca por execução.
💰 Pricing
This actor uses Pay Per Event (PPE) pricing. The rate depends on your Apify plan tier:
| Plan tier | Per tweet | Per 1,000 tweets |
|---|---|---|
| Free | $0.02 | $20.00 |
| Bronze | $0.0175 | $17.50 |
| Silver | $0.015 | $15.00 |
| Gold | $0.01 | $10.00 |
| Platinum | $0.0075 | $7.50 |
| Diamond | $0.005 | $5.00 |
You are never charged for a run that returned nothing. When X blocks the request and no
tweet is extracted, the actor returns a labeled _dataQuality: "diagnostic" setup guide and
charges no PPE event. The same holds for the dateFrom / dateTo filter: tweets discarded
because they fall outside the requested range — or because they carry no readable date while a
bound is set — are dropped before the Pay Per Event counter, so they are never billed.
🔗 Related Actors
✅ Available / Disponível — cross-actor upgrades
The items below were PLANNED in earlier versions and are now implemented and live in this actor. They are additive and backward-compatible: when the new input fields are omitted and
normalizeOutputisfalse, the output is byte-for-byte identical to before — paying users are unaffected.Os itens abaixo eram PLANEJADOS em versões anteriores e agora estão implementados e disponíveis neste actor. São aditivos e retrocompatíveis: quando os novos campos de input são omitidos e
normalizeOutputéfalse, a saída é byte-a-byte idêntica à anterior — usuários pagantes não são afetados.
EN
- Unified input vocabulary (#1) ✅ —
maxResults(alias ofmaxTweets),seeds+seedType(handle|url|keyword) are accepted as a cross-actor unified seed list. The existingprofiles/searchQuery/maxTweetsfields keep working exactly as before; the new ones are optional aliases. - Normalized
_normalizedoutput block (#2) ✅ — set the optional inputnormalizeOutput: trueto attach a cross-platform block to each item:{ platform, url, author, text, views, likes, comments, shares, publishedAtISO, lang, hashtags[], engagementVelocity }, alongside the existing raw fields. For Twitter/X,commentsmaps fromreplies,sharesfromretweets + quotes,viewsfrom impressions. Defaultfalse. - ISO date +
engagementVelocity(#6) ✅ — inside_normalized,publishedAtISOis the tweet date in ISO-8601 UTC, andengagementVelocity=(likes + comments + shares) / hours_since_published(ornullwhen no date is available). - Quality flag
_dataQuality(#7) ✅ — successful items carry_dataQuality: "full"(whennormalizeOutputis on); the recoverable no-results setup guide carries_dataQuality: "diagnostic"and is not charged via PPE.
PT
- Vocabulário de input unificado (#1) ✅ —
maxResults(alias demaxTweets),seeds+seedType(handle|url|keyword) são aceitos como lista de sementes unificada entre actors. Os camposprofiles/searchQuery/maxTweetscontinuam funcionando exatamente como antes; os novos são aliases opcionais. - Bloco de saída normalizado
_normalized(#2) ✅ — defina o input opcionalnormalizeOutput: truepara anexar a cada item um bloco cross-plataforma:{ platform, url, author, text, views, likes, comments, shares, publishedAtISO, lang, hashtags[], engagementVelocity }, ao lado dos campos crus. No Twitter/X,commentsvem dereplies,sharesderetweets + quotes,viewsdas impressões. Padrãofalse. - Data ISO +
engagementVelocity(#6) ✅ — dentro de_normalized,publishedAtISOé a data do tweet em ISO-8601 UTC, eengagementVelocity=(likes + comments + shares) / horas_desde_publicação(ounullquando não há data). - Flag de qualidade
_dataQuality(#7) ✅ — itens bem-sucedidos carregam_dataQuality: "full"(quandonormalizeOutputestá ligado); o guia de diagnóstico recuperável (sem resultados) carrega_dataQuality: "diagnostic"e não é cobrado via PPE.
🛣️ Roadmap / Próximas melhorias (planned)
⚠️ The items below are PLANNED, not yet available. They are not current features — do not rely on them yet. Source: internal social-scrapers improvements handoff (2026-06-19).
⚠️ Os itens abaixo são PLANEJADOS, ainda não disponíveis. Não são funcionalidades atuais — não dependa deles ainda. Fonte: handoff interno de melhorias dos scrapers sociais (2026-06-19).
EN
- (nothing pending here — the structured
_blockReasonshipped in v1.2: the diagnostic item now carries_blockReason: "USER_FILTER_EMPTY"when your own filters emptied the result.)
PT
- (nada pendente aqui — o
_blockReasonestruturado entrou na v1.2: o item de diagnóstico agora traz_blockReason: "USER_FILTER_EMPTY"quando os seus próprios filtros esvaziaram o resultado.)
📝 Changelog
- v1.3.0 (2026-09-23) — New primary source: the server-rendered x.com page, read without executing any of its JavaScript. It brings what the syndication widget never had — correct dates (a profile stuck in 2023 there returns its 2025 posts here), view counts, the pinned marker, reposts and the first replies of a post. Optional Bright Data Web Unlocker fallback, billed per request and capped per run (
maxUnlockerRequests, default 3). The dead guest-token strategies were removed along with the hardcoded web-client bearer. - v1.2.0 (2026-09-23) — Fixed: the anonymous source returns tweets ordered by engagement, so
maxTweets: 1could return a post from years ago; the batch is now ordered by date and the pinned tweet is excluded by default (includePinnedkeeps it). Metrics the source does not expose arenullinstead of0/false, and the author now carriesisBlueVerifiedandverifiedType. New replies mode (tweetUrls/conversationIds). On the X API path: date bounds are sent asstart_time/end_time, results paginate, media expansions are requested, 429 is retried usingx-rate-limit-resetand every request has a timeout. Profile URLs like/homeand/i/...are rejected instead of being scraped as a handle, and a run with nothing to scrape returns a diagnostic instead of falling back to a default account. - v1.1.0 (2026-08-27) —
dateFrom/dateToare now honored: the range is enforced in memory against each tweet'screated_at(UTC, both bounds inclusive) before the tweet is stored and before Pay Per Event, so filtered-out tweets are never charged. Tweets with no readable date are dropped while a bound is set, and an invalid bound stops the run with a diagnostic item instead of being silently ignored. - v1.0.0 (2026-02-12) — Initial release: profile scraping, search, full engagement metrics, thread detection, media extraction