// docs

X Tweets Search

Extrai tweets de busca do X por palavra-chave usando Nitter como fonte publica, com dados de autor anonimizados por hash salgado, texto, metricas, links, midia e paginacao por cursor.

Nota importante: alguns campos podem retornar null em produção, dependendo da página de origem. Nesta documentação, os exemplos de output são preenchidos intencionalmente com valores não nulos para facilitar integração.

Quando a entidade consultada não existe na origem, o extract e a tool MCP retornam 200 com data: null e notFound: true. Esse caso é tratado como resposta concluída, não como erro de servidor.

Chamada HTTP

cURL
curl -X POST https://api.geckoapi.com.br/v1/extract \
  -H "Authorization: Bearer SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{
  "keyword": "openai",
  "target": "x.com",
  "type": "plp",
  "page": 1
}'

Chamada MCP

A mesma seam também aparece no MCP hospedado como uma tool dedicada. Os argumentos reaproveitam os campos do extract, mas target e type já ficam fixos pela tool.

Ver guia completo do MCP

Endpoint

POST /v1/mcp

Tool name

x_com_plp

Auth

Bearer ou X-API-Key

x_com_plp tools/call
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "x_com_plp",
    "arguments": {
      "keyword": "openai",
      "page": 1,
      "executionId": "exec_example_123"
    }
  }
}

Possibilidades de input

Campos suportados nesta API do POST /v1/extract, com regras específicas de obrigatoriedade e condicionais.

Campo Tipo Status Regra Default Exemplo
keyword
Palavra-chave para buscas PLP. Em Google Search ela representa a query enviada ao Google; em Booking PLP é obrigatória; em outros PLPs pode substituir a URL.
string Obrigatório Obrigatorio. Representa a busca enviada ao Nitter para localizar tweets do X. - openai
target
Fonte alvo da extração.
enum Obrigatório Sempre obrigatorio no payload e deve ser x.com. - x.com
type
Tipo da extração: pdp, idp, plp, ilp, quote, review ou places.
enum Obrigatório Sempre obrigatorio no payload e deve ser plp. - plp
page
Paginacao. Em PLP, inclusive Trivago, e no Reclame AQUI ILP inicia em 1; em review (MercadoLivre, Booking e Hoteis) inicia em 0. O Reclame AQUI ILP aceita ate a pagina 100.
integer Opcional Pagina de tweets (inteiro de 1 a 10). Como o Nitter usa cursor, o backend caminha pelos cursores ate a pagina solicitada. 1 1

Exemplos de request

Busca por tweets - primeira pagina

Fluxo recomendado; envie apenas keyword e page. A URL do Nitter e montada automaticamente pelo backend.

Busca por tweets - primeira pagina
{
  "keyword": "openai",
  "target": "x.com",
  "type": "plp",
  "page": 1
}

Busca por tweets - pagina 2

O backend navega internamente pelo cursor do Nitter para retornar tweets mais antigos da mesma keyword.

Busca por tweets - pagina 2
{
  "keyword": "openai",
  "target": "x.com",
  "type": "plp",
  "page": 2
}

Schema de response (leaf paths)

Mapa de paths de saída com tipo esperado para esta API.

responseSchema
{
  "requestId": "string (uuid)",
  "executionId": "string (uuid)",
  "notFound": "boolean (optional; true when the upstream entity was not found and data is null)",
  "data.source": "string",
  "data.provider": "string",
  "data.type": "string",
  "data.url": "string",
  "data.requestUrl": "string",
  "data.searchUrl": "string",
  "data.extractedAt": "string (iso datetime)",
  "data.query": "string",
  "data.page": "number",
  "data.resultsPerPage": "number",
  "data.offset": "number",
  "data.primaryResults": "number",
  "data.totalResults": "number | null",
  "data.hasMore": "boolean",
  "data.nextPage": "number | null",
  "data.nextPageUrl": "string | null",
  "data.nextCursor": "string | null",
  "data.exhaustedBeforePage": "boolean",
  "data.items[].position": "number",
  "data.items[].id": "string | null",
  "data.items[].url": "string | null",
  "data.items[].nitterUrl": "string",
  "data.items[].author.username": "string | null",
  "data.items[].author.handle": "string | null",
  "data.items[].author.displayName": "string | null",
  "data.items[].author.profileUrl": "string | null",
  "data.items[].author.nitterProfileUrl": "string | null",
  "data.items[].author.avatarUrl": "string | null",
  "data.items[].author.verified": "boolean",
  "data.items[].author.verifiedType": "string | null",
  "data.items[].publishedAt": "string | null",
  "data.items[].publishedAtRaw": "string | null",
  "data.items[].relativeTime": "string | null",
  "data.items[].text": "string | null",
  "data.items[].contentHtml": "string | null",
  "data.items[].retweetedBy": "string | null",
  "data.items[].replyTo[]": "string",
  "data.items[].hashtags[]": "string",
  "data.items[].mentions[]": "string",
  "data.items[].links[].url": "string",
  "data.items[].links[].text": "string | null",
  "data.items[].media[].type": "string",
  "data.items[].media[].url": "string | null",
  "data.items[].media[].thumbnailUrl": "string | null",
  "data.items[].media[].altText": "string | null",
  "data.items[].stats.comments": "number",
  "data.items[].stats.retweets": "number",
  "data.items[].stats.quotes": "number",
  "data.items[].stats.likes": "number",
  "data.items[].stats.views": "number"
}

Exemplo de response

responseExample
{
  "requestId": "req_01HZXAMPLE0000000000000000",
  "executionId": "exec_01HZXAMPLE0000000000000000",
  "notFound": false,
  "data": {
    "source": "x.com",
    "provider": "nitter.net",
    "type": "plp",
    "url": "https://nitter.net/search?f=tweets&q=openai",
    "requestUrl": "https://nitter.net/search?f=tweets&q=openai",
    "searchUrl": "https://nitter.net/search?f=tweets&q=openai",
    "extractedAt": "2026-05-17T14:45:30.000Z",
    "query": "openai",
    "page": 1,
    "resultsPerPage": 20,
    "offset": 0,
    "primaryResults": 20,
    "totalResults": 0,
    "hasMore": true,
    "nextPage": 2,
    "nextPageUrl": "https://nitter.net/search?f=tweets&q=openai&cursor=DAADDAABCgABExample",
    "nextCursor": "DAADDAABCgABExample",
    "exhaustedBeforePage": false,
    "items": [
      {
        "position": 1,
        "id": "tweet_8f65c0d6a71b2e34",
        "url": "x://tweet/tweet_8f65c0d6a71b2e34",
        "nitterUrl": "nitter://tweet/tweet_8f65c0d6a71b2e34",
        "author": {
          "username": "user_4b1d2f90a63c5e18",
          "handle": "@user_4b1d2f90a63c5e18",
          "displayName": "display_2d8ad6a2f4c901ef",
          "profileUrl": "x://user/user_4b1d2f90a63c5e18",
          "nitterProfileUrl": "nitter://user/user_4b1d2f90a63c5e18",
          "avatarUrl": "avatar_a4bfe91c8842d70e",
          "verified": true,
          "verifiedType": "Verified blue account"
        },
        "publishedAt": "2026-05-17T14:45:00.000Z",
        "publishedAtRaw": "May 17, 2026 · 2:45 PM UTC",
        "relativeTime": "24s",
        "text": "Building with #OpenAI and url_02fdcfb7d67c7c80",
        "contentHtml": "Building with <a href=\"link_3b7e588a5e9f2450\">#OpenAI</a> and <a href=\"link_8c305bbd1bd38ff3\">url_02fdcfb7d67c7c80</a>",
        "retweetedBy": "retweet_223f1c6c5d9c4b80",
        "replyTo": [
          "@user_94c47df2cbbf2f93"
        ],
        "hashtags": [
          "#OpenAI"
        ],
        "mentions": [
          "@user_94c47df2cbbf2f93"
        ],
        "links": [
          {
            "url": "link_3b7e588a5e9f2450",
            "text": "#OpenAI"
          },
          {
            "url": "link_8c305bbd1bd38ff3",
            "text": "link_text_0ea8d4aa9c1b2a64"
          }
        ],
        "media": [
          {
            "type": "image",
            "url": "media_76652f4f2ec86107",
            "thumbnailUrl": "thumbnail_b216bdb83a8caa91",
            "altText": "alt_458e56f647245215"
          }
        ],
        "stats": {
          "comments": 2,
          "retweets": 3,
          "quotes": 0,
          "likes": 4,
          "views": 1200
        }
      }
    ]
  }
}

Referência completa de campos

Path Tipo Descrição Exemplo
data.exhaustedBeforePage boolean Indica que a pagina solicitada ficou alem do ultimo cursor disponivel. false
data.extractedAt string (iso datetime) Timestamp ISO da extracao. 2026-05-17T14:45:30.000Z
data.hasMore boolean Indica se ha cursor para carregar tweets mais antigos. true
data.items[].author.avatarUrl string | null Token pseudonimo do avatar. avatar_a4bfe91c8842d70e
data.items[].author.displayName string | null Token pseudonimo do nome exibido. display_2d8ad6a2f4c901ef
data.items[].author.handle string | null Token pseudonimo do autor com @. @user_4b1d2f90a63c5e18
data.items[].author.nitterProfileUrl string | null Referencia pseudonima do perfil no Nitter. nitter://user/user_4b1d2f90a63c5e18
data.items[].author.profileUrl string | null Referencia pseudonima do perfil no x.com. x://user/user_4b1d2f90a63c5e18
data.items[].author.username string | null Token pseudonimo do autor sem @. user_4b1d2f90a63c5e18
data.items[].author.verified boolean Indica se o markup do Nitter mostra selo de verificacao. true
data.items[].author.verifiedType string | null Texto/tipo de verificacao quando disponivel. Verified blue account
data.items[].contentHtml string | null HTML do conteudo do tweet com hrefs e identificadores anonimizados. Building with <a href="link_3b7e588a5e9f2450">#OpenAI</a> and <a href="link_8c305bbd1bd38ff3">url_02fdcfb7d67c7c80</a>
data.items[].hashtags[] string Hashtags encontradas no conteudo. #OpenAI
data.items[].id string | null Token do tweet gerado por hash salgado do ID/caminho original. tweet_8f65c0d6a71b2e34
data.items[].links[].text string | null Texto exibido para o link, com URLs e identificadores anonimizados. #OpenAI
data.items[].links[].url string Token pseudonimo de link presente no conteudo. link_3b7e588a5e9f2450
data.items[].media[].altText string | null Token pseudonimo do texto alternativo quando disponivel. alt_458e56f647245215
data.items[].media[].thumbnailUrl string | null Token pseudonimo da miniatura quando disponivel. thumbnail_b216bdb83a8caa91
data.items[].media[].type string Tipo de midia detectada. image
data.items[].media[].url string | null Token pseudonimo da midia. media_76652f4f2ec86107
data.items[].mentions[] string Mencoes pseudonimas encontradas no conteudo. @user_94c47df2cbbf2f93
data.items[].nitterUrl string Referencia pseudonima equivalente no Nitter; nao contem username nem ID bruto. nitter://tweet/tweet_8f65c0d6a71b2e34
data.items[].position number Posicao do tweet na paginacao retornada. 1
data.items[].publishedAt string | null Data ISO do tweet quando o Nitter fornece title parseavel. 2026-05-17T14:45:00.000Z
data.items[].publishedAtRaw string | null Data original exibida no title do Nitter. May 17, 2026 · 2:45 PM UTC
data.items[].relativeTime string | null Tempo relativo exibido pelo Nitter. 24s
data.items[].replyTo[] string Handles pseudonimos citados pelo bloco de reply. @user_94c47df2cbbf2f93
data.items[].retweetedBy string | null Token pseudonimo de retweet quando o item e um retweet. retweet_223f1c6c5d9c4b80
data.items[].stats.comments number Numero de comentarios exibido pelo Nitter. 2
data.items[].stats.likes number Numero de likes exibido pelo Nitter. 4
data.items[].stats.quotes number Numero de quotes exibido pelo Nitter. 0
data.items[].stats.retweets number Numero de retweets exibido pelo Nitter. 3
data.items[].stats.views number Numero de visualizacoes exibido pelo Nitter. 1200
data.items[].text string | null Texto limpo do tweet com handles, emails, URLs e identificadores longos anonimizados por hash salgado. Building with #OpenAI and url_02fdcfb7d67c7c80
data.items[].url string | null Referencia pseudonima equivalente no x.com; nao contem username nem ID bruto. x://tweet/tweet_8f65c0d6a71b2e34
data.nextCursor string | null Cursor Nitter extraido do link Load more. DAADDAABCgABExample
data.nextPage number | null Proxima pagina numerica que pode ser solicitada. 2
data.nextPageUrl string | null URL Nitter com cursor para a proxima pagina. https://nitter.net/search?f=tweets&q=openai&cursor=DAADDAABCgABExample
data.offset number Offset estimado considerando 20 tweets por pagina do Nitter. 0
data.page number Pagina solicitada. 1
data.primaryResults number Quantidade de itens principais retornados. 20
data.provider string Site usado para ler os tweets publicos. nitter.net
data.query string Keyword pesquisada. openai
data.requestUrl string Mesmo valor de `data.url`; nunca expõe o endpoint interno consultado. https://nitter.net/search?f=tweets&q=openai
data.resultsPerPage number Quantidade de tweets retornados nesta pagina. 20
data.searchUrl string URL inicial da busca no Nitter. https://nitter.net/search?f=tweets&q=openai
data.source string Fonte publica exposta pela API. x.com
data.totalResults number | null Total de resultados quando disponivel; Nitter nao fornece total confiavel. 0
data.type string Tipo da API, sempre plp. plp
data.url string URL efetivamente usada para a pagina retornada. https://nitter.net/search?f=tweets&q=openai
executionId string (uuid) Identificador de execucao usado pelo gateway. exec_01HZXAMPLE0000000000000000
notFound boolean (optional; true when the upstream entity was not found and data is null) Presente e true quando a entidade upstream nao foi encontrada. false
requestId string (uuid) Identificador unico da requisicao. req_01HZXAMPLE0000000000000000

Erros comuns

Respostas com notFound: true não entram nesta tabela, porque retornam sucesso HTTP 200.

Status errorCode Quando acontece
400 INVALID_PAYLOAD JSON inválido ou violação das regras de validação do payload.
401 UNAUTHORIZED Header Authorization ausente ou token/chave inválida.
402 INSUFFICIENT_CREDITS Saldo de créditos insuficiente para a API solicitada.
403 FORBIDDEN Usuário sem acesso ou API temporariamente desabilitada.
409 EXECUTION_CONFLICT executionId conflita com uma execução em estado incompatível.
429 RATE_LIMIT_EXCEEDED / TOO_MANY_INFLIGHT_REQUESTS Limite de taxa ou limite de requisições em voo excedido.
5xx UPSTREAM_TIMEOUT / UPSTREAM_HTTP_ERROR / WORKER_INVOCATION_FAILED / WORKER_FUNCTION_ERROR / WORKER_INVALID_RESPONSE / INTERNAL_ERROR Falha de servidor no worker, provider/proxy ou gateway. Nesses casos os créditos são estornados automaticamente.