Zum Inhalt springen
Live-Katalog

Fahrzeughistorie (VHR)

Status, Fehler und Webhooks

So funktioniert’s

01Authentifizierung

Sende x-api-key bei jeder Anfrage. Quellen-IDs und Formate kommen aus deinem Katalog und der VIN-Prüfung; Zugang und Preise wendet die API an.

02Prüfen, dann eine Quelle wählen

POST /checks liefert price, available_formats und eine Vorschau für jede Quelle. POST /reports nimmt eine source_id, eine Sprache und ein oder mehrere Formate, zu einem Preis pro Bericht. Ist availability_confirmed false, lies zuerst availability_notice.

03Dateien statt Verlauf in der Antwort

JSON, HTML und PDF kommen als Links auf unserem CDN; manche Quellen behalten Fotos oder eine fertige HTML-Seite unter ihrer ursprünglichen Adresse. Behandle jeden Berichtslink wie einen Zugangsschlüssel.

04Lange Anfragen

HTTP wartet bis zu 10 Sekunden. HTTP 202 heißt, die Arbeit läuft weiter: frag status_url alle 1 bis 2 Sekunden ab, bis der Status final ist. Wiederhole nie einen laufenden Kauf.

05Fehler und Wiederherstellung

Ein Quellenfehler ist nicht dasselbe wie keine Daten. Ein Bericht wird nur berechnet, wenn jede gewählte Datei fertig ist. Scheitern die Dateien, nutzt POST /reports/{id}/retry die gespeicherten Daten, ohne zweite Berechnung.

06Webhooks

Für echte VINs füge eine öffentliche HTTPS webhook_url und ein webhook_secret (16 bis 256 Zeichen) hinzu. Die API antwortet mit 202 und sendet das Ergebnis, sobald es fertig ist, signiert in X-VHR-Signature mit X-VHR-Timestamp.

Status

Eine Antwort ist endgültig, wenn ihr Status final ist; bis dahin folge status_url.

Prüfung

running
Läuft noch. Frag status_url ab.
completedFinal
Fertig. Jede Quelle hat geantwortet oder die Dateien sind bereit.
partialFinal
Fertig, aber einige Quellen haben einen Fehler geliefert.
failedFinal
Mit Fehler gestoppt. Es wird nichts berechnet.

Bericht

running
Läuft noch. Frag status_url ab.
preparing
Die Quelldaten sind gespeichert; die Dateien werden erstellt.
rendering
Das PDF wird gerendert.
completedFinal
Fertig. Jede Quelle hat geantwortet oder die Dateien sind bereit.
not_foundFinal
Die Quelle hat keinen Eintrag zu dieser VIN. Es wird nichts berechnet.
failedFinal
Mit Fehler gestoppt. Es wird nichts berechnet.

Jede Quelle einer Prüfung

available
Einträge gefunden: die Quelle kann bestellt werden (kein Statusfeld).
pending
Diese Quelle antwortet noch.
not_found
Die Quelle hat keinen Eintrag zu dieser VIN. Es wird nichts berechnet.
error
Diese Quelle konnte gerade nicht antworten. Das ist nicht dasselbe wie keine Daten.
not_checked
Von dieser Anfrage nicht geprüft. Das heißt nicht, dass es keine Daten gibt.

Fehler

Fehler kommen als JSON mit error_code und message zurück. Für einen Fehler wird nichts berechnet.

401x-api-key fehlt oder ist ungültig.
402Nicht genug Berichtsguthaben für diesen Bericht.
403Diese Berichtsart ist für deinen Key nicht freigeschaltet.
409Derselbe Bericht für diese VIN wird bereits vorbereitet.
422Ungültiger Body, zum Beispiel eine VIN, ein Format oder eine Sprache, oder ein geänderter Preis.
429Zu viele Anfragen. Warte kurz und versuch es erneut.
503Berichte sind kurz pausiert.

Webhooks

Füge webhook_url und webhook_secret zu einer Prüfung oder einem Bericht für eine echte VIN hinzu: Die API antwortet sofort mit 202 und sendet das Ergebnis, sobald es fertig ist. Prüf die Signatur, bevor du ihm vertraust.

  • X-VHR-Signature ist sha256= gefolgt vom HMAC-SHA256 aus dem Wert von X-VHR-Timestamp, einem Punkt und dem rohen Body.
  • Lehne alte Zeitstempel (zum Beispiel älter als 5 Minuten) und wiederholte X-VHR-Event-Id-Werte ab.
  • Beispiel-VINs antworten sofort und rufen nie einen Webhook auf.
import crypto from 'node:crypto'
 
// raw: the request body exactly as received (a Buffer or string)
export const verify = (raw, headers, secret) => {
const stamp = headers['x-vhr-timestamp']
const sent = String(headers['x-vhr-signature'] || '').replace('sha256=', '')
const age = Math.abs(Date.now() / 1000 - Number(stamp))
if (!stamp || !Number.isFinite(age) || age > 300) return false
const mac = crypto.createHmac('sha256', secret).update(`${stamp}.${raw}`).digest('hex')
return sent.length === mac.length && crypto.timingSafeEqual(Buffer.from(sent), Buffer.from(mac))
}
© 2025. AuctionsAPI operates independently and is not affiliated with Copart, IAAI or Encar.