# Create a workflow

> **POST** `https://api.us.nylas.com/v3/workflows`

Source: https://developer.nylas.com/docs/reference/api/application-level-workflows/create-workflow/

Creates an application-level workflow.

<div id="admonition-info">ℹ️ <b>You must have an existing <a href="/docs/reference/api/application-level-templates/">template</a> to create a workflow</b>.</div>

**Authentication:** NYLAS_API_KEY

## Request body

Create workflow request

Content-Type: application/json

- `delay` (integer, default: `0`) - The number of minutes between a `trigger_event` being met and the workflow
sending a message.
- `is_enabled` (boolean, default: `true`) - When `true`, indicates that the workflow is enabled.
- `name` (string) **(required)** - The name of the workflow.
- `template_id` (string) **(required)** - The ID of the email template the workflow uses.
- `trigger_event` (string, one of: `booking.cancelled`, `booking.created`, `booking.pending`, `booking.reminder`, `booking.rescheduled`, `calendar.created`, `calendar.deleted`, `calendar.updated`, `contact.deleted`, `contact.updated`, `event.created`, `event.deleted`, `event.updated`, `folder.created`, `folder.deleted`, `folder.updated`, `grant.created`, `grant.deleted`, `grant.expired`, `grant.imap_sync_completed`, `grant.updated`, `message.bounce_detected`, `message.created`, `message.link_clicked`, `message.opened`, `message.send_failed`, `message.send_success`, `message.updated`, `notetaker.created`, `notetaker.deleted`, `notetaker.media`, `notetaker.meeting_state`, `notetaker.updated`, `thread.replied`) **(required)** - The event which triggers the workflow.

`grant.expired` and `grant.deleted` require a `from` sender address, because the grant that
triggered them can no longer send email. Every other trigger accepts a workflow without one.

Workflows have no condition or filter field, so an enabled workflow sends for every matching
event in its scope. High-volume triggers such as `message.created` fire for every message in
every mailbox the workflow covers.
- `from` (object, nullable) - Details of the sender if the workflow should use [transactional send](/docs/reference/api/transactional-send/).
If not provided, the sender will be the grant associated with the trigger event.

A workflow with `from.email` must use an application-level template. If `template_id` points
to a grant-level template, the request returns `400` with the message
`a Workflow with a from email must use an application-level template`.
  - `email` (string) - The email address of the sender.
  - `name` (string) - The name of the sender.

## Responses

### 200 - Success. Returns workflow.

- `request_id` (string) **(required)** - The ID of the request.
- `data` (object) **(required)** - A custom workflow that sends messages from a template when certain events are triggered.
  - `app_id` (string, nullable) - The ID of the Nylas application associated with the workflow. Returned only if the
workflow is configured at the application level.
  - `date_created` (integer) **(required)** - When the workflow was created, in seconds using the Unix timestamp format.
  - `delay` (integer) **(required)** - The number of minutes between a `trigger_event` being met and the workflow sending
a message.
  - `grant_id` (string, nullable) - The ID of the grant associated with the workflow. Returned only if the workflow is
configured at the grant level.
  - `id` (string) **(required)** - The ID of the workflow.
  - `is_enabled` (boolean) **(required)** - When `true`, indicates that the workflow is enabled.
  - `name` (string) **(required)** - The name of the workflow.
  - `template_id` (string) **(required)** - The ID of the email template the workflow uses.
  - `trigger_event` (string, one of: `booking.cancelled`, `booking.created`, `booking.pending`, `booking.reminder`, `booking.rescheduled`, `calendar.created`, `calendar.deleted`, `calendar.updated`, `contact.deleted`, `contact.updated`, `event.created`, `event.deleted`, `event.updated`, `folder.created`, `folder.deleted`, `folder.updated`, `grant.created`, `grant.deleted`, `grant.expired`, `grant.imap_sync_completed`, `grant.updated`, `message.bounce_detected`, `message.created`, `message.link_clicked`, `message.opened`, `message.send_failed`, `message.send_success`, `message.updated`, `notetaker.created`, `notetaker.deleted`, `notetaker.media`, `notetaker.meeting_state`, `notetaker.updated`, `thread.replied`) **(required)** - The event which triggers the workflow.

`grant.expired` and `grant.deleted` require a `from` sender address, because the grant that
triggered them can no longer send email. Every other trigger accepts a workflow without one.

Workflows have no condition or filter field, so an enabled workflow sends for every matching
event in its scope. High-volume triggers such as `message.created` fire for every message in
every mailbox the workflow covers.
  - `from` (object, nullable) - Details of the sender if the workflow uses transactional send.
    - `email` (string) - The email address of the sender.
    - `name` (string) - The name of the sender.

### 400 - Error: Bad request

- `request_id` (string) **(required)** - The ID of the request.
- `error` (object) **(required)**
  - `type` (string) **(required)** - The type of error that occurred.
  - `message` (string) **(required)** - A human-readable message describing the error.

### 404 - Error: Not found

- `request_id` (string) **(required)** - The ID of the request.
- `error` (object) **(required)**
  - `type` (string) **(required)** - The type of error that occurred.
  - `message` (string) **(required)** - A human-readable message describing the error.

## Code samples

### cURL

```bash
curl --request POST \
  --url "https://api.us.nylas.com/v3/workflows" \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "Confirmation Workflow",
    "trigger_event": "booking.created",
    "template_id": "<TEMPLATE_ID>",
    "delay": 1,
    "is_enabled": true
  }'
```
