Skip to main content

Delivery model

SafeFetch sends your action body to url using the configured method and headers.
  • Any 2xx response marks the action completed.
  • Non-2xx, network errors, and timeouts trigger retries until retries is exhausted.

Headers SafeFetch sends

X-SafeFetch-Signature
string
required
HMAC signature in format sha256=<hex>.
X-SafeFetch-Action-Id
string
required
Action identifier.
X-SafeFetch-Attempt
integer
required
1-based attempt number.
Content-Type
string
required
Always application/json.

HMAC verification

Use your API key as the secret and the exact JSON body as input.
import { createHmac, timingSafeEqual } from 'node:crypto';

function verifySafeFetchSignature(rawBody: string, signatureHeader: string, apiKey: string): boolean {
  const expected = `sha256=${createHmac('sha256', apiKey).update(rawBody).digest('hex')}`;
  const a = Buffer.from(expected);
  const b = Buffer.from(signatureHeader || '');
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);
}

Timeout behavior

Default HTTP request timeout is 30 seconds (DISPATCH_TIMEOUT_MS=30000). Timeout is treated as a failed attempt and retried.

Retry behavior for non-2xx

SafeFetch retries with exponential backoff and caps delay at 1 hour.

Callback URLs

If callback is set on an action, SafeFetch sends a POST notification on terminal outcomes:
  • completed: includes response code/body/duration
  • failed: includes last_error