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.
Supports functions, secrets, retries, replay, and failed-delivery handling.
Hides the Functions tab. Traffic is delivered to the single proxy forwarder without any transform step.
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.
Navigate to the queued bucket forwarder that should transform matching events and select the Functions tab.
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.
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.
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.
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
| Field | Type | Description |
|---|---|---|
method | string | HTTP method of the original request |
path | string | Path of the original request |
query | Record<string, string> | Parsed query string parameters |
headers | Record<string, string> | Request headers |
body | T (generic) | Parsed request body |
sourceIp | string | IP address of the incoming request |
receivedAt | string | ISO 8601 timestamp when Repost received the event |
TransformResult fields
| Field | Type | Description |
|---|---|---|
path | string | Path to use for the outbound request |
headers | Record<string, string> | Headers to send with the outbound request |
body | string | object | Body to send: any JSON-serializable value or a raw string |
discard | true | Return 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.
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.
Stops normal delivery and creates a failed-delivery item that you can inspect and replay. This is the default.
Skips the transform and delivers the original, unmodified request to the forwarder destination.
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.