> ## Documentation Index
> Fetch the complete documentation index at: https://nango.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Functions guide

> Understand Nango Functions, set up your functions project, and choose the right function type.

## Overview

**Functions** are Nango's runtime for custom integration logic.

When you build integrations directly, every provider forces you to solve the same hard problems: OAuth credentials, token refresh, per-customer permissions, retries, rate limits, data freshness, observability, and safe execution. Nango handles that infrastructure, and functions let you write the provider-specific logic that is unique to your product.

You write functions in TypeScript and deploy them to Nango. Your app can call them from any language, framework, backend job, or agent workflow. Each execution runs for a specific integration and connection, so the function has scoped access to the right customer's credentials without exposing those credentials to your app or agent.

## How functions fit

1. Your user authorizes an external API through [Nango Auth](/guides/auth/auth-guide).
2. Your app stores the resulting `connectionId`.
3. You deploy functions for the integration.
4. Nango runs the function on demand, on a schedule, from an external webhook, or after a connection lifecycle event.
5. Your app receives the function result, sync records, or webhooks from Nango.

Functions are the right layer when you need custom API logic, data syncing, webhook processing, AI tools, or per-customer integration behavior.

## Capabilities

* **Scoped external API access** — run API calls with the credentials and scopes of one connection.
* **Any app stack** — trigger functions through HTTP APIs or SDKs from any backend language.
* **Multiple trigger types** — call functions on demand, run them on a schedule, route external webhooks into them, or react to connection lifecycle events.
* **Agent-ready tools** — expose selected functions to agents through the API or Nango's MCP server while keeping provider credentials out of the model loop.
* **Built-in integration infrastructure** — retries, rate-limit handling, logs, OpenTelemetry export, records storage, checkpoints, and per-connection metadata.
* **Local development and CI/CD** — dry run functions against real connections, snapshot test them, and deploy them with your application pipeline.

## Template catalog

Nango's template catalog contains template functions for common provider use cases. Use it to ship faster, inspect implementation patterns, or bootstrap a custom function.

Template functions are normal Nango functions. You can deploy them as-is when they fit your use case, or pull the source into your functions project and customize it.

You can browse template functions in three places:

* The [template catalog](https://www.nango.dev/templates) on the Nango website.
* The integration page in the Nango dashboard.
* The source code in the [Nango integration templates repository](https://github.com/NangoHQ/integration-templates).

Generated integration docs also list template use cases for many providers, with links to the corresponding GitHub source file.

When a template function already matches your use case, enable it for the integration and deploy it without changing the code. Before using it in production, check the function type, required scopes, input and output schema, synced record model, and provider plan requirements.

Use the CLI to clone template code into your local functions project:

```bash theme={null}
nango clone github
nango clone github/actions
nango clone github/actions/list-repos
```

You can clone an entire integration, a function-type folder, or a single function. After cloning, review the source and schemas, import the function from `index.ts` if needed, adjust inputs, outputs, record models, metadata, or provider mapping logic, then run `nango dryrun` and deploy with `nango deploy`.

<Tip>
  Pull template code when you need custom fields, a smaller output shape, customer-specific filtering, different retry behavior, or a provider workflow that is close to a template function but not identical.
</Tip>

Template action functions can also be exposed as agent tools. Enable the action function, discover its schema with the [Get integration functions config API](/reference/backend/http-api/scripts/config), then execute it through [tool calling](/guides/functions/tool-calling), the action trigger API, or Nango's MCP server.

## Function AI Builder

Nango's Function AI Builder is a workflow for building functions with the coding agent, IDE, and model of your choice.

Instead of using a black-box integration generator, you get TypeScript function code that you can review, test, customize, deploy, and maintain in your own repo.

Use both sources of context when asking an agent to build a function:

1. Add Nango's documentation MCP server: `https://nango.dev/docs/mcp`
2. Install the Nango function builder skill:

```bash theme={null}
npx skills add NangoHQ/skills -s building-nango-functions-locally
```

<Note>
  If your coding agent is already running, restart it after installing the skill so it can load the new instructions.
</Note>

The docs MCP and skill give the agent current Nango function APIs, CLI commands, project layout, Zod schema patterns, testing guidance, deployment expectations, and examples for action, sync, webhook, and event functions.

You can start with a short request:

```text theme={null}
Build a Nango action that gets Slack channel information.
```

You will get better output if you include the integration ID, connection ID, desired input and output models, and the provider API reference:

```text theme={null}
Build a Nango action that gets Slack channel information.

Integration ID: slack
Connection ID for dry run: my-slack-connection
Inputs: channel_id
Outputs: id, name, is_private
API reference: https://api.slack.com/methods/conversations.info
```

For syncs, include the record model, frequency, pagination and incremental hints if you already know them, and any customer-specific metadata the function needs:

```text theme={null}
Build a Nango sync that stores Figma projects.

Integration ID: figma
Connection ID for dry run: my-figma-connection
Frequency: every hour
Metadata: team_id
Records: Project with id, name, last_modified
API reference: https://www.figma.com/developers/api#projects-endpoints
```

A good agent workflow generates the function code, imports it from `index.ts`, adds schemas, writes or updates tests, runs `nango dryrun`, iterates on failures, and leaves the function ready for `nango deploy`.

## Guide

<Tip>
  **Using a coding agent?** Set up the [docs MCP](/getting-started/coding-agent-setup#docs-mcp-server) and [skills](/getting-started/coding-agent-setup#skills), then copy this page as prompt.
</Tip>

<Steps>
  <Step id="install-and-initialize" title="Install and initialize">
    Install the Nango CLI globally:

    ```bash theme={null}
    npm install -g nango
    ```

    Initialize your integrations folder at the root of your repo and commit it to source control:

    ```bash theme={null}
    nango init nango-integrations
    ```

    This creates a `nango-integrations/` folder with example configuration. The `.nango` subdirectory must be committed because the CLI uses it to track deployed state.
  </Step>

  <Step id="configure-api-keys" title="Configure API keys">
    Add your API keys to a `.env` file inside `nango-integrations/`. The CLI currently reads these API keys from `NANGO_SECRET_KEY_<ENV_NAME>` variables:

    ```bash theme={null}
    NANGO_SECRET_KEY_PROD='<PROD-API-KEY>'
    NANGO_SECRET_KEY_DEV='<DEV-API-KEY>'
    ```

    Get your API keys from **Environment Settings > API Keys**. The CLI picks up the matching key for whichever environment you deploy to.

    `nango init` creates `nango-integrations/.gitignore` with `.env` ignored. Keep the `.env` file untracked so Nango API keys are not committed.

    <Note>
      Keys are matched by environment name: `NANGO_SECRET_KEY_<ENV_NAME>`. If you rename an environment in the UI, update the variable name in `.env` to match.

      For example, an environment named `staging` needs:

      ```bash theme={null}
      NANGO_SECRET_KEY_STAGING='<STAGING-API-KEY>'
      ```
    </Note>

    <Accordion title="Team setup">
      Give each engineer their own Nango environment. This prevents overwriting each other's deployed functions and lets each person configure webhooks independently, for example by pointing to a local ngrok tunnel.

      Each engineer adds their environment's key to their local `.env`:

      ```bash theme={null}
      NANGO_SECRET_KEY_<YOUR_ENV_NAME>='<your-personal-api-key>'
      ```

      Use a shared `dev` or `staging` environment as a stable baseline written to only by CI. See the [CI/CD guide](/guides/functions/ci-cd).
    </Accordion>

    <Accordion title="For agents">
      Run `nango init nango-integrations` to scaffold the folder. Ask the user for their API key from **Environment Settings > API Keys** and write it to the matching `NANGO_SECRET_KEY_<ENV_NAME>` variable in `nango-integrations/.env`. Confirm that `nango-integrations/.gitignore` ignores `.env`.

      For additional context while building, add Nango's documentation MCP server (`https://nango.dev/docs/mcp`) and install the Nango function builder skill:

      ```bash theme={null}
      npx skills add NangoHQ/skills -s building-nango-functions-locally
      ```
    </Accordion>
  </Step>

  <Step id="understand-folder-layout" title="Understand the folder layout">
    Each integration gets its own folder, with subfolders by function type. `index.ts` imports every function file you want deployed:

    ```
    nango-integrations/
    ├── .nango/                        # auto-managed state, commit it
    ├── .env                           # API keys per environment
    ├── .gitignore                     # keeps .env and dist untracked
    ├── index.ts                       # imports every function file
    ├── package.json
    └── <integration-id>/              # one folder per integration, e.g. github
        ├── syncs/
        │   └── github-issues.ts
        ├── actions/
        │   └── github-create-issue.ts
        └── on-events/
            └── post-connection-creation.ts
    ```

    Each new function file must be imported in `index.ts`, for example `import './github/syncs/github-issues';`.
  </Step>

  <Step id="run-dev-mode" title="Run dev mode">
    Keep dev mode running while you write code:

    ```bash theme={null}
    nango dev
    ```

    `nango dev` continuously type-checks and compiles your function files, surfacing errors immediately.
  </Step>

  <Step id="choose-function-type" title="Choose a function type">
    Choose the function type by starting from the event that should cause Nango to run your logic.

    <a id="trigger-asynchronously" />

    | If you need to...                                               | Guides                                                  | Trigger types                                                     | Common examples                                                                         |
    | --------------------------------------------------------------- | ------------------------------------------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
    | Keep external API data fresh in your app, or react to changes   | [Sync function](/guides/functions/syncs/sync-functions) | Schedule, manual sync trigger, or external webhook reconciliation | Sync contacts/files/events/tickets, RAG, change detection / triggers                    |
    | Run an operation when your app or agent asks for it             | [Action function](/guides/functions/action-functions)   | HTTP API, SDK, async action queue, or MCP/tool call               | Create an issue, send a message, fetch details, perform a write                         |
    | Process an external provider webhook inside Nango               | [Webhook function](/guides/functions/webhook-functions) | External API sends a webhook to Nango                             | Update records from a webhook payload, normalize events, mark data for reconciliation   |
    | React when a Nango connection is created, validated, or deleted | [Event function](/guides/functions/event-functions)     | Nango connection lifecycle event                                  | Validate credentials, register provider webhooks, seed metadata, clean up subscriptions |

    <Tip>
      Use [webhook forwarding](/guides/platform/webhook-forwarding) instead of a webhook function when you want Nango to receive an external webhook, attribute it to a connection when possible, and forward the payload to your app for handling.
    </Tip>
  </Step>

  <Step id="build-function" title="Build the function">
    Follow the specific function type guide for implementation details:

    * [Sync functions](/guides/functions/syncs/sync-functions) — build scheduled data replication, checkpoints, metadata-driven parameters, and record consumption.
    * [Action functions](/guides/functions/action-functions) — build action function operations your app, jobs, or agents can call.
    * [Webhook functions](/guides/functions/webhook-functions) — process external API webhooks inside Nango.
    * [Event functions](/guides/functions/event-functions) — react to Nango connection lifecycle events.

    For shared primitives, use [Storage](/guides/functions/storage) for connection metadata and [Data validation](/guides/functions/data-validation) for input, output, and provider response validation.
  </Step>

  <Step id="test-and-deploy" title="Test and deploy">
    Dry run a function against a real connection:

    ```bash theme={null}
    nango dryrun <function-name> '<CONNECTION-ID>' -e dev
    ```

    If the function reads connection metadata, pass test metadata:

    ```bash theme={null}
    nango dryrun <function-name> '<CONNECTION-ID>' -e dev --metadata '{"accountRegion":"eu"}'
    ```

    Deploy your functions:

    ```bash theme={null}
    nango deploy
    ```

    For function-type-specific commands, see the [Sync function guide](/guides/functions/syncs/sync-functions#test-and-deploy), [Action function guide](/guides/functions/action-functions#test-and-deploy), and [Testing](/guides/functions/testing).
  </Step>

  <Step id="receive-nango-webhooks" title="Receive webhooks from Nango">
    Nango sends webhooks to your app when important events happen: a connection is created, a sync run finishes, an async action completes, or an external webhook is forwarded.

    Configure your app endpoint in **Environment Settings > Webhook URLs**. Webhook URLs are environment-specific, and you can configure up to two URLs per environment. Your endpoint should accept `POST` requests, verify the `X-Nango-Hmac-Sha256` signature, and return a 2xx response after processing.

    Common webhook payloads:

    ```json Auth creation theme={null}
    {
      "type": "auth",
      "operation": "creation",
      "connectionId": "<CONNECTION-ID>",
      "providerConfigKey": "<INTEGRATION-ID>",
      "provider": "<PROVIDER>",
      "environment": "DEV",
      "success": true,
      "tags": {
        "end_user_id": "<USER-ID>",
        "organization_id": "<ORG-ID>"
      }
    }
    ```

    ```json Sync completion theme={null}
    {
      "type": "sync",
      "connectionId": "<CONNECTION-ID>",
      "providerConfigKey": "<INTEGRATION-ID>",
      "syncName": "<SYNC-NAME>",
      "model": "<MODEL-NAME>",
      "success": true,
      "modifiedAfter": "<TIMESTAMP>",
      "responseResults": {
        "added": 10,
        "updated": 5,
        "deleted": 1
      }
    }
    ```

    ```json Async action completion theme={null}
    {
      "type": "async_action",
      "from": "nango",
      "connectionId": "<CONNECTION-ID>",
      "providerConfigKey": "<INTEGRATION-ID>",
      "payload": {
        "id": "<ACTION-ID>",
        "statusUrl": "/action/<ACTION-ID>"
      }
    }
    ```

    For sync webhooks, fetch changed records from the [records API](/reference/backend/http-api/sync/records-list), process them in your app, and persist the last processed cursor. For forwarded external webhooks, see [Webhook forwarding](/guides/platform/webhook-forwarding).

    Read [Receive webhooks from Nango](/guides/platform/webhooks-from-nango) for signature verification, retry behavior, failure payloads, and the full webhook reference.
  </Step>
</Steps>

## Related guides

* [Function tool calling](/guides/functions/tool-calling) — expose action functions to agents, LLM SDKs, and MCP clients.
* [Unified APIs](/guides/functions/unified-apis) — build provider-specific functions behind one stable model.
* [Logging](/guides/functions/logging) — control custom function logs locally and in cloud environments.
* [Storage](/guides/functions/storage) — store per-connection metadata and read it inside functions.
* [Data validation](/guides/functions/data-validation) — validate function input, output, and provider API responses.
* [Testing](/guides/functions/testing) — dry runs, mocks, and snapshot tests.
* [Rate limits](/guides/functions/rate-limits) — handle provider `429` responses and long-running retries.
* [CI/CD](/guides/functions/ci-cd) — deploy functions with your application pipeline.
