> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/calcom/cal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Workflows

> Automate reminders, notifications, and follow-ups for your bookings

Workflows allow you to automate communications and actions based on booking events. Send email reminders, SMS notifications, WhatsApp messages, or trigger custom actions at specific times or events.

## Overview

A workflow consists of:

* **Trigger**: The event that starts the workflow (e.g., booking created, event starts soon)
* **Steps**: Actions to take (e.g., send email, send SMS)
* **Timing**: When to execute (immediately or at a specific time before/after the event)
* **Recipients**: Who receives the notification (host, attendee, or custom recipients)

```typescript theme={null}
// From workflows types.ts:19
type Workflow = {
  id: number;
  name: string;
  trigger: WorkflowTriggerEvents;
  time: number | null;      // e.g., 24 for "24 hours"
  timeUnit: TimeUnit | null; // "HOUR", "DAY", "MINUTE"
  steps: WorkflowStep[];
};
```

## Workflow Triggers

```typescript theme={null}
// From constants.ts:3
enum WorkflowTriggerEvents {
  BEFORE_EVENT                    // X time before event starts
  AFTER_EVENT                     // X time after event ends
  NEW_EVENT                       // Immediately when booked
  EVENT_CANCELLED                 // When booking is cancelled
  RESCHEDULE_EVENT               // When booking is rescheduled
  BOOKING_REQUESTED              // When approval is requested
  BOOKING_REJECTED               // When booking is rejected
  BOOKING_PAID                   // When payment is completed
  FORM_SUBMITTED                 // When routing form is submitted
  BOOKING_NO_SHOW_UPDATED        // When no-show status changes
}
```

<Tabs>
  <Tab title="Time-Based">
    Execute at a specific time relative to the event:

    ```typescript theme={null}
    {
      trigger: "BEFORE_EVENT",
      time: 24,
      timeUnit: "HOUR"  // 24 hours before event
    }
    ```
  </Tab>

  <Tab title="Immediate">
    Execute immediately when the event occurs:

    ```typescript theme={null}
    {
      trigger: "NEW_EVENT",
      time: null,
      timeUnit: null
    }
    ```
  </Tab>
</Tabs>

<Note>
  Time-based triggers (BEFORE\_EVENT, AFTER\_EVENT) require a time and timeUnit. Immediate triggers don't.
</Note>

## Workflow Actions

```typescript theme={null}
// From constants.ts:20
enum WorkflowActions {
  EMAIL_HOST         // Send email to event host
  EMAIL_ATTENDEE     // Send email to attendee
  EMAIL_ADDRESS      // Send to custom email address
  SMS_ATTENDEE       // Send SMS to attendee
  SMS_NUMBER         // Send SMS to custom number
  WHATSAPP_ATTENDEE  // Send WhatsApp to attendee
  WHATSAPP_NUMBER    // Send WhatsApp to custom number
  CAL_AI_PHONE_CALL  // Trigger AI phone call
}
```

### Email Actions

```typescript theme={null}
// Workflow step for email
type WorkflowStep = {
  action: "EMAIL_HOST" | "EMAIL_ATTENDEE" | "EMAIL_ADDRESS";
  sendTo: "user@example.com" | null;  // For EMAIL_ADDRESS only
  emailSubject: string;
  reminderBody: string | null;  // Email body
  template: WorkflowTemplates;
  includeCalendarEvent: boolean;  // Attach ICS file
};
```

<CardGroup cols={2}>
  <Card title="EMAIL_HOST" icon="envelope">
    Sends to the event host(s). No `sendTo` needed.
  </Card>

  <Card title="EMAIL_ATTENDEE" icon="envelope-open">
    Sends to the booking attendee(s). No `sendTo` needed.
  </Card>

  <Card title="EMAIL_ADDRESS" icon="at">
    Sends to a custom email address specified in `sendTo`.
  </Card>
</CardGroup>

### SMS and WhatsApp Actions

```typescript theme={null}
{
  action: "SMS_ATTENDEE",
  reminderBody: "Your meeting is starting in 1 hour!",
  template: "REMINDER",
  numberRequired: true,            // Attendee must provide phone number
  numberVerificationPending: false // Verification status
}
```

<Warning>
  SMS and WhatsApp actions require phone number verification. The first time a number is used, the sender must verify it.
</Warning>

## Workflow Templates

```typescript theme={null}
// From constants.ts:33
enum WorkflowTemplates {
  CUSTOM      // Custom message
  REMINDER    // Default reminder template
  RATING      // Request feedback/rating
  CANCELLED   // Cancellation notification
  COMPLETED   // Event completed notification
  RESCHEDULED // Reschedule notification
}
```

Templates provide pre-filled content with dynamic variables.

## Dynamic Variables

Use variables in your workflow messages:

```typescript theme={null}
// From constants.ts:57
[
  "event_name",              // Event type title
  "event_date",              // Event date
  "event_time",              // Event start time
  "event_end_time",          // Event end time
  "timezone",                // User's timezone
  "location",                // Meeting location
  "organizer_name",          // Host name
  "attendee_name",           // Attendee full name
  "attendee_first_name",     // Attendee first name
  "attendee_last_name",      // Attendee last name
  "attendee_email",          // Attendee email
  "additional_notes",        // Booking notes
  "meeting_url",             // Video meeting URL
  "cancel_url",              // Cancellation link
  "reschedule_url",          // Reschedule link
  "rating_url",              // Rating/feedback link
  "no_show_url",             // Mark as no-show link
  "attendee_timezone",       // Attendee's timezone
]
```

### Using Variables

```typescript theme={null}
{
  emailSubject: "Reminder: {event_name} in 24 hours",
  reminderBody: `
    Hi {attendee_first_name},
    
    This is a reminder that you have "{event_name}" scheduled for:
    {event_date} at {event_time} ({timezone})
    
    Location: {location}
    Meeting URL: {meeting_url}
    
    Need to reschedule? {reschedule_url}
    
    See you soon!
    {organizer_name}
  `
}
```

<Note>
  Variables are automatically replaced with actual values when the workflow executes.
</Note>

## Creating a Workflow

<Steps>
  <Step title="Navigate to Workflows">
    Go to Settings → Workflows from your dashboard
  </Step>

  <Step title="Create New Workflow">
    Click "New Workflow" and give it a descriptive name
  </Step>

  <Step title="Select Trigger">
    Choose when the workflow should run (e.g., "Before Event")
  </Step>

  <Step title="Set Timing">
    For time-based triggers, specify how long before/after (e.g., 24 hours)
  </Step>

  <Step title="Add Steps">
    Add one or more actions (email, SMS, etc.)
  </Step>

  <Step title="Configure Each Step">
    Set recipient, template, and message content
  </Step>

  <Step title="Assign to Event Types">
    Select which event types should use this workflow
  </Step>
</Steps>

## Workflow Schema

```typescript theme={null}
// From schema.prisma:1556
model Workflow {
  id          Int                   @id
  name        String
  userId      Int?                  // Owner (if personal)
  teamId      Int?                  // Owner (if team)
  trigger     WorkflowTriggerEvents
  time        Int?                  // Time value
  timeUnit    TimeUnit?             // DAY, HOUR, MINUTE
  steps       WorkflowStep[]
  
  // Activation
  activeOn             WorkflowsOnEventTypes[]    // Event types using this
  activeOnTeams        WorkflowsOnTeams[]         // Teams using this
  activeOnRoutingForms WorkflowsOnRoutingForms[]  // Routing forms using this
  isActiveOnAll        Boolean @default(false)    // Apply to all event types
}

model WorkflowStep {
  id            Int      @id
  stepNumber    Int      // Order of execution
  workflowId    Int
  action        WorkflowActions
  sendTo        String?  // Custom recipient
  emailSubject  String?
  reminderBody  String?
  template      WorkflowTemplates
  
  // Phone/SMS specific
  numberRequired            Boolean?
  numberVerificationPending Boolean @default(true)
  sender                    String?  // SMS sender ID
  
  // Options
  includeCalendarEvent Boolean @default(false)
  autoTranslateEnabled Boolean @default(false)
  sourceLocale         String?
}
```

## Assigning Workflows

### To Event Types

```typescript theme={null}
// From schema.prisma:1598
model WorkflowsOnEventTypes {
  workflowId  Int
  eventTypeId Int
  workflow    Workflow
  eventType   EventType
}
```

Assign workflows to specific event types from the workflow editor or event type settings.

### To Teams

```typescript theme={null}
// From schema.prisma:1622
model WorkflowsOnTeams {
  workflowId Int
  teamId     Int
  workflow   Workflow
  team       Team
}
```

Team workflows apply to all team event types.

### To Routing Forms

```typescript theme={null}
// From schema.prisma:1610
model WorkflowsOnRoutingForms {
  workflowId    Int
  routingFormId String
  workflow      Workflow
  routingForm   App_RoutingForms_Form
}
```

Workflows can trigger when routing forms are submitted.

## Workflow Reminders

```typescript theme={null}
// From schema.prisma:1652
model WorkflowReminder {
  id              Int      @id
  bookingUid      String
  booking         Booking
  workflowStepId  Int
  workflowStep    WorkflowStep
  method          String   // EMAIL, SMS, WHATSAPP
  scheduled       Boolean  // Has been scheduled
  scheduledDate   DateTime // When to send
  referenceId     String?  // External reference (e.g., email ID)
}
```

When a booking is created, workflow reminders are scheduled based on the trigger time.

<Note>
  Reminders are stored in the database and executed by a background job at the scheduled time.
</Note>

## Common Workflow Examples

### 24-Hour Reminder

```typescript theme={null}
{
  name: "24 Hour Reminder",
  trigger: "BEFORE_EVENT",
  time: 24,
  timeUnit: "HOUR",
  steps: [
    {
      action: "EMAIL_ATTENDEE",
      template: "REMINDER",
      emailSubject: "Reminder: {event_name} tomorrow",
      reminderBody: `Hi {attendee_first_name},\n\nYour meeting "{event_name}" is scheduled for tomorrow at {event_time}.\n\nJoin here: {meeting_url}`,
      includeCalendarEvent: true
    }
  ]
}
```

### Booking Confirmation

```typescript theme={null}
{
  name: "Booking Confirmed",
  trigger: "NEW_EVENT",
  time: null,
  timeUnit: null,
  steps: [
    {
      action: "EMAIL_ATTENDEE",
      template: "CUSTOM",
      emailSubject: "Booking Confirmed: {event_name}",
      reminderBody: `Thank you for booking!\n\nDetails:\n- Event: {event_name}\n- Date: {event_date}\n- Time: {event_time}\n- Location: {location}\n\nNeed to reschedule? {reschedule_url}`,
      includeCalendarEvent: true
    },
    {
      action: "EMAIL_HOST",
      template: "CUSTOM",
      emailSubject: "New Booking: {event_name}",
      reminderBody: `New booking from {attendee_name}\n\nScheduled for {event_date} at {event_time}`
    }
  ]
}
```

### Follow-Up After Meeting

```typescript theme={null}
{
  name: "Post-Meeting Follow-Up",
  trigger: "AFTER_EVENT",
  time: 1,
  timeUnit: "HOUR",
  steps: [
    {
      action: "EMAIL_ATTENDEE",
      template: "RATING",
      emailSubject: "How was your meeting?",
      reminderBody: `Hi {attendee_first_name},\n\nThank you for meeting with us!\n\nWe'd love your feedback: {rating_url}`
    }
  ]
}
```

### SMS Reminder

```typescript theme={null}
{
  name: "SMS 1 Hour Before",
  trigger: "BEFORE_EVENT",
  time: 1,
  timeUnit: "HOUR",
  steps: [
    {
      action: "SMS_ATTENDEE",
      template: "REMINDER",
      reminderBody: "Reminder: {event_name} starts in 1 hour. Join: {meeting_url}",
      numberRequired: true
    }
  ]
}
```

### Multi-Channel Reminder

```typescript theme={null}
{
  name: "Multi-Channel Reminder",
  trigger: "BEFORE_EVENT",
  time: 2,
  timeUnit: "HOUR",
  steps: [
    {
      action: "EMAIL_ATTENDEE",
      template: "REMINDER",
      emailSubject: "Starting soon: {event_name}",
      reminderBody: "Your meeting starts in 2 hours."
    },
    {
      action: "SMS_ATTENDEE",
      template: "REMINDER",
      reminderBody: "{event_name} in 2 hours. Join: {meeting_url}"
    },
    {
      action: "WHATSAPP_ATTENDEE",
      template: "REMINDER",
      reminderBody: "Reminder: {event_name} at {event_time}"
    }
  ]
}
```

## Best Practices

<CardGroup cols={2}>
  <Card title="Don't Over-Notify" icon="bell-slash">
    Too many reminders can annoy attendees. One 24-hour reminder is usually sufficient.
  </Card>

  <Card title="Use Clear Subject Lines" icon="heading">
    Make email subjects descriptive with dynamic variables
  </Card>

  <Card title="Include Action Links" icon="link">
    Always provide reschedule/cancel links in reminders
  </Card>

  <Card title="Test Your Workflows" icon="flask">
    Create a test booking to verify workflow messages before going live
  </Card>
</CardGroup>

## Advanced Features

### Auto-Translation

```typescript theme={null}
// From WorkflowStep schema.prisma:1549-1550
{
  autoTranslateEnabled: true,
  sourceLocale: "en"  // Translate from English to attendee's locale
}
```

### Time Unit Options

```typescript theme={null}
// From constants.ts:31
enum TimeUnit {
  MINUTE  // For very short reminders
  HOUR    // Most common
  DAY     // For advance reminders
}
```

### Workflow Types

```typescript theme={null}
enum WorkflowType {
  EVENT_TYPE    // Standard booking workflows
  ROUTING_FORM  // Routing form workflows
}
```

## Troubleshooting

### Workflow Not Triggering

1. **Check activation**: Verify workflow is assigned to the event type
2. **Review trigger conditions**: Ensure booking meets trigger criteria
3. **Check timing**: For time-based triggers, verify the scheduled time
4. **Verify workflow is active**: Workflows can be disabled

### Reminders Not Sent

1. **Check WorkflowReminder records**: Verify reminders were created
2. **Review scheduled date**: Ensure it's in the future
3. **Check email deliverability**: Emails might be in spam
4. **Verify phone numbers**: For SMS, ensure number is verified

## Related Features

* [Event Types](/features/event-types) - Assign workflows to event types
* [Bookings](/features/bookings) - Workflows trigger on booking events
* [Routing Forms](/features/routing-forms) - Workflows for form submissions
