Trigger helpers

Trigger helpers are functions that provide type-safe ways to define triggers and schemas for Inngest functions. They replace raw string-based triggers with typed, validated alternatives.

import { eventType, cron, invoke, staticSchema } from "inngest";

eventType

Define a typed event with optional runtime validation. Use the returned object as a trigger, with step.waitForEvent(), and with inngest.send() or step.sendEvent().

import { eventType } from "inngest";
import { z } from "zod";

const accountCreated = eventType("app/account.created", {
  schema: z.object({
    userId: z.string(),
    email: z.string(),
  }),
});

Parameters

  • Name
    name
    Type
    string
    Required
    required
    Description

    The event name. We recommend lowercase dot notation with a prefix/ namespace, e.g. "app/account.created".

  • Name
    options
    Type
    object
    Required
    optional
    Description
    Properties
    • Name
      schema
      Type
      StandardSchemaV1 | StaticSchema
      Required
      optional
      Description

      A schema for the event's data payload. Accepts any Standard Schema compatible library (Zod, Valibot, ArkType, etc.) or a staticSchema() for type-only validation.

      When you provide a runtime schema, the SDK validates event payloads at runtime.

    • Name
      version
      Type
      string
      Required
      optional
      Description

      An optional version identifier for the event payload, e.g. "2024-01-15.1". This sets the v field on sent events.

Return value

eventType() returns an EventType object. The only use case for directly interacting with this object is calling its create method when sending events.

As a trigger

Pass an eventType() result directly in the triggers array of createFunction:

const orderPlaced = eventType("shop/order.placed", {
  schema: z.object({
    orderId: z.string(),
    total: z.number(),
  }),
});

inngest.createFunction(
  {
    id: "process-order",
    triggers: [orderPlaced],
  },
  async ({ event }) => {
    // event.data is typed as { orderId: string; total: number }
    console.log(event.data.orderId);
  }
);

You can also combine with if filtering by wrapping in an object:

inngest.createFunction(
  {
    id: "process-large-orders",
    triggers: [{
      ...orderPlaced,
      if: "event.data.total > 100",
    }],
  },
  async ({ event }) => {
    // Only runs for orders over 100
  }
);

With step.waitForEvent()

Pass an eventType() result as the event option to get typed return values:

const approvalReceived = eventType("app/approval.received", {
  schema: z.object({
    approved: z.boolean(),
    approvedBy: z.string(),
  }),
});

inngest.createFunction(
  {
    id: "approval-workflow",
    triggers: [orderPlaced],
  },
  async ({ event, step }) => {
    const approval = await step.waitForEvent("wait-for-approval", {
      event: approvalReceived,
      timeout: "7d",
      match: "data.orderId",
    });

    if (approval) {
      // approval.data is typed as { approved: boolean; approvedBy: string }
    }
  }
);

With inngest.send() and step.sendEvent()

Use the .create() method to build fully typed event payloads:

// With inngest.send()
await inngest.send(
  orderPlaced.create({
    orderId: "order_123",
    total: 99.99,
  })
);

// With step.sendEvent()
await step.sendEvent("notify-order",
  orderPlaced.create({
    orderId: "order_456",
    total: 149.99,
  })
);

Multiple event types

When a function has multiple event triggers, use event.name to narrow the type:

const userCreated = eventType("app/user.created", {
  schema: z.object({ userId: z.string() }),
});

const userUpdated = eventType("app/user.updated", {
  schema: z.object({ userId: z.string(), changes: z.record(z.unknown()) }),
});

inngest.createFunction(
  {
    id: "sync-user",
    triggers: [userCreated, userUpdated],
  },
  async ({ event }) => {
    if (event.name === "app/user.created") {
      // event.data typed as { userId: string }
    }

    if (event.name === "app/user.updated") {
      // event.data typed as { userId: string; changes: Record<string, unknown> }
    }
  }
);

Wildcards

You can use wildcard patterns with eventType() to match multiple event names:

const anyUserEvent = eventType("user/*");

inngest.createFunction(
  {
    id: "audit-user-events",
    triggers: [anyUserEvent],
  },
  async ({ event }) => {
    // Triggers on "user/created", "user/updated", etc.
  }
);

Wildcard event types cannot define a schema, since the matched events may have different payload shapes.


cron

Create a typed cron trigger for scheduled functions.

import { cron } from "inngest";

inngest.createFunction(
  {
    id: "daily-cleanup",
    triggers: [cron("0 0 * * *")],
  },
  async ({ step }) => {
    // Runs every day at midnight UTC
  }
);

Parameters

  • Name
    cronExpression
    Type
    string
    Required
    required
    Description

    A unix-cron compatible schedule string. Supports an optional timezone prefix, e.g. "TZ=Europe/Paris 0 12 * * 5".

Examples

inngest.createFunction(
  {
    id: "hourly-sync",
    triggers: [cron("0 * * * *")],
  },
  async ({ step }) => {
    // Runs every hour
  }
);

invoke

Define a typed schema for step.invoke() input data. All functions can be invoked regardless of whether you use invoke(). This helper only defines the schema so callers get type checking on the data they pass.

import { invoke } from "inngest";
import { z } from "zod";

const computeSquare = inngest.createFunction(
  {
    id: "compute-square",
    triggers: [
      { event: "calculate/square" },
      invoke({
        schema: z.object({ number: z.number() }),
      }),
    ],
  },
  async ({ event }) => {
    return { result: event.data.number * event.data.number };
  }
);

Parameters

  • Name
    options
    Type
    object
    Required
    required
    Description
    Properties
    • Name
      schema
      Type
      StandardSchemaV1 | StaticSchema
      Required
      required
      Description

      A schema defining the expected data shape when callers invoke this function via step.invoke(). Accepts any Standard Schema compatible library or a staticSchema().

Example

Define the invoke schema on the target function, then call it with typed data:

Target function

import { invoke } from "inngest";
import { z } from "zod";

export const processImage = inngest.createFunction(
  {
    id: "process-image",
    triggers: [
      { event: "image/uploaded" },
      invoke({
        schema: z.object({
          imageUrl: z.string().url(),
          width: z.number(),
        }),
      }),
    ],
  },
  async ({ event }) => {
    // event.data.imageUrl and event.data.width are typed
    return { processed: true };
  }
);

Calling function

const result = await step.invoke("resize-image", {
  function: processImage,
  data: {
    imageUrl: "https://example.com/photo.jpg",
    width: 800,
    // ^ The invoke schema types and validates this
  },
});

staticSchema

A type-only schema utility for when you want TypeScript type checking without runtime validation. Use this as an alternative to a Standard Schema library like Zod.

import { eventType, staticSchema } from "inngest";

type OrderData = {
  orderId: string;
  total: number;
};

const orderPlaced = eventType("shop/order.placed", {
  schema: staticSchema<OrderData>(),
});

Use staticSchema() when you don't need runtime validation. If you want payloads validated at runtime, use a Standard Schema library like Zod, Valibot, or ArkType instead.

Type parameters

  • Name
    T
    Type
    type
    Required
    required
    Description

    The TypeScript type representing the event's data shape. The compiler uses this type for compile-time type checking only — it does not perform runtime validation.

Examples

import { eventType, staticSchema } from "inngest";

type UserPayload = {
  userId: string;
  email: string;
};

const userCreated = eventType("app/user.created", {
  schema: staticSchema<UserPayload>(),
});

inngest.createFunction(
  {
    id: "on-user-created",
    triggers: [userCreated],
  },
  async ({ event }) => {
    // event.data typed as { userId: string; email: string }
  }
);