Ohne KYC — kein Ausweis, kein Selfie, keine Dokumente. Mit Krypto bezahlen: BTC, USDT, USDC, ETH, SOL, LTC
Sprache: Deutsch
API-Schlüssel erhalten

Docs · Node.js 18+ · fetch · ESM

SERP-API in Node.js: fetch, ein Worker-Pool und Pagination

Keine Abhängigkeit: Node.js hat fetch seit Version 18. Ein kleiner Client mit JSDoc-Typen für Editoren und TypeScript, ein Pool, der das Limit Ihres Kontos einhält, und eine Pagination-Schleife, die stoppt, wenn die Ergebnisse ausgehen.

Zuletzt aktualisiert: · 5 Min. Lesezeit

Kurze Antwort

Wie verwende ich eine SERP-API in Node.js?

Rufen Sie fetch("https://serpcrypto.com/api/v1/search?" + new URLSearchParams({ q })) mit dem Header Authorization: Bearer <key> auf und lesen Sie await res.json(). Node.js 18+ braucht kein Paket. SerpCrypto liefert Google- oder Bing-Ergebnisse als JSON für 1 Credit pro erfolgreicher Suche, ab 0,30 $/1K Suchanfragen, und berechnet Fehler nie. Mit Krypto bezahlen, ohne KYC.

Node.js-Setup auf einen Blick

LaufzeitumgebungNode.js 18 oder neuer (integriertes fetch, AbortSignal.timeout)
ModuleES-Module: .mjs-Dateien oder "type": "module" in package.json
Schlüsselprocess.env.SERPCRYPTO_API_KEY
Timeout90 Sekunden mit AbortSignal.timeout(90_000)
Parallele SuchenEin Pool dimensioniert auf concurrency_limit
TypenJSDoc-Typedefs, gelesen von VS Code und tsc --checkJs

Wie schreibe ich einen kleinen typisierten Client?

Legen Sie den Endpoint, den Header und die Fehlerbehandlung in ein Modul. Die JSDoc-Zeilen @typedef beschreiben die Antwort, sodass Editoren organic_results vervollständigen und Ihren Code ohne Build-Schritt typisieren.

Die Funktion search wirft einen Error mit dem HTTP-Status und dem Fehler-code der API in der Meldung. Ihr Code kann dann entscheiden, bei 429, 502 und 504 erneut zu versuchen und bei den anderen abzubrechen, wie es die Fehlerseite erklärt.

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();
}

Wie führe ich Suchen parallel aus, ohne auf 429 zu stoßen?

Starten Sie so viele Worker, wie Ihr Account erlaubt, und lassen Sie jeden den nächsten Suchbegriff aus einer gemeinsamen Liste nehmen. Der Pool liest concurrency_limit aus dem Endpoint für Gratis-Credits, sodass er nie mehr Suchen gleichzeitig sendet, als der Account akzeptiert.

Ein fehlgeschlagener Suchbegriff wird vermerkt, und der Worker macht weiter. Starten Sie die Fehlschläge danach erneut: Fehler kosten nichts, ein zweiter Durchlauf ist also gratis, bis er erfolgreich ist.

batch.mjs: ein Pool aus Workern
// 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));

Wie rufe ich mehrere Ergebnisseiten ab?

Schleifen Sie über page und stoppen Sie, sobald pagination.next_page fehlt. Etwa 10 organische Ergebnisse pro Seite, so wie Google sie liefert, seit num=100 im September 2025 nicht mehr berücksichtigt wird; jede weitere Seite kostet einen weiteren Credit. Eine Prüfung über drei Seiten für einen Suchbegriff kostet drei Credits; ein Suchbegriff mit nur einer Ergebnisseite kostet eine.

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" }));

Kann ich die API aus einem Browser oder einer Edge-Funktion aufrufen?

Aus einem Server oder einer Edge-Funktion ja: Cloudflare Workers, Vercel und Deno bieten alle das gleiche fetch. Aus einer Browserseite nein: Der Schlüssel wäre für jeden Besucher sichtbar. Schalten Sie eine kleine Server-Route dazwischen, die den Schlüssel hält und nur die Parameter weiterleitet, die Sie erlauben.

Dieselbe Regel gilt für mobile Apps. Alles, was auf das Gerät eines Nutzers ausgeliefert wird, kann gelesen werden, daher bleiben Schlüssel auf Ihren Servern.

Wie halte ich die Kosten in Node.js planbar?

Zählen Sie Ihre Aufrufe: Ein erfolgreicher Aufruf ist ein Credit, zu 0,56 $/1K Suchanfragen im 100.000 Suchanfragen-Paket. Prüfen Sie credits_remaining vor einem großen Batch und stoppen Sie den Pool, wenn er sich der Null nähert, statt eine Reihe von 402-Antworten zu sammeln. Vorausbezahlte Such-Credits verfallen nie: ungenutzte Suchen bleiben auf Ihrem Konto, bis Sie sie verwenden, sodass ein ungenutzter Rest für den nächsten Job erhalten bleibt.

Node.js-Fragen

Gibt es ein npm-Paket für SerpCrypto?

Nein. Der Client oben umfasst etwa 40 Zeilen Standard-JavaScript mit fetch, es gibt also nichts von uns zu installieren. Kopieren Sie ihn in Ihr Projekt und passen Sie ihn an.

Funktioniert das mit CommonJS (require)?

Die Beispiele verwenden ES-Module für await auf oberster Ebene. In einer CommonJS-Datei wickeln Sie die Aufrufe in eine async-Funktion und verwenden fetch genauso; es ist ab Node.js 18+ global.

Wie verwende ich es mit TypeScript?

Kopieren Sie die JSDoc-Formen in ein interface SearchResponse und typisieren Sie damit das Ergebnis von res.json(). Optionale Blöcke wie organic_results? müssen optional bleiben, da eine Seite sie möglicherweise nicht zeigt.

Welche Node.js-Version brauche ich?

Node.js 18 oder höher für das integrierte fetch. AbortSignal.timeout ist ab Node.js 17.3 verfügbar, 18 deckt also alles auf dieser Seite ab.

Ab 0,30 $/1K Suchanfragen · ohne KYC

API-Schlüssel erhalten