API リファレンス

コールバック

署名付きの完了コールバック。

コールバックは、実行が終了したことをあなたのサーバーに知らせます。ポーリングしたり、イベントストリームを開いたままにしたりする必要はありません。実行が最終ステータスに達すると、Ephemeral が実行オブジェクトを含む署名付きの POST リクエストを 1 回送信します。

コールバックを要求する

実行リクエストに callback を追加します。

callback.urlstring必須
あなたのエンドポイント。HTTPS を使用し、パブリックなアドレスに解決される必要があります。リダイレクトには従いません。
callback.secretstring必須
24 から 1,024 文字。各配信の署名に使います。ランダムな値を生成し、サーバー上で保管してください。
JSON
{
  "workflow": "investigate-payment",
  "input": { "payment_id": "pay_123" },
  "max_cost_micros": 500000,
  "callback": {
    "url": "https://example.com/hooks/ephemeral",
    "secret": "3f9a6c1e8b2d47f0a5c3e9d1b7f2a6c4"
  }
}

シークレットは、実行の定義を含め、どの読み取りでも返されません。コールバックは保存済みのワークフローには含まれません。必要な実行ごとに設定してください。

受信する内容

ボディは、配信時点の実行オブジェクトで、次のヘッダーを付けた JSON として送信されます。

ヘッダー値
X-Ephemeral-Run実行 ID。
X-Ephemeral-Timestampこの試行に署名した時刻の Unix 時間 (秒)。
X-Ephemeral-Signaturesha256= に続けて、タイムスタンプ、ピリオド、生のボディをシークレットで署名した HMAC-SHA256 の 16 進数。
Content-Typeapplication/json
署名対象の内容
<X-Ephemeral-Timestamp>.<raw request body>

署名を検証する

ボディをパースする前に、生のバイト列に対して HMAC を計算し、定数時間で比較してください。

Express を使う Node.js
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);
  // Record run.id first and skip it if you have already handled it.
  res.sendStatus(204);
});

各試行は、その時点の時刻で署名されます。古いタイムスタンプを拒否すれば、正当な再試行を拒否することなく、リプレイ攻撃を抑えられます。

配信と再試行

2xx のレスポンスは、配信済みとみなされます。それ以外 (タイムアウトやリダイレクトを含む) は再試行されます。最初の再試行は 10 秒後で、その後は間隔が毎回 2 倍になり、最大で約 43 分間隔になります。保留中の配信は永続的に保存されるため、エンジンが再起動しても失われません。

実行 ID で重複を排除してください
同じ実行が、エンドポイントに複数回届くことがあります。たとえば、配信を処理したもののレスポンスが失われた場合です。X-Ephemeral-Run を使って、処理が冪等になるようにしてください。
コールバックは、請求の精算が完了する前に届くことがあります。ボディの billing_pending が true の場合は、後で GET /v1/runs/{id} で実行を読み取り、最終的なコストを確認してください。
© 2026 Ephemeral制作: erni.works
esc

「」に一致する項目はありません。