KYC yok — kimlik yok, selfie yok, belge yok. Kripto ile ödeme: BTC, USDT, USDC, ETH, SOL, LTC
Dil: Türkçe
API anahtarı alın

Docs · Node.js 18+ · fetch · ESM

Node.js'te SERP API: fetch, bir worker pool ve sayfalama

Bağımlılık yok: Node.js, 18. sürümden beri fetch sunuyor. Editörler ve TypeScript için JSDoc tipli küçük bir client, hesabınızın sınırına uyan bir pool ve sonuçlar tükendiğinde duran bir sayfalama döngüsü.

Son güncelleme: · 4 dk okuma

Hızlı yanıt

Node.js'te bir SERP API'yi nasıl kullanırım?

Authorization: Bearer <key> header'ıyla fetch("https://serpcrypto.com/api/v1/search?" + new URLSearchParams({ q })) çağırın ve await res.json() okuyun. Node.js 18+ hiçbir paket gerektirmez. SerpCrypto, başarılı arama başına 1 kredi karşılığında Google veya Bing sonuçlarını JSON olarak döndürür, $0,30/1K arama itibarıyla başlar ve hatalar için asla ücret almaz. Kripto ile ödeme, KYC olmadan.

Bir bakışta Node.js kurulumu

Çalışma zamanıNode.js 18 veya üzeri (yerleşik fetch, AbortSignal.timeout)
ModüllerES modülleri: .mjs dosyaları veya package.json içinde "type": "module"
Anahtarprocess.env.SERPCRYPTO_API_KEY
Zaman aşımıAbortSignal.timeout(90_000) ile 90 saniye
Paralel aramalarconcurrency_limit boyutuna göre ayarlanmış bir havuz
TürlerVS Code ve tsc --checkJs tarafından okunan JSDoc typedef'leri

Küçük, tipli bir client nasıl yazarım?

Endpoint'i, header'ı ve hata yönetimini tek bir modülde toplayın. JSDoc @typedef satırları yanıtı tanımlar, böylece editörler organic_results otomatik tamamlar ve kodunuzu derleme adımı olmadan tip kontrolünden geçirir. TypeScript kullanıcıları aynı şekilleri bir interface'e kopyalayabilir.

search fonksiyonu, mesajında HTTP durum kodu ve API'nin hata code bilgisini taşıyan bir Error fırlatır. Kodunuz ardından 429, 502 ve 504 için yeniden denemeye, diğerlerinde durmaya karar verebilir; hatalar sayfası bunu açıklıyor.

serp-client.mjs
// serp-client.mjs — Node.js 18+, no dependency
const API_URL = "https://serpcrypto.com/api/v1/search";
const CREDITS_URL = "https://serpcrypto.com/api/v1/credits";
const headers = { Authorization: `Bearer ${process.env.SERPCRYPTO_API_KEY}` };

/**
 * @typedef {Object} OrganicResult
 * @property {number} position
 * @property {string} title
 * @property {string} link
 * @property {string} [snippet]
 * @property {string} [date]
 */

/**
 * @typedef {Object} SearchResponse
 * @property {Object} search_metadata
 * @property {string} search_metadata.id
 * @property {string} search_metadata.status
 * @property {number} search_metadata.credits_used
 * @property {OrganicResult[]} [organic_results]
 * @property {Object} [pagination]
 * @property {number} pagination.current
 * @property {number} [pagination.next_page]
 */

/**
 * Run one search (1 credit when it succeeds).
 * @param {string} q
 * @param {Record<string, string | number>} [params]
 * @returns {Promise<SearchResponse>}
 */
export async function search(q, params = {}) {
  const query = new URLSearchParams({ q, ...Object.fromEntries(Object.entries(params).map(([k, v]) => [k, String(v)])) });
  const res = await fetch(`${API_URL}?${query}`, { headers, signal: AbortSignal.timeout(90_000) });
  if (!res.ok) {
    const body = await res.json().catch(() => ({}));
    const err = new Error(`${res.status} ${body.error?.code ?? "error"}: ${body.error?.message ?? ""}`);
    err.status = res.status;
    throw err;
  }
  return res.json();
}

/** Free: credits left, used today and the concurrency limit. */
export async function credits() {
  const res = await fetch(CREDITS_URL, { headers });
  if (!res.ok) throw new Error(`credits: HTTP ${res.status}`);
  return res.json();
}

429'a takılmadan aramaları paralel nasıl çalıştırırım?

Hesabınızın izin verdiği kadar worker başlatın ve her biri paylaşılan listeden sıradaki anahtar kelimeyi alsın. Havuz, ücretsiz kredi endpoint'inden concurrency_limit okur, böylece hesabın kabul ettiğinden fazla aramayı aynı anda göndermez.

Başarısız olan anahtar kelime kaydedilir ve worker devam eder. Hataları sonradan yeniden çalıştırın: hatalar ücretsizdir, yani ikinci geçiş başarılı olana kadar ücretsizdir.

batch.mjs: worker havuzu
// batch.mjs — parallel searches, never more than the account's limit at once
import { search, credits } from "./serp-client.mjs";

const keywords = ["password manager", "note taking app", "time tracking software", "invoice software"];
const { concurrency_limit: limit } = await credits();

let next = 0;
const results = new Map();

async function worker() {
  while (next < keywords.length) {
    const kw = keywords[next++];
    try {
      const data = await search(kw, { gl: "us", hl: "en" });
      results.set(kw, data.organic_results?.[0]?.link ?? null);
    } catch (err) {
      results.set(kw, `failed: ${err.message}`);
    }
  }
}

await Promise.all(Array.from({ length: Math.min(limit, keywords.length) }, worker));
console.table(Object.fromEntries(results));

Birden fazla sonuç sayfasını nasıl çekerim?

page üzerinde döngü kurun ve pagination.next_page eksik olduğunda durun. Google'ın Eylül 2025'te num=100 değerini dikkate almayı bırakmasından bu yana sunduğu gibi sayfa başına yaklaşık 10 organik sonuç; her ek sayfa bir kredi daha. Bir anahtar kelimenin üç sayfalık kontrolü üç kredi tutar; yalnızca tek sayfa sonucu olan bir anahtar kelime ise bir kredi tutar.

pages.mjs
// pages.mjs — up to three pages, stop when results end
import { search } from "./serp-client.mjs";

async function topResults(q, pages = 3, params = {}) {
  const rows = [];
  for (let page = 1; page <= pages; page++) {
    const data = await search(q, { ...params, page });
    for (const r of data.organic_results ?? []) rows.push({ page, position: r.position, link: r.link });
    if (!data.pagination?.next_page) break; // nothing more: save the credits
  }
  return rows;
}

console.log(await topResults("headless cms", 3, { gl: "de", hl: "en" }));

API'yi tarayıcıdan veya edge function'dan çağırabilir miyim?

Bir sunucudan veya edge function'dan evet: Cloudflare Workers, Vercel ve Deno aynı fetch sağlar. Bir tarayıcı sayfasından hayır: API anahtarı her ziyaretçiye görünür olur. Araya anahtarı tutan ve yalnızca izin verdiğiniz parametreleri ileten küçük bir sunucu route'u koyun.

Aynı kural mobil uygulamalar için de geçerlidir. Kullanıcının cihazına gönderilen her şey okunabilir, bu yüzden API anahtarları sunucularınızda kalır.

Node.js'te maliyetleri nasıl öngörülebilir tutarım?

Yaptığınız çağrıları sayın: başarılı bir çağrı bir kredidir, 100.000 arama paketinde $0,56/1K arama fiyatla. Büyük bir toplu işlemden önce credits_remaining kontrol edin ve havuzu sıfıra yaklaştığında durdurun; bir dizi 402 yanıtı toplamayın. Ön ödemeli arama kredileri hiçbir zaman sona ermez: kullanılmayan aramalar siz kullanana kadar hesabınızda kalır, böylece kullanılmayan bakiye sonraki iş için saklanır.

Node.js soruları

SerpCrypto için bir npm paketi var mı?

Hayır. Yukarıdaki client, fetch kullanan yaklaşık 40 satır standart JavaScript'tir, yani bizden kurulacak bir şey yok. Projenize kopyalayın ve uyarlayın.

CommonJS (require) ile çalışır mı?

Örnekler, üst düzey await için ES modülleri kullanır. Bir CommonJS dosyasında çağrıları bir async fonksiyonu içine alın ve fetch aynı şekilde kullanın; Node.js 18+ sürümünde global'dir.

TypeScript ile nasıl kullanırım?

JSDoc şekillerini bir interface SearchResponse içine kopyalayın ve res.json() sonucunu bununla tiplendirin. organic_results? gibi isteğe bağlı bloklar isteğe bağlı kalmalıdır, çünkü bir sayfa bunları göstermeyebilir.

Hangi Node.js sürümüne ihtiyacım var?

Yerleşik fetch için Node.js 18 veya üzeri. AbortSignal.timeout Node.js 17.3'ten itibaren mevcuttur, yani 18 bu sayfadaki her şeyi kapsar.

$0,30/1K arama itibarıyla · KYC olmadan

API anahtarı alın