---
title: "Getting started with Trigger.dev"
sidebarTitle: "Quick start"
description: "Get your first workflow running in just a few minutes"
---

Trigger.dev workflows are written in your codebase and run in your existing infrastructure. This means:

- They are version controlled with the rest of your code.
- They run locally and don't require you to use tunnels.

<Note>
  Currently we require you to have a long-running Node.js server, e.g. Express.
  Support for serverless is coming soon.
</Note>

## 1. Installing @trigger.dev packages

In your existing project install the packages:

<Tabs>
  <Tab title="npm">

```bash
npm install @trigger.dev/sdk @trigger.dev/slack zod
```

  </Tab>
  <Tab title="pnpm">

```bash
pnpm install @trigger.dev/sdk @trigger.dev/slack zod
```

  </Tab>
  <Tab title="yarn">

```bash
yarn add @trigger.dev/sdk @trigger.dev/slack zod
```

  </Tab>
</Tabs>

What do the packages do?

- `@trigger.dev/sdk` is required to use Trigger.dev, it allows you to run workflows.
- `@trigger.dev/slack` is the official Slack integration, which allows you to interact with the Slack API.
- `zod` is used to define schemas (the expected shape of an object).

## 2. Sign in to your Trigger.dev dashboard

Go to [trigger.dev](https://app.trigger.dev) and sign up or login to your account.

## 3. Get your API keys

In the bottom-left corner of an Organization page you can find your API keys.
![API Keys](/images/api-keys.png)

## 4. Creating your first workflow

Workflows are triggered by events. In this example, we have defined a custom event called `user.created`. We support many different types of events including webhooks, scheduled, and more coming soon.

```ts first-workflow.ts
import { Trigger, customEvent } from "@trigger.dev/sdk";
import { postMessage } from "@trigger.dev/slack";
import { z } from "zod";

new Trigger({
  id: "new-user",
  name: "New user slack message",
  apiKey: "<your_api_key>",
  on: customEvent({
    name: "user.created",
    schema: z.object({
      name: z.string(),
      email: z.string(),
      paidPlan: z.boolean(),
    }),
  }),
  run: async (event, ctx) => {
    await ctx.logger.info("This log will appear on the Trigger.dev run page");

    //send a message to the #new-users Slack channel with user details
    const response = await postMessage("send-to-slack", {
      channel: "new-users",
      text: `New user: ${event.name} (${event.email}) signed up. ${
        event.paidPlan ? "They are paying" : "They are on the free plan"
      }.`,
    });

    return response.message;
  },
}).listen();
```

You'll notice that when we subscribe to the custom event we have to say the name of the event and provide a schema. Schemas are created using Zod. In this case events must send an object that has `name`, `email`, and `paidPlan`.

<Note>
  If the event is triggered with an object that doesn't match this schema, the
  workflow won't run.
</Note>

<Note>
  Above we set the API key inside the Trigger object. We recommend instead that
  you add an environment variable called `TRIGGER_API_KEY`. That way you can use
  your development API key locally and the production one when you deploy.
</Note>

## 6. Run your web server

Run your server how you normally would, e.g. `npm run dev`. This will connect your workflow to Trigger.dev, so we can start sending you events. You should see some log messages in your server console (tip: you can turn these off by removing the `logLevel: "info"` from the code above).

## 5. Testing your workflow from the dashboard

Now that the workflow is connected to Trigger.dev we need to trigger it. You can easily test your workflow from [your Trigger.dev dashboard](https://app.trigger.dev).

On the organization page you should see that the Workflow has now appeared (you may need to refresh the page from last time).

!["New user slack message" workflow](/images/workflow.png)

Move to the "New user slack message" and you will see the workflow page. There have been no runs yet.

Move to the "Test" page and input a valid test event, remember the workflow expects a name, email and paidPlan. You can copy this:

```json
{
  "name": "Rick Astley",
  "email": "nevergonn@giveyou.up",
  "paidPlan": true
}
```

Hit the "Run test" button and it will take us to our first run 🚀!

![Test a run](/images/run-test.png)

## 6. The run page

All of the steps in a workflow, including the initial event, can be viewed in detail. You will need to refresh the page if it's running to see it move between steps.

But there's a problem, we've used Slack in our code and we haven't authenticated.

![Test run failed](/images/run-failed.png)

## 7. Authenticating with Slack

When a workflow step uses an API integration that you haven't already authenticated with, it will pause until you've authenticated.

Simply click the "Connect to Slack" button and sign-in with your desired Slack workspace. As soon as you do, the workflow will pick up where it left off.

Test complete!

![Test a run](/images/run-succeeded.png)

## 8. Triggering this workflow from code

As this workflow uses a custom event, we need to manually trigger it from our code. Anywhere in your code you can do this:

```ts
import { sendEvent } from "@trigger.dev/sdk";

/*
...your other code
*/

await sendEvent(uuidv4(), {
  name: "user.created"
  payload: {
    name: "Eleven",
    email: "jane@hawksmoorhigh.edu",
    paidPlan: true,
  },
});
```

<Note>
  If you are using `sendEvent` outside of a Trigger, make sure and set your API
  key to the `TRIGGER_API_KEY` environment variable. See the
  [sendEvent](/functions/send-event) docs for more info.
</Note>

When you run your server and this code executes, it will trigger the workflow. You will see this in the run list on your workflow page.

You can also use our API to send events from other programming languages. See the [sendEvent](/api/events/sendEvent) API reference for more info.

## Next steps

<Card
  title="Join the communty"
  icon="discord"
  href="https://discord.gg/nkqV9xBYWy"
>
  Meet other users, get help and product updates. We will respond to all
  messages and will help with any issues.
</Card>

There are many things we didn't cover here, including Webhook and Scheduled triggers. Below are a some more features to explore:

### Triggers

Triggers are what cause your workflows to run.

<CardGroup>
  <Card title="Webhooks" icon="rectangle-terminal" href="/triggers/webhooks">
    Easily subscribe to the APIs you're using
  </Card>
  <Card title="Scheduled" icon="clock" href="/triggers/scheduled">
    Trigger your workflows on a repeating schedule
  </Card>
  <Card title="Custom events" icon="code" href="/triggers/custom-events">
    More details on custom events
  </Card>
  <Card title="More coming soon" icon="bookmark">
    On received email, HTTP endpoint and AWS Event Bridge
  </Card>
</CardGroup>

### Functions

<CardGroup>
  <Card
    title="API integrations"
    icon="rectangle-terminal"
    href="/integrations/apis"
  >
    We are making it easy to use lots of APIs by adding integrations.
  </Card>
  <Card title="Fetch" icon="server" href="/functions/fetch">
    Call any API from your workflow
  </Card>
  <Card title="Delays" icon="alarm-clock" href="/functions/delays">
    Add delays to your workflows. They're resilient so it doesn't matter if your
    server goes down.
  </Card>
  <Card title="Send event" icon="code" href="/functions/send-event">
    Send an event, to trigger a custom event workflow
  </Card>
</CardGroup>
