> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://contentful.com/developers/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://contentful.com/developers/docs/_mcp/server.

# Working with Functions

> Learn how to create, update, delete, view, and manage Contentful Functions.

> **Info**
>
> **IMPORTANT**: Functions are only available for Premium plans and Partners.

This guide explains how to work with Contentful Functions, which are serverless workloads that run on Contentful's infrastructure to provide enhanced flexibility and customization. For a general overview of functions and use cases, read the [functions overview](/extensibility/app-framework/functions). This guide is aimed at developers looking to build using Contentful Functions, and goes into more detail on the full lifecycle of working with functions.

## Prerequisites

* Functions are a feature associated with apps, and this guide assumes a basic level of understanding of Contentful's [App Framework](/extensibility/app-framework).
* Install the following Contentful CLI tools to work with functions: [Create Contentful App](/extensibility/app-framework/create-contentful-app) and [App Scripts](https://github.com/contentful/create-contentful-app/blob/main/packages/contentful--app-scripts/README.md)
* Functions are only available for Premium plans and Partners.

## Anatomy of a function

There are a few required elements in order to create a function within an app project:

* [App manifest](#app-manifest): json configuration
* [Function handler](#function-handler): your function code
* [Build script](#build-script): builds an App Framework bundle from your config and code

### App manifest

The app manifest is a json file that contains configuration information for the function. This file must always be named `contentful-app-manifest.json`. When generating function code using a template or example, this file is always automatically generated at the project root.

```json
{
  "functions": [
    {
      "id": "exampleFunction",
      "name": "Example Function",
      "description": "This is an example Contentful Function",
      "path": "functions/exampleFunction.js",
      "entryFile": "functions/exampleFunction.ts",
      "allowNetworks": [],
      "accepts": ["appevent.filter"]
    }
  ]
}
```

* `id`: The *id* of the function.
* `name`: A readable name for the function.
* `description`: A brief description of the function.
* `path`: This is the path to the transpiled source file of the function in your bundle. Exposing a `handler` method.
* `entryFile`: Path pointing to the source file of the function. Exposing a `handler` method.
* `allowNetworks`: A list of endpoints the function should be allowed to connect to.
* `accepts`: A list of events the function is able to process. [View values in `node-apps-toolkit`](https://github.com/contentful/node-apps-toolkit/blob/595cce7073e935332dee5aab65256f23249f53d9/src/requests/typings/function.ts#L15)

**Valid `accepts` Values**

| Function type(s)                                                                                                                                                                                                    | Valid `accepts` values                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| [Custom external references](/extensibility/app-framework/functions#use-case-custom-external-references) and [Native external references](/extensibility/app-framework/native-external-references-example-tutorial) | `graphql.field.mapping`  `graphql.resourcetype.mapping`  `graphql.query`  `resources.search`  `resources.lookup` |
| [App Event functions](/extensibility/app-framework/functions#use-case-app-events)                                                                                                                                   | `appevent.filter`  `appevent.handler`  `appevent.transformation`                                                 |
| [App Action functions](/extensibility/app-framework/functions#use-case-app-actions)                                                                                                                                 | `appaction.call`                                                                                                 |

**Valid `allowNetworks` Values**

1. **Wildcard Domains**:

   * `*.example.com`
   * `*.sub.example.com`

2. **Standard Domains**:

   * `example.com`
   * `sub.example.com`
   * `sub.sub.example.com`

3. **IPv4 Addresses**:

   * `192.168.0.1`
   * `10.0.0.1`
   * `255.255.255.255`

4. **IPv6 Addresses**:

   * `[2001:0db8:85a3:0000:0000:8a2e:0370:7334]`
   * `2001:0db8:85a3:0000:0000:8a2e:0370:7334`

5. **Optional Port Numbers**:
   * `example.com:8080`
   * `192.168.0.1:3000`
   * `[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:443`

### Function handler

When generating function code using a template or example, a `functions` directory is created at the project root. This directory should contain a file that matches what is listed in the app manifest `entryFile` (e.g. `functions/exampleFunction.ts`). This file is the primary entry point of the function, and contains a `handler` method:

```typescript
import {
  FunctionEventHandler,
  FunctionTypeEnum,
} from '@contentful/node-apps-toolkit';

export const handler: FunctionEventHandler<FunctionTypeEnum.AppEventFilter> = (
  event,
  context
) => {
  const { body } = event;

  // TODO: Implement your custom filtering logic here
  const shouldAllowEvent = true; // Replace with your actual condition

  return { result: shouldAllowEvent };
};
```

This file imports the [`@contentful/node-apps-toolkit` package](https://github.com/contentful/node-apps-toolkit), which contains types for building your function handler. This is helpful for knowing the shape of the event and context available within the function, and also for knowing the return types for each function type. The handler defines which type of events are accepted. If multiple function types are accepted, all of those types should be defined, and the main handler can then call individual methods for each type. See this [`kitchen-sink` template](https://github.com/contentful/apps/blob/c84d544998d6a22c8d6dfe9a2a5d12a823611128/function-examples/kitchen-sink/typescript/kitchen-sink-template.ts#L135-L153) for an example.

### Build script

The final required element is a build script that builds the source code for a Contentful function into an App framework compatible bundle. When generating function code using a template or example, a build script is automatically added to the project's `package.json`. This build script calls the `build-functions` command from the [App Scripts CLI tool](https://github.com/contentful/create-contentful-app/blob/main/packages/contentful--app-scripts/README.md#build-contentful-function-source).

The app must be built and uploaded to the `AppDefinition` in order for functions to be created, managed, utilized, and tested end to end. See more info [here](#step-3-build-and-upload-your-app) about building and uploading functions.

## Create functions

### Step 1: Generate a project with a function

Functions are enabled through the App Framework, so the first step in creating a function is to generate a project containing the code for your Contentful app. App code can be generated from scratch with a template function or a function can be added to existing app code.

#### Create new app code with functions

App templates with functions are provided via [Create Contentful App](/extensibility/app-framework/create-contentful-app). In the template files, comments provide explanations and `TODO` sections to get your function operational. These templates also contain detailed instructions that outline each step of the process needed to create and use a function within your app, including examples and links to documentation.

Review the code generated for these function templates [here](https://github.com/contentful/apps/tree/master/function-examples). For more information about the function templates and examples for different use cases, see the [functions overview](/extensibility/app-framework/functions).

To quickly scaffold a new app project with one of these function templates, run the following command:

```bash
npx create-contentful-app@latest <app-name> --function <function-template>
```

Replace `<app-name>` with your desired app name, and replace `<function-template>` with one of the following:

* [`appaction-call`](https://github.com/contentful/apps/blob/master/function-examples/appaction-call/typescript/INSTRUCTIONS.md)
* [`appevent-filter`](https://github.com/contentful/apps/blob/master/function-examples/appevent-filter/typescript/INSTRUCTIONS.md)
* [`appevent-handler`](https://github.com/contentful/apps/blob/master/function-examples/appevent-handler/typescript/INSTRUCTIONS.md)
* [`appevent-transformation`](https://github.com/contentful/apps/blob/master/function-examples/appevent-transformation/typescript/INSTRUCTIONS.md)
* [`external-references`](https://github.com/contentful/apps/blob/master/function-examples/external-references/typescript/INSTRUCTIONS.md)
* [`kitchen-sink`](https://github.com/contentful/apps/blob/master/function-examples/kitchen-sink/typescript/INSTRUCTIONS.md) (contains all App Function types)

By default, `create-contentful-app` creates a Contentful app using [TypeScript](https://www.typescriptlang.org/). If you prefer to build your app using vanilla JavaScript, add the `-js` option `npx create-contentful-app@latest <app-name> --function <function-template> -js`.

Create Contentful App can also be used to generate example apps showcasing full functionality of various function use cases. Create your project using one of these examples by running:

```bash
npx create-contentful-app@latest <app-name> --example <function-example>
```

Replace `<app-name>` with your desired app name, and replace `<function-example>` with one of the following:

* [`autotagger`](https://github.com/contentful/apps/tree/master/examples/autotagger)
* [`function-appaction`](https://github.com/contentful/apps/blob/master/examples/function-appaction/INSTRUCTIONS.md)
* [`function-appevent-filter`](https://github.com/contentful/apps/blob/master/examples/function-appevent-filter/typescript/INSTRUCTIONS.md)
* [`function-appevent-handler`](https://github.com/contentful/apps/blob/master/examples/function-appevent-handler/INSTRUCTIONS.md)
* [`function-appevent-transformation`](https://github.com/contentful/apps/blob/master/examples/function-appevent-transformation/INSTRUCTIONS.md)
* [`function-comment-bot`](https://github.com/contentful/apps/blob/master/examples/function-comment-bot/INSTRUCTIONS.md)
* [`function-mock-shop`](https://github.com/contentful/apps/tree/master/examples/function-mock-shop)
* [`function-potterdb`](https://github.com/contentful/apps/tree/master/examples/function-potterdb)
* [`function-potterdb-rest-api`](https://github.com/contentful/apps/tree/master/examples/function-potterdb-rest-api)

Learn more about function use cases and these templates and examples in the [functions overview](/extensibility/app-framework/functions).

#### Add functions to existing app code

To add functions to existing app code, run the following command from the [`app-scripts` CLI tool](https://github.com/contentful/create-contentful-app/tree/main/packages/contentful--app-scripts) inside your app project. This will add functions to your app project based on the template code [here](https://github.com/contentful/apps/tree/master/function-examples).

**Interactive Mode**

Run the CLI in interactive mode, which will prompt you for the necessary options:

```bash
npx --no-install @contentful/app-scripts generate-function
```

The interactive process will guide you through:

1. Selecting a function name
2. Choosing from available function templates
3. Selecting your preferred language (JavaScript or TypeScript)

**Non-Interactive Mode**

For automated workflows or CI/CD pipelines, use the `--ci` flag with required parameters:

```bash
npx --no-install @contentful/app-scripts generate-function --ci --name <name> --example <function-template> --language typescript
```

Replace `<name>` with your desired function name (any value except `example`), and replace `<function-template>` with one of the following:

* [`appaction-call`](https://github.com/contentful/apps/blob/master/function-examples/appaction-call/typescript/INSTRUCTIONS.md)
* [`appevent-filter`](https://github.com/contentful/apps/blob/master/function-examples/appevent-filter/typescript/INSTRUCTIONS.md)
* [`appevent-handler`](https://github.com/contentful/apps/blob/master/function-examples/appevent-handler/typescript/INSTRUCTIONS.md)
* [`appevent-transformation`](https://github.com/contentful/apps/blob/master/function-examples/appevent-transformation/typescript/INSTRUCTIONS.md)
* [`external-references`](https://github.com/contentful/apps/blob/master/function-examples/external-references/typescript/INSTRUCTIONS.md)
* [`kitchen-sink`](https://github.com/contentful/apps/blob/master/function-examples/kitchen-sink/typescript/INSTRUCTIONS.md) (contains all App Function types)

Available Parameters:

* `--name <name>`: Your function name (any value except `example`)
* `--example <example>`: Template to use (e.g., `appevent-transformation`, `external-references`)
* `--language <language>`: `javascript` or `typescript` (defaults to `typescript`)
* `--ci`: Enables non-interactive mode

When executed, this command:

1. Creates a `functions` directory if one doesn't exist
2. Adds the selected function template with your specified name
3. Creates or updates the `contentful-app-manifest.json` file
4. Updates your `package.json` to include function build commands

### Step 2: Create an app definition

An [app definition](/extensibility/app-framework/app-definition) is an entity that represents an app in Contentful and stores general information about it. Functions are associated with an app definition, which is why one is needed to create a function.

You can create an app definition:

* using the [Create Contentful App](/extensibility/app-framework/create-contentful-app) CLI tool by running the `npx @contentful/app-scripts create-app-definition` command,
* navigating to the [Apps tab](https://app.contentful.com/deeplink?link=app-definition-list) of the Organization settings & subscriptions in the web app, and clicking **Create app** , or
* through the [CMA](/references/content-management-api/overview).

### Step 3: Build and upload your app

Build and upload scripts are provided when scaffolding an app using [Create Contentful App](/extensibility/app-framework/create-contentful-app) or when adding functions to an existing app using the `generate-function` command from [App Scripts](https://github.com/contentful/create-contentful-app/blob/main/packages/contentful--app-scripts/README.md).

#### Build your app bundle

This build script calls the [`build-functions` command](https://github.com/contentful/create-contentful-app/tree/main/packages/contentful--app-scripts#build-contentful-function-source) from App Scripts. This command builds the source code for a Contentful function into a bundle compatible with the App Framework.

```bash
npm run build
```

#### Upload your app bundle

Next, run the following command to upload the build folder, which creates an [`AppBundle`](/extensibility/app-framework/app-bundle). The upload script calls the [`upload` command](https://github.com/contentful/create-contentful-app/tree/main/packages/contentful--app-scripts#upload-a-bundle-to-an-app-definition) from App Scripts. The function is created during this upload process.

```bash
npm run upload
```

> **Info**
>
> **IMPORTANT**: Apps that use functions must be uploaded via the CLI. Uploading a bundle via the app management view in the Contentful web app will not create functions.

### Step 4: Install your app

After the app bundle has been uploaded and the functions have been created, [install the app](/extensibility/app-framework/app-installation) into a space where you would like the functions to run. An app can be installed via the [Contentful web app](https://app.contentful.com/deeplink?link=apps), via the [app-scripts](https://github.com/contentful/create-contentful-app/tree/main/packages/contentful--app-scripts#install-the-appdefinition-into-a-specific-space--environment) CLI tool, or via the [CMA](/references/content-management-api/overview).

## Enable and trigger functions

At this point, your function has been created and is almost ready to be used within Contentful. You have just a few more steps left to enable it depending on your function type. Learn more about function types and use cases in the [functions overview](/extensibility/app-framework/functions).

### Custom external references

Follow these steps to link a Custom external references function to a content type and use it in a GraphQL request:

1. Create a [content type](/references/content-management-api/overview).
   > **Info**
   >
   > **IMPORTANT:** To use the functions, make sure you select your app in the **Appearance** section of the Content Type field settings and enable the **Resolve content on delivery** checkbox.

![Screenshot of functions](https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/contentful.docs.buildwithfern.com/5bc4926dc5eee4a4feb8efdefa54b6718b70c58edee7081cdad807dbf735cc09/docs/assets/images/functions.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260929%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260929T234758Z&X-Amz-Expires=604800&X-Amz-Signature=82aeac3384a7fd2eef6454e2ccff2ea21712eadf4cb7f5219bb65121a9f182a7&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject)

2. Create an [entry](/references/content-management-api/overview).
3. Make a GraphQL request. You can use the [GraphiQL app](https://www.contentful.com/marketplace/app/graphiql/) to try this easily.

```
query {
  topicProduct(id: "ENTRY_ID") {
    myField
    myField_data {
      foo
    }
  }
}
```

Within the `topicProduct` content type, there is a field named `myField` which represents the content within `topicProduct`.
The query also contains a reference to `myField_data`. The `_data` suffix in the field name implies that it is intended for use with functions. Functions retrieve content, and the `_data` suffix is a convention to signify that the field is designed to access content fetched through these functions. The `foo` type comes from the schema used in the function implementation.

Here is an example response with resolved data from the function:

```json
{
  "data": {
    "topicProduct": {
      "myField": "this is a test",
      "myField_data": {
        "foo": "hello world"
      }
    }
  }
}
```

### App Event functions

Follow these steps to link an App Event function to an App Event Subscription:

1. Navigate to the [**Events** tab of your app definition in the organization settings](https://app.contentful.com/deeplink?link=app-definition\&tab=events), and ensure the **Enable events** option is active for your app.

![App Event functions setup](https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/contentful.docs.buildwithfern.com/e1b3a6c9d917e153ec053d25b738c3d4c8d2ec8adeaf1c034612334a078d762c/docs/assets/images/app-event-functions-setup.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260929%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260929T234758Z&X-Amz-Expires=604800&X-Amz-Signature=12bcfcd5e0af0f1287e6b3454bebc76839fb2837aa5185f3dac4582a99469cf9&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject)

2. Select the topics you would like to trigger your function.

3. Use the dropdown menus on this page to select the functions you would like to invoke. You may select one filter function, one transformation function, and one handler function.

4. Click **Save** to preserve your selections.
   > **Info**
   >
   > You can also perform these actions via the Content Management API (CMA) by issuing a request to [update or subscribe to events](/references/content-management-api/overview).

5. Success! Your app is now subscribed to the events you have chosen. You can test that this works as expected by triggering a targeted action within Contentful to invoke your function. For example, if you subscribed to the `Entry.create` topic, create an [entry](/references/content-management-api/overview) to invoke your function.

### App Action functions

Once you've created your App Action function, follow these steps to link it to an App Action:

1. Navigate to the [**Actions** tab of your app definition in the organization settings](https://app.contentful.com/deeplink?link=app-definition\&tab=actions).
2. Click **Add action** if you want to add a new action, or click on the three dots actions menu next to an existing action, and select **Edit** to modify an existing action.

![App Action functions setup](https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/contentful.docs.buildwithfern.com/963406dde8c5ea8f963a303bdba14f04e51f2ab4e0a7f73a604a8c40ed5db35e/docs/assets/images/app-action-functions-setup.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260929%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260929T234758Z&X-Amz-Expires=604800&X-Amz-Signature=8660722e04d1421b048f748a8f14447cb0051b5d14d9e376c1be473b06eb6e29&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject)

3. Select the `function-invocation` action type.

4. Use the dropdown menu to select the function you want to invoke.

5. Click **Save action** to preserve your selections.
   > **Info**
   >
   > You can also perform these actions via the Content Management API (CMA) by issuing a request to [create an action](/references/content-management-api/overview) or [update an existing action](/references/content-management-api/overview).

6. Success! Your function is now linked to your App Action. You can test that this works as expected by using the CMA to [trigger an App Action Call](/references/content-management-api/overview). To read more about this process, see the [App Actions documentation](/extensibility/app-framework/app-actions).

If your app code was generated using the `appaction-call` or `kitchen-sink` function templates ([more info here](#create-new-app-code-with-functions)), these templates include an `upsert-actions` command, which allows for programmatically adding App Actions to an `AppDefinition` from the command line. The `actions` array in the `contentful-app-manifest.json` file should be updated manually before running `upsert-actions`. Further instructions can be found [here](https://github.com/contentful/apps/blob/master/function-examples/appaction-call/typescript/INSTRUCTIONS.md#6-create-an-app-action).

## View function executions and logs

To get a better understanding of how your function is performing, you can inspect the executions and log output.

To inspect the executions and log output:

1. Navigate to the **App configuration** page in the Contentful web app.
2. Select the **Functions** tab.
3. Open the menu of the function you want to inspect and select **View logs**.

![Function logs menu item](https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/contentful.docs.buildwithfern.com/de1ef27e77cdc3bb8dc241b109137b82c2fd750e936fa2332ba340f1b430b528/docs/assets/images/function-logs-menu-option.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260929%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260929T234758Z&X-Amz-Expires=604800&X-Amz-Signature=9f8f4bcf3b1978e314653b13eeb5ae5675e62f04ce3a959c46fe390f22a4c9cc&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject)

4. On the **Function logs** page, select the space and environment the app is installed in. A list of all the function executions in the selected space and environment is displayed.

> **Info**
>
> Function logs can be filtered by a relative or absolute timeframe.

5. Click on an execution to see the log output of the function.

![Function executions table](https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/contentful.docs.buildwithfern.com/158b9ddfdcbf32b36a0ce75e937245dba482a9e255effc9cbabd0459400d5a9b/docs/assets/images/function-invocations.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260929%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260929T234758Z&X-Amz-Expires=604800&X-Amz-Signature=4e9fac6bcd29c73c4e24217b392fc39c6f62f94563a5fcc99307e605b0ffd45f&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject)

6. At the top of the drawer, expand the **Event** section to see the event that triggered the function. Below that, the log output of the function is displayed.

> **Info**
>
> The log severity is based on the log method used in the function. `console.log` will show severity `info`, `console.warn` will show severity `warn`, and `console.error` will show severity `error`.

![Function execution logs](https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/contentful.docs.buildwithfern.com/52454a9fa61f023ffee21986b51f306deea155c1836f095c54c8b38f95c98dc9/docs/assets/images/function-logs.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260929%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260929T234758Z&X-Amz-Expires=604800&X-Amz-Signature=89d0321c67c746146a0a519f141871ce03f2ed9fec0573fad5ecfa00e80284e4&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject)

## Update functions

To modify an existing function, follow a process similar to creating a new one. First, make any necessary changes (e.g., updating your function code, editing the app manifest, adding new functions, etc.). Then, follow [these steps](#step-3-build-and-upload-your-app) to build and upload your app.

## Delete functions

To remove a function from an app, first, remove the function from the app manifest and delete the function code from your project. Then, follow [these steps](#step-3-build-and-upload-your-app) to build and upload your app.

> **Info**
>
> **IMPORTANT**: This is a destructive operation and no history or backup of your function is stored. Before deleting, ensure that your function is not in use.