Functions

Write TypeScript functions that transform webhook request path, headers, and body before a queued forwarder delivers the event to its destination.

A function is a TypeScript transform attached to one queued forwarder. It receives the original webhook request, lets you change the path, headers, or body, and then hands the modified request back to that forwarder for delivery. Functions run per matching path, so you can apply different logic to different providers without creating separate buckets.

Availability

Functions run in the asynchronous delivery path and are available only on queued bucket forwarders. If you are working with a proxy bucket, the Functions tab does not appear.

Queued bucket

Supports functions, secrets, retries, replay, and failed-delivery handling.

Proxy bucket

Hides the Functions tab. Traffic is delivered to the single proxy forwarder without any transform step.

Per forwarder

A function belongs to one forwarder. If two destinations both need the same transform, create the function on each forwarder separately.

Path matching

Each function is tied to a specific path. Repost compares the original incoming webhook path against the function's configured path and runs the function only when there is an exact match.

Exact match required

A function configured for /webhooks/stripe runs when an event arrives at /webhooks/stripe. It does not run for /webhooks/shopify or /webhooks/stripe/events.

No match: deliver normally

When no enabled, saved function matches the incoming path, the forwarder delivers the original request unchanged.

Unique paths per forwarder

One forwarder cannot have two functions configured with the same path. Each path maps to exactly one function on a given forwarder.

Draft, disabled, and never-saved functions do not transform traffic. Save a valid function and confirm it is enabled before routing provider traffic through it.

Create and publish a function

Creating a function stores the configuration shell. Saving from the editor compiles your code and publishes the version that will process live traffic.

1
Open the forwarder's Functions tab

Navigate to the queued bucket forwarder that should transform matching events and select the Functions tab.

2
Create the function shell

Enter a name (up to 100 characters), a path such as /webhooks/stripe (up to 200 characters), and an error policy. The default error policy sends transform failures to failed deliveries.

3
Write your transform in the editor

Export a single transform function with the signature export function transform(req: WebhookRequest): TransformResult. The editor provides type information and process.env autocomplete for your forwarder's secrets.

4
Test with a JSON input

Use the default request shape, paste your own JSON, or load a real event from History using the From History button. Tests run against the forwarder's current secrets. Up to 30 tests per minute are allowed per user.

5
Save the function

Saving formats the source, compiles it, and publishes the new version. If the source has compile errors, those errors appear in the editor and the previously active version continues to handle traffic.

Function signature and types

Your transform receives a WebhookRequest object and must return a TransformResult. Both types are provided by the Repost runtime: you do not need to import them.

WebhookRequest fields
FieldTypeDescription
methodstringHTTP method of the original request
pathstringPath of the original request
queryRecord<string, string>Parsed query string parameters
headersRecord<string, string>Request headers
bodyT (generic)Parsed request body
sourceIpstringIP address of the incoming request
receivedAtstringISO 8601 timestamp when Repost received the event
TransformResult fields
FieldTypeDescription
pathstringPath to use for the outbound request
headersRecord<string, string>Headers to send with the outbound request
bodystring | objectBody to send: any JSON-serializable value or a raw string
discardtrueReturn true to stop delivery for this forwarder without an error
Secrets and helpers

Read forwarder secrets with process.env.KEY. Missing keys resolve to undefined, so always guard required credentials. For signing and verification work, use the built-in repost.crypto.* and repost.jwt.* helpers. External package imports are not supported.

Example transform

The following function filters out Stripe events that are missing the stripe-signature header, injects an internal auth token, and remaps the delivery path.

type StripeEvent = {
  type: string;
  data?: unknown;
};
 
export function transform(
  req: WebhookRequest<StripeEvent>,
): TransformResult {
  if (!req.headers["stripe-signature"]) {
    return {
      discard: true,
      path: req.path,
      headers: req.headers,
      body: req.body,
    };
  }
 
  const token = process.env.INTERNAL_WEBHOOK_TOKEN ?? "";
 
  return {
    path: "/internal/stripe",
    headers: {
      ...req.headers,
      "x-repost-source": "stripe",
      authorization: `Bearer ${token}`,
    },
    body: {
      provider: "stripe",
      receivedAt: req.receivedAt,
      event: req.body,
    },
  };
}

Store the INTERNAL_WEBHOOK_TOKEN value as a forwarder secret so it never appears in your function source code. See the Secrets guide for instructions.

Discarding events

Returning discard: true tells Repost to stop delivery for this forwarder without treating the outcome as an error.

Discard is a successful function result

The function's error policy is not applied when you return discard: true. Repost marks the forward as discarded and skips delivery for that forwarder. Other forwarders on the same bucket are not affected.

Error policies

The error policy controls what Repost does when your function throws an unhandled error, times out, or otherwise cannot execute. Choose the policy that matches how sensitive your destination is to receiving untransformed events.

Send to failed deliveries

Stops normal delivery and creates a failed-delivery item that you can inspect and replay. This is the default.

Forward as-is

Skips the transform and delivers the original, unmodified request to the forwarder destination.

Discard

Marks the forward discarded and does not deliver it to the destination.

Editor features

From History

Load a real recent webhook event as your test input. The dialog lets you filter by 24h, 7d, or 30d windows and supports search.

Generate Types

Generate TypeScript types from the current test input body. If the test input matches the full webhook request shape, the editor uses its body field. Generated types are placed between generated-type markers, or prepended as a new block if markers are absent.

Secrets autocomplete

Keys from the forwarder's Secrets page appear as process.env suggestions in the editor. Add secrets before writing code that depends on them.

Format

Use the Format button in the editor toolbar to auto-format source before saving. Formatting also removes unused imports.

Save shortcut

Press Cmd+S on macOS or Ctrl+S on Windows and Linux to save the current source and metadata without leaving the keyboard.

Function states

Draft

The function is enabled but no compiled version has been saved yet. Matching traffic is delivered normally without transformation.

Active

The function is enabled and a saved, compiled version exists. Matching traffic is transformed before delivery.

Disabled

The function remains configured but does not process any traffic. Re-enable it at any time.

Unsaved or Modified

The editor contains source or metadata that has not yet replaced the active version. Test and save before sending live traffic through the function.

Version numbering

A successful source compile increments the function version number. Metadata-only saves, such as changing the name or error policy, do not create a new executable version. Compile errors leave the previous active version in place.