Referência da API

Callbacks

Callbacks assinados de conclusão.

Um callback avisa o seu servidor quando uma execução termina, para que você não precise consultar o status nem manter um stream de eventos aberto. O Ephemeral envia uma requisição POST assinada com o objeto de execução depois que a execução chega a um status final.

Solicitar um callback

Adicione callback à requisição da execução.

callback.urlstringobrigatório
Seu endpoint. Deve usar HTTPS e resolver para um endereço público. Os redirecionamentos não são seguidos.
callback.secretstringobrigatório
De 24 a 1.024 caracteres, usado para assinar cada entrega. Gere um valor aleatório e guarde-o no seu servidor.
JSON
{
  "workflow": "investigate-payment",
  "input": { "payment_id": "pay_123" },
  "max_cost_micros": 500000,
  "callback": {
    "url": "https://example.com/hooks/ephemeral",
    "secret": "3f9a6c1e8b2d47f0a5c3e9d1b7f2a6c4"
  }
}

O segredo nunca é retornado por nenhuma leitura, incluindo a definição da execução. Os callbacks não fazem parte dos fluxos de trabalho salvos; defina um em cada execução que precisar.

O que você recebe

O corpo é o objeto de execução como está no momento da entrega, enviado como JSON com estes cabeçalhos:

CabeçalhoValor
X-Ephemeral-RunO ID da execução.
X-Ephemeral-TimestampHora Unix, em segundos, em que esta tentativa foi assinada.
X-Ephemeral-Signaturesha256= seguido do HMAC-SHA256 em hexadecimal do carimbo de data e hora, um ponto e o corpo bruto, com o seu segredo como chave.
Content-Typeapplication/json
Conteúdo assinado
<X-Ephemeral-Timestamp>.<raw request body>

Verificar a assinatura

Calcule o HMAC sobre os bytes brutos do corpo antes de interpretá-lo e compare em tempo constante.

Node.js com 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);
  // Registre run.id primeiro e ignore-o se já o tiver processado.
  res.sendStatus(204);
});

Cada tentativa é assinada com a hora atual, então rejeitar carimbos de data e hora antigos limita a repetição de requisições sem rejeitar novas tentativas legítimas.

Entrega e novas tentativas

Qualquer resposta 2xx conta como entregue. Qualquer outra, incluindo um timeout ou um redirecionamento, é tentada de novo: primeiro após 10 segundos e depois com o intervalo dobrando a cada vez, até cerca de 43 minutos entre as tentativas. As entregas pendentes são armazenadas de forma durável, então uma reinicialização do mecanismo não as perde.

Elimine duplicatas pelo ID da execução
Seu endpoint pode receber a mesma execução mais de uma vez, por exemplo quando processou uma entrega mas a resposta se perdeu. Use X-Ephemeral-Run para tornar o tratamento idempotente.
Um callback pode chegar antes de o faturamento ser liquidado. Se billing_pending for true no corpo, leia a execução de novo mais tarde com GET /v1/runs/{id} para obter o custo final.
© 2026 EphemeralProduzido por erni.works
esc

Nada corresponde a “”.