> ## Documentation Index
> Fetch the complete documentation index at: https://conductorone-leet-slack-mcp-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Extend with custom code

> Extend C1's identity governance capabilities with custom serverless TypeScript functions that integrate with external systems and implement organization-specific workflows.

<Warning>
  **Early access.** This feature is in early access, which means it's undergoing ongoing testing and development while we gather feedback, validate functionality, and improve outputs. Contact the C1 Support team if you'd like to try it out or share feedback.
</Warning>

Functions are serverless TypeScript functions that extend C1's identity governance capabilities. Write custom automation logic, integrate with external systems, and implement organization-specific workflows that go beyond out-of-the-box features.

## What you can do with functions

* **Call external systems**: Integrate with approved external APIs using a network allowlist
* **Run on events**: Trigger functions from automations using user lifecycle events, access changes, or schedules
* **Implement custom business logic**: Write your organization's unique workflows in TypeScript
* **Access C1 data**: Query users, apps, and entitlements through type-safe APIs

## Key features

Functions provide a secure, managed environment for running custom code.

### TypeScript runtime

* Modern TypeScript with async/await support
* Import external npm packages dynamically using `npm:` prefix
* `@c1/functions-sdk` provides pre-authenticated access to C1 APIs

### Security and isolation

* Each function runs in isolation in a sandboxed environment
* Functions authenticate to the C1 API as a [service principal](/product/admin/service-principals/overview) — its role bindings determine what the function can do at runtime
* Network allowlist controls which external domains functions can access
* Secrets management stores API keys securely, accessible via `functions.getConfig()`
* Execution logs capture `console.log` statements and stream back to the UI

## Where functions run

Once you've [written and published a function](/product/admin/functions-create), it can be invoked in multiple ways:

### Automation steps

Functions can run as steps in [automation workflows](/product/admin/functions-automations), triggered by:

* User lifecycle events (created, updated, deactivated)
* Access events (grant created, revoked)
* Review events (completed, decisions made)
* Schedule triggers (daily, weekly, custom)

### Manual invocation

You can run functions on-demand from the C1 web UI:

<Steps>
  <Step>
    Navigate to **Workflows** > **Functions** and select your function.
  </Step>

  <Step>
    Click **Run**.
  </Step>

  <Step>
    Provide input JSON.
  </Step>

  <Step>
    Click **Run**. The function executes and returns output JSON.
  </Step>
</Steps>

### API invocation

You can also call functions programmatically via the C1 API for administrative tasks, batch processing, or integration with other systems.

## Key use cases for functions

Functions unlock automation scenarios that go beyond standard workflows. Here are some examples of what they can do:

### Dynamic attribute generation

Generate and transform user attributes across systems — usernames, custom domain matching logic, attribute mapping translation tables, and other logic that goes beyond simple field mapping. Functions can implement your organization's naming conventions, check existing values for uniqueness, apply custom domain rules, and return computed values for use in provisioning.

### Custom notification and escalation

Send notifications via multiple channels (Slack, Teams, email, SMS) with custom formatting and escalation logic. Functions can format rich notifications with user and access context, implement retry logic, and track delivery.

### Out-of-band API calls

Call external APIs for provisioning-related tasks or other integrations that a connector invoked via automation can't handle. Functions manage authentication, rate limits, and response handling for these calls. If a system has an existing ConductorOne connector (such as Jira or ServiceNow), use that connector via automation instead of a function.
