// 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. - iphone 15 pro max
target
Fonte alvo da extração.
enum Obrigatório Sempre obrigatorio no payload e deve ser x.com. - mercadolivre.com.br
type
Tipo da extração: pdp, idp, plp, quote, review ou places.
enum Obrigatório Sempre obrigatorio no payload e deve ser plp. - pdp
page
Paginacao. Em PLP inicia em 1; em review (MercadoLivre, Booking e Hoteis) inicia em 0.
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 2

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 URL enviada ao provedor de extracao para a pagina retornada. 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.