Kleinanzeigen Agent ist jetzt API-first. Die alte API v1 läuft noch bis zum 1. Juni 2026.

Mehr erfahren
Zurück zum Blog

Kleinanzeigen Webhook: neue Inserate in Echtzeit

Wie du mit einem Kleinanzeigen Webhook neue Inserate in Echtzeit auf deinen Server bekommst — ohne Polling, ohne Scraping, mit HMAC-Verifizierung.

7 Min. Lesezeit

Wer Kleinanzeigen-Daten in einer eigenen Anwendung verarbeiten will, landet früher oder später beim selben Problem: Du baust einen Polling-Loop, der die Such-API im Minutentakt aufruft, legst eine Dedup-Tabelle an, damit dieselben Inserate nicht zweimal verarbeitet werden, und kämpfst dabei gegen Rate Limits, die dein Intervall von vorne einschränken. Das Ergebnis ist ein System, das viel Infrastruktur braucht und trotzdem Inserate verpasst, weil der Abstand zwischen zwei Aufrufen zu groß ist.

Ein Kleinanzeigen Webhook dreht dieses Modell um.

Das Problem mit klassischem Polling

Beim Polling fragst du regelmäßig ab, ob es etwas Neues gibt. Das klingt einfach, hat aber in der Praxis mehrere Schwachstellen.

Zeitverzug: Wenn du alle 60 Sekunden abfragst, kann ein frisches Inserat bis zu einer Minute alt sein, bevor es bei dir ankommt. Bei einem 5-Sekunden-Intervall verbesserst du die Latenz, multiplizierst aber gleichzeitig deine API-Aufrufe mal zwölf.

Dedup-Logik auf deiner Seite: Du musst selbst verfolgen, welche ad_id du bereits gesehen hast. Das erfordert persistenten State, Bereinigung alter Einträge und die Frage, wie weit zurück dein Fenster reichen soll.

Rate-Limit-Druck: Je kürzer das Intervall, desto eher stößt du an Limits. Jeder Fehlversuch mit einem 429 ist Zeit, in der du blind bist.

Unnötige Lastspitzen: Die meisten Polling-Aufrufe finden keine neuen Inserate. Der Aufwand entsteht trotzdem.

Was ein Webhook stattdessen tut

Mit einem Kleinanzeigen Webhook kehrt sich die Richtung um: Die Plattform ruft dich auf, wenn es etwas Neues gibt.

  • Du registrierst eine HTTPS-URL, die du kontrollierst.
  • Du legst fest, nach welchen Inseraten du suchst — dieselben Filter wie in der Such-API.
  • Wenn neue Inserate zu deiner Suche passen, schickt der Server eine signierte POST-Anfrage an deine URL.
  • Jede ad_id wird dir genau einmal geliefert — die Dedup-Logik läuft serverseitig.
  • Du verarbeitest nur echte Treffer, keine leeren Aufrufe.

Für alles, was von Neuzugängen abhängt — Deal-Tracker, Marktbeobachtung, Matching-Tools — ist ein Webhook der direktere Weg.

So sieht eine Webhook-Anfrage aus

Wenn neue Inserate gefunden werden, schickt der Server einen POST an deine Webhook-URL. Der Body ist JSON:

{
  "event": "kleinanzeigen.search.ads_found",
  "webhook_id": "5e0f...",
  "delivery_id": "9ab2...",
  "created_at": "2026-05-09T12:00:00.000Z",
  "query": { "q": "iphone", "location_id": "3331", "distance": "25" },
  "data": {
    "meta": { "source": "live", "interval_seconds": 30, "dedupe": "new_ad_ids_only" },
    "ads": [/* normalisiertes Inseratformat */]
  }
}

Zusammen mit dem Body kommen diese Header:

X-Klaz-Webhook-Id: <webhook_id>
X-Klaz-Delivery-Id: <delivery_id>
X-Klaz-Timestamp: 2026-05-09T12:00:00.000Z
X-Klaz-Signature: v1=<hex_hmac>

Die Signatur musst du auf deiner Seite verifizieren, bevor du den Body verarbeitest. Sie wird als HMAC-SHA256 über ${timestamp}.${rawBody} gebildet und mit deinem Webhook-Secret verglichen. In Node.js sieht das in etwa so aus:

import crypto from "crypto";

function isValidSignature(req, secret) {
  const timestamp = req.headers["x-klaz-timestamp"];
  const signature = req.headers["x-klaz-signature"];
  const rawBody = req.rawBody; // ungeparster Buffer oder String

  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  const received = signature?.replace(/^v1=/, "") ?? "";

  return crypto.timingSafeEqual(
    Buffer.from(expected, "hex"),
    Buffer.from(received, "hex")
  );
}

timingSafeEqual ist hier kein Stilmittel — Byte-für-Byte-Vergleiche mit === sind anfällig für Timing-Angriffe.

Filter — gleich wie in der Such-API

Du konfigurierst den Webhook mit denselben Parametern, die du aus der Such-API kennst:

ParameterBeschreibung
qSuchbegriff
category_idKategorie
location_idStandort
distanceRadius in km
min_price / max_pricePreisbereich
ad_typeOFFER oder WANTED
poster_typePRIVATE oder COMMERCIAL
picture_requiredNur Inserate mit Bild
buy_now_onlyNur Sofortkauf-Inserate
shippableNur versandbare Inserate
lat / lngKoordinaten statt location_id

Die Dedup-Garantie: Jede ad_id wird dir über die Laufzeit eines Webhooks genau einmal geliefert. Wenn dasselbe Inserat in zwei aufeinanderfolgenden Scan-Läufen auftaucht, bekommst du es nur beim ersten Mal — danach filtert der Server es heraus.

Welches Intervall passt zu welchem Use Case

Die Scan-Frequenz bestimmst du über den Tier, den du für den Webhook wählst. Vier Stufen stehen zur Verfügung:

Pulse — 60 Sekunden, 9 €/Monat Gut geeignet für passive Marktbeobachtung: du willst wissen, was sich auf einem Markt tut, ohne sofort handeln zu müssen. Hobby-Suchen, gelegentliche Preis-Analysen, Benachrichtigungen ohne Echtzeit-Anspruch.

Flow — 30 Sekunden, 19 €/Monat Der praktische Mittelweg für regelmäßige Integrationen: Monitoring-Dashboards, Datensammlungen für spätere Analysen, Bots, die innerhalb von Minuten reagieren sollen.

Stream — 10 Sekunden, 49 €/Monat Wenn Reaktionszeit zählt: Deal-Tracker, die auf bestimmte Preisschwellen warten, oder Matching-Systeme, bei denen ein frühzeitiger Treffer einen echten Unterschied macht.

Realtime — 5 Sekunden, 99 €/Monat Für Anwendungsfälle, bei denen jede Sekunde zählt: automatisierte Systeme, die auf frische Inserate sofort reagieren und bei denen ein 60-Sekunden-Fenster schlicht zu spät wäre.

Der Tier bestimmt ausschließlich das Scan-Intervall, keine anderen Funktionen oder Filter.

In drei Schritten startklar

Schritt 1 — Account anlegen Registriere dich unter /anmelden. Du brauchst dafür keine Kreditkarte. Der Free-Account gibt dir genug, um die API kennenzulernen; für Webhooks wählst du danach einen Plan.

Schritt 2 — Tier im Dashboard wählen Öffne die Webhook-Übersicht in deinem Dashboard und wähle den Tier, der zu deinem Anwendungsfall passt. Die Abrechnung läuft monatlich, du kannst jederzeit hoch- oder runterstufen.

Schritt 3 — URL und Filter eintragen Trage deine Ziel-URL ein und konfiguriere die Suchfilter. Speichern, fertig — ab diesem Moment scannt der Server in deinem Intervall und liefert dir neue Treffer direkt an deine URL.

Häufige Stolpersteine

Einige Dinge, die in der Produktion häufiger zu Problemen führen:

HTTPS in der Produktion ist Pflicht. Für lokale Entwicklung kannst du einen Tunnel wie ngrok oder cloudflared nutzen. In der Produktion akzeptiert der Server nur HTTPS-Endpunkte.

Idempotenz auf deiner Seite. Bei Netzwerkproblemen oder Timeouts kann eine Anfrage erneut zugestellt werden. Die delivery_id bleibt dabei dieselbe — nutze sie, um doppelte Verarbeitungen sicher abzufangen.

Signatur zuerst, Body danach. Verarbeite den Payload erst, nachdem du die Signatur geprüft hast. Ein Body ohne gültige Signatur sollte mit einem 400 abgelehnt werden, nicht mit einem 200.

Antworte schnell mit 200. Wenn dein Handler länger braucht als das Timeout erlaubt, wertet der Server die Zustellung als fehlgeschlagen und versucht es erneut. Schreibe die Nachricht zunächst in eine interne Queue und gib sofort 200 zurück; die eigentliche Verarbeitung machst du danach asynchron.

Secret nicht im Code-Repository ablegen. Das Webhook-Secret gehört in eine Umgebungsvariable. Du kannst es im Dashboard jederzeit rotieren — danach musst du es in deiner Umgebung aktualisieren, bevor neue Anfragen ankommen.


Wenn du mehr über die technischen Details erfahren willst — verfügbare Filter, Retry-Verhalten, Payload-Struktur und Secret-Rotation — findest du alles in der Dokumentation. Eine Übersicht über Tiers und Preise gibt es unter /webhooks.

Für Fragen und Feedback erreichst du uns unter [email protected].