# Create Function
Source: https://www.inngest.com/docs/reference/functions/create

Define your functions using the `createFunction` method on the [Inngest client](/docs/reference/client/create).

```ts
export default inngest.createFunction(
  { id: "import-product-images" },
  { event: "shop/product.imported" },
  async ({ event, step, runId }) => {
    // Your function code
  }
);
```

---

## `inngest.createFunction(configuration, trigger, handler): InngestFunction`

The `createFunction` method accepts a series of arguments to define your function.

### Configuration

<Properties>
  <Property name="id" type="string" required>
    A unique identifier for your function. This should not change between deploys.
  </Property>
  <Property name="name" type="string">
    A name for your function. If defined, this will be shown in the UI as a friendly display name instead of the ID.
  </Property>

  <Property name="concurrency" type="number | object | [object, object]">
    Limit the number of concurrently running functions ([reference](/docs/functions/concurrency))

    <Properties nested={true} collapse={true}>
      <Property name="limit" type="number" required>
        The maximum number of concurrently running steps.
      </Property>
      <Property name="scope" type="'account' | 'env' | 'fn'">
        The scope for the concurrency limit, which impacts whether concurrency is managed on an individual function, across an environment, or across your entire account.
    
        * `fn` (default):  only the runs of this function affects the concurrency limit
        * `env`:  all runs within the same environment that share the same evaluated key value will affect the concurrency limit.  This requires setting a `key` which evaluates to a virtual queue name.
        * `account`:  every run that shares the same evaluated key value will affect the concurrency limit, across every environment.  This requires setting a `key` which evaluates to a virtual queue name.
      </Property>
      <Property name="key" type="string">
        A unique key expression for which to restrict concurrently running steps to. The expression is evaluated for each triggering event and a unique key is generated. Read [our guide to writing expressions](/docs/guides/writing-expressions) for more info.
      </Property>
    </Properties>
  </Property>

  <Property name="throttle" type="object">
    Limits the number of new function runs started over a given period of time ([guide](/docs/guides/throttling)).

    <Properties nested={true} collapse={true}>
      <Property name="limit" type="number" required>
        The total number of runs allowed to start within the given `period`.
      </Property>
      <Property name="period" type="string" required>
        The period within which the `limit` will be applied.
      </Property>
      <Property name="burst" type="number">
        The number of additional runs allowed to start in the given window in a single burst. This is added on top of the limit, which ensures high throughput within the period.
      </Property>
      <Property name="key" type="string">
        A unique expression for which to apply the throttle limit to. The expression is evaluated for each triggering event and will be applied for each unique value. Read [our guide to writing expressions](/docs/guides/writing-expressions) for more info.
      </Property>
    </Properties>
  </Property>

  <Property name="idempotency" type="string">
    A key expression which is used to prevent duplicate events from triggering a function more than once in 24 hours. This is equivalent to setting `rateLimit` with a `key`, a `limit` of `1`  and `period` of `24hr`. [Read the idempotency guide here](/docs/guides/handling-idempotency).

    Expressions are defined using the Common Expression Language (CEL) with the original event accessible using dot-notation. Read [our guide to writing expressions](/docs/guides/writing-expressions) for more info. Examples:

    * Only run once for each customer id: `'event.data.customer_id'`
    * Only run once for each account and email address: `'event.data.account_id + "-" + event.user.email'`
  </Property>

  <Property name="rateLimit" type="object">
    Options to configure how to rate limit function execution ([reference](/docs/reference/functions/rate-limit))

    <Properties nested={true} collapse={true}>
      <Property name="limit" type="number" required>
        The maximum number of functions to run in the given time period.
      </Property>
      <Property name="period" type="string" required>
        The time period of which to set the limit. The period begins when the first matching event is received.
        Current permitted values are from `1s` to `60s`.
      </Property>
      <Property name="key" type="string">
        A unique key expression to apply the limit to. The expression is evaluated for each triggering event.

        Expressions are defined using the Common Expression Language (CEL) with the original event accessible using dot-notation. Read [our guide to writing expressions](/docs/guides/writing-expressions) for more info. Examples:

        * Rate limit per customer id: `'event.data.customer_id'`
        * Rate limit per account and email address: `'event.data.account_id + "-" + event.user.email'`
      </Property>
    </Properties>
  </Property>

  <Property name="debounce" type="object">
    Options to configure function debounce ([reference](/docs/reference/functions/debounce))
    <Properties nested={true} collapse={true}>
      <Property name="period" type="string" required>
        The time period of which to set the limit. The period begins when the first matching event is received.
        Current permitted values are from `1s` to `7d` (`168h`).
      </Property>
      <Property name="key" type="string">
        A unique key expression to apply the debounce to. The expression is evaluated for each triggering event.

        Expressions are defined using the Common Expression Language (CEL) with the original event accessible using dot-notation. Read [our guide to writing expressions](/docs/guides/writing-expressions) for more info. Examples:

        * Debounce per customer id: `'event.data.customer_id'`
        * Debounce per account and email address: `'event.data.account_id + "-" + event.user.email'`
      </Property>
    </Properties>
  </Property>

  <Property name="priority" type="object">
    Options to configure how to prioritize functions

    <Properties nested={true} collapse={true}>
      <Property name="run" type="string">
        An expression which must return an integer between -600 and 600 (by default), with higher return values resulting in a higher priority.

        Examples:
        * Return the priority within an event directly: `event.data.priority` (where
    `event.data.priority` is an int within your account's range)
        * Rate limit by a string field: `event.data.plan == 'enterprise' ? 180 : 0`

        See [reference](/docs/reference/functions/run-priority) for more information.
      </Property>
    </Properties>
  </Property>

  <Property name="batchEvents" type="object">
    Configure how the function should consume batches of events ([reference](/docs/guides/batching))

    <Properties nested={true} collapse={true}>  
      <Property name="maxSize" type="number" required>
        The maximum number of events a batch can have. Current limit is `100`.
      </Property>
      <Property name="timeout" type="string" required>
        How long to wait before invoking the function with the batch even if it's not full.
        Current permitted values are from `1s` to `60s`.
      </Property>
      <Property name="key" type="string">
        A unique key expression to apply the batching to. The expression is evaluated for each triggering event.

        Expressions are defined using the Common Expression Language (CEL) with the original event accessible using dot-notation. Read [our guide to writing expressions](/docs/guides/writing-expressions) for more info. Examples:

        * Batch events per customer id: `'event.data.customer_id'`
        * Batch events per account and email address: `'event.data.account_id + "-" + event.user.email'`
      </Property>
      <Property name="if" type="string">
        A boolean expression to conditionally batch events that evaluate to true on this expression. The expression is evaluated for each triggering event.

        Expressions are defined using the Common Expression Language (CEL) with the original event accessible using dot-notation. Read [our guide to writing expressions](/docs/guides/writing-expressions) for more info. Examples:

        * Batch events for free account types: `'event.data.account_type == "free"'`
      </Property>
    </Properties>
  </Property>
  <Property name="retries" type="number">
    Configure the number of times the function will be retried from `0` to `20`. Default: `4`
  </Property>
  <Property name="onFailure" type="function">
    A function that will be called only when this Inngest function fails after all retries have been attempted ([reference](/docs/reference/functions/handling-failures))
  </Property>
  <Property name="cancelOn" type="array of objects">
    Define events that can be used to cancel a running or sleeping function ([reference](/docs/reference/typescript/functions/cancel-on))
    <Properties nested={true} collapse={true}>
      <Property name="event" type="string" required>
        The event name which will be used to cancel
      </Property>
      <Property name="match" type="string">
        The property to match the event trigger and the cancelling event, using dot-notation, for example, `data.userId`. Read [our guide to writing expressions](/docs/guides/writing-expressions) for more info.
      </Property>
      <Property name="if" type="string">
        An expression on which to conditionally match the original event trigger (`event`) and the wait event (`async`). Cannot be combined with `match`.

        Expressions are defined using the Common Expression Language (CEL) with the events accessible using dot-notation. Read our [guide to writing expressions](/docs/guides/writing-expressions) for more info. Examples:

        * `event.data.userId == async.data.userId && async.data.billing_plan == 'pro'`
      </Property>
      <Property name="timeout" type="string">
        The amount of time to wait to receive the cancelling event. A time string compatible with the [ms](https://npm.im/ms) package, e.g. `"30m"`, `"3 hours"`, or `"2.5d"`
      </Property>
    </Properties>
  </Property>

  <Property name="timeouts" type="object">
    Options to configure timeouts for cancellation ([reference](/docs/features/inngest-functions/cancellation/cancel-on-timeouts))
    <Properties nested={true} collapse={true}>
      <Property name="start" type="string">
        The timeout for starting a function run.  If the time between scheduling and starting a function exceeds this duration, the function will be cancelled.
        Examples are: `10s`, `45m`, `18h30m`.
      </Property>
      <Property name="finish" type="string">
        The timeout for executing a run.  If a run takes longer than this duration to execute, the run will be cancelled.  This does not include the
        time waiting for the function to start (see `timeouts.start`).
        Examples are: `10s`, `45m`, `18h30m`.
      </Property>
    </Properties>
  </Property>

</Properties>

{/*TODO - Document fns arg*/}

### Trigger

One of the following function triggers is **Required**.

You can also specify an array of up to 10 of the following triggers to invoke
your function with multiple events or crons. See the [Multiple Triggers](/docs/guides/multiple-triggers) guide.

<Callout>
Cron triggers with overlapping schedules for a single function will be deduplicated.
</Callout>

<Properties>
  <Property name="event" type="string">
    The name of the event that will trigger this event to run
  </Property>
  <Property name="cron" type="string">
    A [unix-cron](https://crontab.guru/) compatible schedule string. <br/>Optional timezone prefix, e.g. `TZ=Europe/Paris 0 12 * * 5`.
  </Property>
</Properties>

When using an `event` trigger, you can optionally combine it with the `if` option to filter events:

<Properties nested={true} name="Additional options">
  <Property name="if" type="string">
    A comparison expression that returns true or false whether the function should handle or ignore a given matching event.

    Expressions are defined using the Common Expression Language (CEL) with the original event accessible using dot-notation. Read [our guide to writing expressions](/docs/guides/writing-expressions) for more info. Examples:

    * `'event.data.action == "published"'`
    * `'event.data.priority >= 4'`
  </Property>
</Properties>

### Handler

The handler is your code that runs whenever the trigger occurs. Every function handler receives a single object argument which can be deconstructed. The key arguments are `event` and `step`. Note, that scheduled functions that use a `cron` trigger will not receive an `event` argument.

```ts
function handler({ event, events, step, runId, logger, attempt }) {/* ... */}
```

#### `event`

The event payload `object` that triggered the given function run. The event payload object will match what you send with [`inngest.send()`](/docs/reference/events/send). Below is an example event payload object:

```ts
{
  name: "app/account.created",
  data: {
    userId: "1234567890"
  },
  v: "2023-05-12.1",
  ts: 1683898268584
}
```

#### `events` <VersionBadge version="v2.2.0+" />

`events` is an array of `event` payload objects that's accessible when the `batchEvents` is set on the function configuration.
If batching is not configured, the array contains a single event payload matching the `event` argument.

#### `step`

The `step` object has methods that enable you to define

- [`step.run()`](/docs/reference/functions/step-run) - Run synchronous or asynchronous code as a retriable step in your function
- [`step.sleep()`](/docs/reference/functions/step-sleep) - Sleep for a given amount of time
- [`step.sleepUntil()`](/docs/reference/functions/step-sleep-until) - Sleep until a given time
- [`step.invoke()`](/docs/reference/functions/step-invoke) - Invoke another Inngest function as a step, receiving the result of the invoked function
- [`step.waitForEvent()`](/docs/reference/functions/step-wait-for-event) - Pause a function's execution until another event is received
- [`step.sendEvent()`](/docs/reference/functions/step-send-event) - Send event(s) reliability within your function. Use this instead of `inngest.send()` to ensure reliable event delivery from within functions.

#### `runId`

The unique ID for the given function run. This can be useful for logging and looking up specific function runs in the Inngest dashboard.

#### `logger` <VersionBadge version="v2.0.0+" />

The `logger` object exposes the following interfaces.

```ts
export interface Logger {
  info(...args: any[]): void;
  warn(...args: any[]): void;
  error(...args: any[]): void;
  debug(...args: any[]): void;
}
```

It is a proxy object that is either backed by `console` or the logger you provided ([reference](/docs/guides/logging)).

#### `attempt` <VersionBadge version="v2.5.0+" />

The current zero-indexed attempt number for this function execution. The first attempt will be 0, the second 1, and so on. The attempt number is incremented every time the function throws an error and is retried.