Como ler as respostas de um tweet de forma programática

Como ler as respostas de um tweet de forma programática
Unif Cookbooks team
Unif Cookbooks team

Atualizado

Um endpoint grátis que retorna as respostas públicas de qualquer post do X em JSON ou Markdown, por engajamento ou data, com paginação.

Em resumo: GET https://unifapi.com/tools/x/replies?id=<post id or URL> devolve o post e as respostas públicas abaixo dele em JSON. É grátis, sem fazer login, sem precisar de conta e sem chave de API, com limite por visitante. sort=top (padrão) ordena por engajamento, sort=recent por tempo. As páginas têm 20 respostas com um nextCursor. Cada resposta traz autor, texto, métricas, mídia e inReplyToPostId, então dá para reconstruir a thread. É o único pedaço do X que nenhum dos endpoints gratuitos de post único expõe, e o motivo de a maioria das tarefas de agente do tipo "leia essa thread" acabar em um navegador headless.

As respostas abaixo de um post são onde mora a reação. O post em si diz o que uma marca falou; as respostas dizem o que as pessoas acham disso, o que quebrou, o que elas querem e qual reclamação ganhou 4.000 curtidas. Para análise de sentimento, pesquisa com clientes e monitoramento de incidentes, elas são o dado.

Também são a parte mais difícil do X de ler sem conta. O FxTwitter e o vxTwitter leem um post. O endpoint de syndication lê um post. A própria página do X carrega as respostas com JavaScript depois do fato, então o curl recebe uma casca vazia. A API oficial expõe respostas via busca por conversa nos níveis pagos.

A requisição

curl -s "https://unifapi.com/tools/x/replies?id=https://x.com/NASA/status/2107237881668313108"

id aceita o ID numérico do post ou a URL completa de x.com / twitter.com. A resposta:

{
  "post": {
    "id": "2107237881668313108",
    "text": "Time to bring them home 🌎 …",
    "author": { "handle": "NASA", "name": "NASA", "verified": true },
    "metrics": {
      "likes": 7210,
      "reposts": 846,
      "replies": 262,
      "quotes": 60,
      "bookmarks": 197,
      "views": 2823329
    },
    "conversationId": "2107237881668313108"
  },
  "replies": {
    "items": [
      {
        "id": "2107252849688424504",
        "text": "@NASA @Space_Station @SpaceX Those space suits don't look right…",
        "createdAt": "2026-10-05T23:33:22.000Z",
        "author": {
          "handle": "Troyztoys",
          "name": "Tee Crenshaw",
          "verified": true,
          "followers": 1823
        },
        "metrics": {
          "likes": 15,
          "reposts": 1,
          "replies": 0,
          "quotes": 0,
          "bookmarks": 0,
          "views": 894
        },
        "media": [],
        "conversationId": "2107237881668313108",
        "inReplyToPostId": "2107237881668313108"
      }
    ],
    "hasMore": true,
    "nextCursor": "20@"
  }
}

post é o original. replies.items são os posts públicos da conversa dele além do original, tanto respostas diretas quanto aninhadas. Cada um tem inReplyToPostId, então uma resposta a uma resposta aponta para o pai e a thread pode ser reconstruída como uma árvore.

Ordenação

sort=top (o padrão) ordena por curtidas mais reposts mais respostas, mais ou menos como a aba "Mais relevantes" do próprio X faz. sort=recent ordena do mais novo para o mais antigo. Para "qual é a reação", use top; para "o que aconteceu na última hora", use recent.

A página para humanos, /tools/x-reply-viewer, tem as mesmas duas opções como pílulas, e /tools/x-reply-viewer?q=<id>&sort=recent&format=json devolve exatamente o que a API devolve.

Paginação

As respostas vêm 20 por página. Devolva nextCursor como cursor para continuar. O primeiro cursor costuma se parecer com 20@, que significa "as próximas 20 da página já buscada"; os seguintes são os cursores opacos do próprio X. Trate todos como strings opacas.

Um post com 262 respostas tem cerca de 14 páginas. São 14 das suas 20 unidades gratuitas a cada 10 minutos, então leia X-RateLimit-Remaining nos headers e pare quando tiver o suficiente; a primeira página ordenada por top normalmente já contém as respostas que importam.

O que um registro de resposta contém

CampoSignificado
id, urlO id da resposta e a URL canônica em x.com
textTexto completo, com as @menções iniciais do jeito que o X as armazena
createdAtISO 8601, UTC
authorhandle, name, verified, followers, avatarUrl, …
metricslikes, reposts, replies, quotes, bookmarks, views
mediaFotos e vídeos com tamanhos e URLs de MP4 na CDN do X
inReplyToPostIdO post que esta resposta responde
conversationIdO post raiz da conversa
possiblySensitiveA flag do próprio X

O formato é o mesmo registro post que os endpoints de busca, perfil e mídia devolvem, então uma função que pontua um post funciona em uma resposta sem alteração.

Três coisas para construir

Um resumo de reações. Busque a página top, passe os 20 textos para um modelo junto com o post original e peça os três sentimentos mais comuns com uma citação representativa de cada. Vinte respostas e uma chamada; a ordenação top já fez o ranqueamento.

Um feed de reclamações. Para o anúncio de uma marca, consulte sort=recent a cada 10 minutos, guarde as respostas cujo metrics.likes passa de um limiar entre uma consulta e outra e encaminhe essas para uma pessoa. As que estão subindo são as que vão virar print.

Uma reconstrução de thread. Percorra todas as páginas, monte um mapa de id para resposta e então ligue cada resposta ao seu inReplyToPostId. Respostas ao original ficam na profundidade um; o resto se aninha. Renderize em Markdown e você tem uma transcrição legível da conversa para um relatório.

Limites

  • Só respostas públicas. Respostas de contas protegidas e respostas apagadas não entram, e por isso a contagem de replies no post original pode ser maior do que o que dá para ler.
  • O limite gratuito é de 20 consultas a cada 10 minutos por visitante, somando todos os endpoints /tools/x/*, e uma busca conta como duas. Um 429 traz Retry-After e a URL onde o teto é levantado.
  • Volume, histórico e garantias ficam na API do X / Twitter medida, pay as you go com uma chave de workspace, com os mesmos nomes de campo.

FAQ

Dá para pegar as respostas de um tweet sem a API do Twitter?

Sim. O endpoint acima lê respostas públicas grátis, sem fazer login, sem precisar de conta e sem chave, com limite por visitante. Devolve JSON por padrão e Markdown com format=md.

Por que o X diz 262 respostas e eu só vejo 200?

Algumas respostas são de contas protegidas, algumas foram apagadas e algumas foram ocultadas pelo autor. A contagem no post original é a do X; o conjunto legível é o que é público.

Inclui posts com citação?

Não. Citações são posts separados, não respostas. Busque a URL do post com /tools/x/search?q=<post url> para encontrá-las.

Dá para ler as respostas como texto para um modelo?

Sim. format=md devolve o post original e cada resposta como um bloco de Markdown com autor, texto, métricas e URL.