API-Referenz

Callbacks

Signierte Abschluss-Callbacks.

Ein Callback teilt Ihrem Server mit, wenn eine Ausführung beendet ist, sodass Sie weder abfragen noch einen Ereignis-Stream offen halten müssen. Ephemeral sendet eine signierte POST-Anfrage mit dem Ausführungsobjekt, nachdem die Ausführung einen finalen Status erreicht hat.

Einen Callback anfordern

Fügen Sie callback zur Ausführungsanfrage hinzu.

callback.urlstringerforderlich
Ihr Endpunkt. Er muss HTTPS verwenden und auf eine öffentliche Adresse auflösen. Weiterleitungen werden nicht verfolgt.
callback.secretstringerforderlich
24 bis 1.024 Zeichen, zum Signieren jeder Zustellung. Erzeugen Sie einen Zufallswert und speichern Sie ihn auf Ihrem Server.
JSON
{
  "workflow": "investigate-payment",
  "input": { "payment_id": "pay_123" },
  "max_cost_micros": 500000,
  "callback": {
    "url": "https://example.com/hooks/ephemeral",
    "secret": "3f9a6c1e8b2d47f0a5c3e9d1b7f2a6c4"
  }
}

Das Secret wird von keinem Lesezugriff zurückgegeben, auch nicht von der Ausführungsdefinition. Callbacks sind nicht Teil gespeicherter Workflows; legen Sie einen bei jeder Ausführung fest, die ihn braucht.

Was Sie erhalten

Der Body ist das Ausführungsobjekt im Zustand zum Zeitpunkt der Zustellung, als JSON gesendet mit diesen Headern:

HeaderWert
X-Ephemeral-RunDie Ausführungs-ID.
X-Ephemeral-TimestampUnixzeit in Sekunden, zu der dieser Versuch signiert wurde.
X-Ephemeral-Signaturesha256= gefolgt vom hexadezimalen HMAC-SHA256 aus Zeitstempel, einem Punkt und dem rohen Body, mit Ihrem Secret als Schlüssel.
Content-Typeapplication/json
Signierter Inhalt
<X-Ephemeral-Timestamp>.<raw request body>

Die Signatur prüfen

Berechnen Sie den HMAC über die Rohbytes des Bodys, bevor Sie ihn parsen, und vergleichen Sie in konstanter Zeit.

Node.js mit Express
import crypto from "node:crypto";
import express from "express";

const app = express();

app.post("/hooks/ephemeral", express.raw({ type: "application/json" }), (req, res) => {
  const timestamp = req.get("X-Ephemeral-Timestamp") ?? "";
  const signature = req.get("X-Ephemeral-Signature") ?? "";
  const expected =
    "sha256=" +
    crypto
      .createHmac("sha256", process.env.EPHEMERAL_CALLBACK_SECRET)
      .update(timestamp + ".")
      .update(req.body)
      .digest("hex");

  const valid =
    signature.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
  const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) < 300;
  if (!valid || !fresh) return res.sendStatus(401);

  const run = JSON.parse(req.body);
  // Zuerst run.id festhalten und überspringen, wenn er schon verarbeitet wurde.
  res.sendStatus(204);
});

Jeder Versuch wird mit der aktuellen Zeit signiert. Das Ablehnen alter Zeitstempel begrenzt daher Replays, ohne echte Wiederholungen abzulehnen.

Zustellung und Wiederholungen

Jede 2xx-Antwort gilt als zugestellt. Alles andere, auch ein Timeout oder eine Weiterleitung, wird wiederholt: zuerst nach 10 Sekunden, dann mit jeweils verdoppelter Wartezeit bis zu etwa 43 Minuten zwischen den Versuchen. Ausstehende Zustellungen werden dauerhaft gespeichert, ein Neustart der Engine verliert sie also nicht.

Nach Ausführungs-ID deduplizieren
Ihr Endpunkt kann dieselbe Ausführung mehrmals erhalten, etwa wenn er eine Zustellung verarbeitet hat, die Antwort aber verloren ging. Nutzen Sie X-Ephemeral-Run, um die Verarbeitung idempotent zu machen.
Ein Callback kann eintreffen, bevor die Abrechnung abgeschlossen ist. Ist billing_pending im Body true, lesen Sie die Ausführung später erneut mit GET /v1/runs/{id}, um ihre endgültigen Kosten zu erhalten.
© 2026 EphemeralProduziert von erni.works
esc

Keine Treffer für „“.