Webhooks & Preisalarme
Erhalten Sie signierte HTTP-Callbacks, sobald ein Preis Ihren Schwellenwert über- oder unterschreitet, und verifizieren Sie diese zuverlässig mit HMAC-SHA256.
So funktionieren Alarme und Webhooks
MetalAPI sendet Webhooks, wenn ein Preisalarm auslöst. Ein Alarm überwacht ein Symbol in einer Währung Ihrer Wahl. Er löst aus, wenn der Preis einen Schwellenwert über- oder unterschreitet oder sich seit dem vorherigen Schlusskurs um einen bestimmten Prozentsatz nach oben oder unten bewegt.
Alarme reagieren auf das Kreuzen der Schwelle: Sie werden einmal benachrichtigt, sobald die Bedingung erfüllt ist, und der Alarm wird erst wieder scharf geschaltet, nachdem die Bedingung zwischenzeitlich nicht mehr erfüllt war. Eine Sperrfrist (Cooldown, standardmäßig 60 Minuten, einstellbar von 5 Minuten bis 7 Tagen) verhindert eine Flut von Benachrichtigungen, wenn ein Preis um den Schwellenwert pendelt.
Alarme benachrichtigen Sie ab dem Lite-Tarif per E-Mail und ab dem Advanced-Tarif per Webhook (ein HTTPS-POST an Ihren Server).
Webhook einrichten
- Öffnen Sie im Dashboard Alerts und erstellen Sie einen Alarm.
- Wählen Sie Symbol, Währung, Bedingung und Schwellenwert.
- Wählen Sie die Zustellung per Webhook und geben Sie die URL Ihres Endpunkts ein.
- Kopieren Sie Ihr Webhook-Signatur-Secret (es beginnt mit
whsec_) aus dem Dashboard in die Konfiguration Ihres Servers.
Webhook-URLs müssen https:// und einen öffentlich erreichbaren Host verwenden. URLs, die Zugangsdaten enthalten oder auf private bzw. interne IP-Adressen auflösen, werden abgelehnt, und Weiterleitungen werden nicht verfolgt.
Die Payload
Jede Zustellung ist ein JSON-POST mit diesen Headern und diesem Body:
POST /webhooks/metalapi HTTP/1.1
Content-Type: application/json
User-Agent: MetalAPI-Webhooks/1.0
X-MetalAPI-Timestamp: 1792765800
X-MetalAPI-Signature: t=1792765800,v1=3b9f0c4e…a71d
{
"event": "alert.triggered",
"id": 18342,
"created": 1792765800,
"alert": {
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"symbol": "XAU",
"base": "USD",
"condition": "above",
"threshold": 4000,
"note": "Gold above 4k"
},
"price": 4001.25,
"unit": "troy_oz"
}condition ist einer der Werte above, below, change_pct_up oder change_pct_down. price ist der Preis, der den Alarm ausgelöst hat, in base pro unit. id ist für jedes Ereignis eindeutig, sodass Sie damit doppelte Zustellungen erkennen und ignorieren können.
Signatur prüfen
Prüfen Sie immer, ob eine Anfrage wirklich von MetalAPI stammt, bevor Sie darauf reagieren. Der Header X-MetalAPI-Signature hat die Form t=<unix timestamp>,v1=<signature>. Die Signatur ist der hex-kodierte HMAC-SHA256 der Zeichenkette <timestamp>.<raw request body>, berechnet mit Ihrem Signatur-Secret als Schlüssel.
- Berechnen Sie den HMAC über den unveränderten Body, noch vor jedem JSON-Parsing.
- Vergleichen Sie Signaturen in konstanter Zeit.
- Lehnen Sie Zeitstempel ab, die älter als fünf Minuten sind, um wiederholt eingespielte Anfragen (Replay-Angriffe) abzuwehren.
In Node.js mit Express:
import crypto from "node:crypto";
import express from "express";
const app = express();
const SECRET = process.env.METALAPI_WEBHOOK_SECRET;
app.post("/webhooks/metalapi", express.raw({ type: "application/json" }), (req, res) => {
const header = req.get("X-MetalAPI-Signature") ?? "";
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const body = req.body.toString("utf8");
const expected = crypto.createHmac("sha256", SECRET).update(`${parts.t}.${body}`).digest("hex");
const valid =
typeof parts.v1 === "string" &&
parts.v1.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
if (!valid || !fresh) return res.status(400).send("invalid signature");
const event = JSON.parse(body);
console.log(event.alert.symbol, event.alert.condition, event.alert.threshold, event.price);
res.sendStatus(200);
});Prüfung in PHP
Dieselbe Prüfung in reinem PHP:
<?php
$secret = getenv('METALAPI_WEBHOOK_SECRET');
$payload = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_METALAPI_SIGNATURE'] ?? '';
parse_str(str_replace(',', '&', $header), $parts);
$timestamp = (int) ($parts['t'] ?? 0);
$expected = hash_hmac('sha256', $timestamp . '.' . $payload, $secret);
if (!hash_equals($expected, $parts['v1'] ?? '') || abs(time() - $timestamp) > 300) {
http_response_code(400);
exit('invalid signature');
}
$event = json_decode($payload, true);
// Hier $event['alert'] und $event['price'] verarbeiten.
http_response_code(200);Antworten und Wiederholungen
Antworten Sie innerhalb von 8 Sekunden mit einem beliebigen 2xx-Status. Erledigen Sie aufwendige Arbeit erst nach der Antwort, zum Beispiel in einer Queue, denn Timeouts und Antworten außerhalb von 2xx gelten als fehlgeschlagene Zustellungen.
Fehlgeschlagene Zustellungen werden mit wachsenden Abständen wiederholt, insgesamt bis zu drei Versuche innerhalb der ersten Stunde nach Auslösen des Alarms. Eine Wiederholung kann auch nach einer Zustellung eintreffen, die bei uns in einen Timeout lief, bei Ihnen aber erfolgreich war. Speichern Sie daher die id des Ereignisses und machen Sie Ihren Handler idempotent.
Verwandte Anleitungen
Bereit zum Loslegen?
Erstellen Sie ein kostenloses Konto, um Ihren API-Schlüssel zu erhalten, oder entdecken Sie alle Endpunkte in der API-Referenz.