Sem KYC — sem documento de identidade, sem selfie, sem documentos. Pague com cripto: BTC, USDT, USDC, ETH, SOL, LTC
Idioma: Português
Obtenha uma chave de API

Docs · Node.js

Exemplos em Node.js: pesquisa com fetch, um pequeno pool e respostas com citações

O Node 18 e versões mais recentes já trazem fetch, então a API não precisa de nenhum pacote. Esta página mostra uma pesquisa, um pool que executa várias pesquisas sem estourar seu rate limit e um loop que transforma fontes em uma resposta com citações numeradas.

Última atualização: · 5 min de leitura

Resposta rápida

Como chamo uma API de pesquisa na web para agentes de IA a partir do Node.js?

Use o fetch nativo do Node 18+ para enviar sua consulta por POST para https://llmwebsearch.com/api/v1/search com uma chave Bearer. LLMWebSearch responde com resultados classificados e as 3 principais páginas em Markdown, prontas para numerar e passar a um modelo para uma resposta com citações. Uma pesquisa custa 1 crédito, a partir de US$ 1,20/1K pesquisas em outubro de 2026. Nenhum pacote npm é necessário. Sem KYC; pague com cripto.

O que você precisa

Node.js18 ou mais recente, para o fetch nativo; salve os scripts como .mjs para await de nível superior
PacotesNenhum
ChaveLLMWEBSEARCH_API_KEY no seu ambiente
Para o loop de respostaUm endpoint de chat compatível com OpenAI: LLM_BASE_URL, LLM_API_KEY, LLM_MODEL
CobrançaUm crédito paga uma pesquisa: até 20 resultados classificados, com as páginas dos 3 primeiros lidas e devolvidas em Markdown. Ler de 4 a 10 páginas custa 2 créditos. Uma chamada que termina em erro não custa nada

Como escrevo uma função de pesquisa reutilizável?

Envolva a chamada uma vez e reutilize em todo lugar. A função abaixo envia o body, lança um erro legível em qualquer falha HTTP e retorna o JSON analisado. Os erros carregam o próprio code da API, como rate_limited ou insufficient_credits, para que quem chama decida o que fazer.

search.mjs
const API = 'https://llmwebsearch.com/api/v1/search';

export async function search(body) {
  const res = await fetch(API, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.LLMWEBSEARCH_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(body),
  });
  const data = await res.json();
  if (!res.ok) {
    const err = new Error(`${res.status} ${data.error?.code}: ${data.error?.message}`);
    err.status = res.status;
    throw err;
  }
  return data;
}

const data = await search({ q: 'how to size a postgres connection pool', read: 3 });
for (const r of data.results) {
  console.log(r.position, r.content_status, r.url, r.word_count ?? '');
}

Como faço várias pesquisas sem atingir o rate limit?

Execute-as através de um pequeno pool: um número fixo de workers, cada um pega a próxima consulta de uma lista compartilhada. Quatro workers é um bom começo. Toda conta tem um limite de chamadas por minuto, exibido no dashboard; peça ao suporte e ele pode ser aumentado.

O pool abaixo não precisa de biblioteca. Cada worker mantém seus próprios resultados, e uma pesquisa com falha é registrada com seu erro em vez de interromper a execução. Isso importa para agentes de pesquisa, onde uma subpergunta ruim não deve custar a tarefa inteira.

pool.mjs
const API = 'https://llmwebsearch.com/api/v1/search';
const questions = [
  'what is connection pooling in postgres',
  'recommended pool size per cpu core',
  'pgbouncer transaction mode limitations',
  'connection pool exhaustion symptoms',
  'pool size for serverless functions',
];

async function search(q) {
  const res = await fetch(API, {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.LLMWEBSEARCH_API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ q, read: 2, max_chars: 4000 }),
  });
  const data = await res.json();
  if (!res.ok) return { q, error: data.error?.code ?? String(res.status) };
  return { q, urls: data.results.filter((r) => r.content_status === 'ok').map((r) => r.url) };
}

async function runPool(items, size, task) {
  const out = [];
  let next = 0;
  const worker = async () => {
    while (next < items.length) {
      const i = next++;
      out[i] = await task(items[i]);
    }
  };
  await Promise.all(Array.from({ length: size }, worker));
  return out;
}

for (const row of await runPool(questions, 4, search)) console.log(row);

Como transformo resultados em uma resposta com citações?

Numere as fontes, coloque a URL ao lado de cada uma, corte-as conforme um limite e peça ao modelo que cite por número. A API retorna fontes, não uma resposta escrita: o seu próprio modelo lê as páginas, escreve a resposta e cita as URLs. O script abaixo fala com qualquer endpoint chat/completions compatível com OpenAI, escolhido com três variáveis de ambiente, então funciona tanto com modelos hospedados quanto locais.

O limite de cerca de 24.000 caracteres, aproximadamente 6.000 tokens, é dividido igualmente entre as fontes. Um resultado cuja página não pôde ser lida é passado como seu snippet, marcado como tal.

answer.mjs
const SEARCH = 'https://llmwebsearch.com/api/v1/search';
const BUDGET = 24000; // characters, about 6,000 tokens

async function sources(question) {
  const res = await fetch(SEARCH, {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.LLMWEBSEARCH_API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ q: question, max_results: 5, read: 3 }),
  });
  const { results } = await res.json();
  const share = Math.floor(BUDGET / Math.max(results.length, 1));
  return results
    .map((r, i) => {
      const body = r.content_status === 'ok' ? r.content.slice(0, share) : `(snippet only) ${r.snippet}`;
      return `[${i + 1}] ${r.title} - ${r.url}\n${body}`;
    })
    .join('\n\n');
}

async function answer(question) {
  const prompt = 'Answer using only the sources below. Cite them as [1], [2] and so on. '
    + 'Say so if they do not answer the question.\n\n' + (await sources(question)) + '\n\nQuestion: ' + question;
  const res = await fetch(`${process.env.LLM_BASE_URL.replace(/\/$/, '')}/chat/completions`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.LLM_API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ model: process.env.LLM_MODEL, messages: [{ role: 'user', content: prompt }] }),
  });
  const data = await res.json();
  return data.choices[0].message.content;
}

console.log(await answer('How should I size a Postgres connection pool?'));

Devo usar GET ou POST no Node?

POST, com um corpo JSON, no código da aplicação. Arrays como include_domains e perguntas longas viajam mais limpos em um corpo do que em uma query string. O GET está lá para testes rápidos e para ferramentas que não conseguem enviar um corpo; monte a query string com URLSearchParams e junte listas com vírgulas.

Ambos os formatos custam o mesmo e retornam o mesmo JSON. A referência de pesquisa lista todos os parâmetros para ambos.

Onde a chave deve ficar?

Em uma variável de ambiente lida em tempo de execução, nunca no arquivo de código. Em um servidor, use o cofre de segredos da sua plataforma. No navegador, não chame a API de jeito nenhum: a chave ficaria visível para todos os visitantes. Chame seu próprio backend, que por sua vez chama LLMWebSearch.

Crie uma chave de API por agente, app ou colega de equipe e revogue qualquer uma delas no dashboard sem afetar as outras. Uma chave por serviço facilita a leitura do histórico do painel e torna uma chave vazada fácil de revogar.

Node.js: perguntas frequentes

Existe um pacote npm?

Não. fetch é nativo do Node 18 e superiores, e a API é JSON puro sobre HTTPS. As funções desta página são a integração inteira.

Funciona em Deno, Bun ou runtimes de edge?

O código usa apenas fetch, JSON e process.env. Runtimes com fetch funcionam depois de substituir process.env pela própria forma de ler segredos deles.

Como faço para tentar novamente chamadas com falha?

Tente novamente apenas 429, 502 e 504, com uma pausa que dobra a cada tentativa. Nunca tente novamente 400, 401 ou 402. A página de erros explica o motivo e mostra um helper.

A partir de US$ 1,20/1K pesquisas · sem KYC

Obtenha uma chave de API