---
title: "Functions | WebhookRelay"
meta:
  "og:description": "Use functions to transform webhooks, modify payloads, filter requests, integrate systems, and more."
  "og:title": Functions
  description: "Use functions to transform webhooks, modify payloads, filter requests, integrate systems, and more."
---

![Stripes](https://webhookrelay.com/docs/webhooks/functions/images/stripes.svg)

Documentation

**Fundamentals**

# **Functions**

Use functions to transform webhooks, modify payloads, filter requests, integrate systems, and more.

Functions let you run custom code on every webhook that passes through Webhook Relay. Use them to transform payloads, modify headers, filter unwanted requests, make HTTP calls to external APIs, and integrate different systems together.

Functions can be written in **JavaScript** or **Lua**. Both languages have access to the same request object (`r`) and built-in modules for HTTP requests, JSON, cryptography, and more.

## [What can you do with functions?](#what-can-you-do-with-functions)

- **Transform payloads** — reshape webhook data from one format to another, for example converting a GitHub push event into a Slack message.
- **Filter requests** — inspect incoming webhooks and reject ones that don't match your criteria.
- **Modify headers and method** — add authentication headers, change the HTTP method, or set a custom path before forwarding.
- **Make HTTP requests** — call external APIs to enrich data, fetch tokens, or send notifications to multiple services.
- **Validate webhooks** — verify HMAC signatures, check shared secrets, and ensure webhook authenticity.
- **Customize responses** — return custom status codes and response bodies to the webhook sender.

## [Quick example: transform a payload](#quick-example-transform-a-payload)

This function takes an incoming JSON webhook and reshapes it into a Slack message format:

```
const payload = JSON.parse(r.body)

const slackMessage = {
    text: \`New event from ${payload.source}: ${payload.message}\`
}

r.setBody(JSON.stringify(slackMessage))
r.setHeader("Content-Type", "application/json")
```

```
local json = require("json")

local payload, err = json.decode(r.RequestBody)
if err then error(err) end

local slack_message = {
    text = "New event from " .. payload.source .. ": " .. payload.message
}

local encoded, err = json.encode(slack_message)
if err then error(err) end

r:SetRequestBody(encoded)
r:SetRequestHeader("Content-Type", "application/json")
```

## [Quick example: filter requests](#quick-example-filter-requests)

This function only forwards webhooks that have an `action` field set to `"completed"`:

```
const payload = JSON.parse(r.body)

if (payload.action !== "completed") {
    r.stopForwarding()
    return
}
```

```
local json = require("json")

local payload, err = json.decode(r.RequestBody)
if err then error(err) end

if payload.action ~= "completed" then
    r:StopForwarding()
    return
end
```

## [Quick example: call an external API](#quick-example-call-an-external-api)

Functions can make HTTP requests to enrich webhook data or notify other services:

```
const payload = JSON.parse(r.body)

// look up additional data from an external API
const resp = http.request("GET", "https://api.example.com/users/" + payload.user_id, {
    headers: {
        Authorization: "Bearer " + cfg.get("API_TOKEN")
    }
})

const user = JSON.parse(resp.body)

// enrich the original payload with user data
payload.user_name = user.name
payload.user_email = user.email

r.setBody(JSON.stringify(payload))
```

```
local json = require("json")
local http = require("http")

local payload, err = json.decode(r.RequestBody)
if err then error(err) end

-- look up additional data from an external API
local resp, err = http.request("GET", "https://api.example.com/users/" .. payload.user_id, {
    headers = {
        Authorization = "Bearer " .. cfg:GetValue("API_TOKEN")
    }
})
if err then error(err) end

local user, err = json.decode(resp.body)
if err then error(err) end

-- enrich the original payload with user data
payload.user_name = user.name
payload.user_email = user.email

local encoded, err = json.encode(payload)
if err then error(err) end

r:SetRequestBody(encoded)
```

## [Next steps](#next-steps)

Explore the guides in this section for detailed examples:

- [JSON encoding](https://webhookrelay.com/docs/webhooks/functions/docs/webhooks/functions/manipulating-json) — parse and construct JSON payloads.
- [Make HTTP requests](https://webhookrelay.com/docs/webhooks/functions/docs/webhooks/functions/make-http-request) — call external APIs from your functions.
- [Read, write request data](https://webhookrelay.com/docs/webhooks/functions/docs/webhooks/functions/modify-request) — access and modify headers, body, method, and query.
- [Base64, encryption](https://webhookrelay.com/docs/webhooks/functions/docs/webhooks/functions/crypto-functions) — hash, sign, and encode data.
- [Working with time](https://webhookrelay.com/docs/webhooks/functions/docs/webhooks/functions/working-with-time) — parse and format timestamps.
- [Send emails](https://webhookrelay.com/docs/webhooks/functions/docs/webhooks/functions/send-emails) — send email notifications from functions.

Did this page help you?