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

# Building Journeys

> Create your first welcome journey step by step

This guide walks through creating a welcome journey from scratch.

## Step 1: Create the Journey

1. Navigate to **Journeys**
2. Click **New Journey**
3. Enter a name: "Welcome Series - Main List"

## Step 2: Configure Triggers

Triggers define when contacts enter the journey.

### Trigger Type: List Membership

The most common trigger—enter when joining a list:

```
Trigger: Contact added to list
List: Main Marketing List
```

### Trigger Type: Custom Field

Enter based on a field value. The `operator` field is required:

```yaml theme={null}
Trigger: Custom field matches
Field: signup_source
Operator: eq
Value: "website"
```

Valid operators for custom field triggers:

| Operator   | Meaning                     |
| ---------- | --------------------------- |
| `eq`       | Equals                      |
| `ne`       | Not equals                  |
| `in`       | Value is in a list          |
| `not_in`   | Value is not in a list      |
| `exists`   | Field exists on the contact |
| `contains` | Field contains substring    |

### Multiple Triggers

Triggers are organized using a `JourneyTriggerGroup` structure that supports nested logic:

```yaml theme={null}
TriggerGroup:
  operator: AND          # AND or OR
  conditions:
    - type: list
      list_id: "main_marketing_list"
    - type: custom_field
      field: signup_source
      operator: eq
      value: "website"
  groups:                # Optional nested groups
    - operator: OR
      conditions:
        - type: custom_field
          field: referral_source
          operator: eq
          value: "partner_a"
        - type: custom_field
          field: referral_source
          operator: eq
          value: "partner_b"
```

Each `JourneyTriggerGroup` has:

* **`operator`**: `AND` or `OR` — how to combine the conditions and nested groups
* **`conditions`**: Array of individual trigger conditions
* **`groups`**: Optional array of nested `JourneyTriggerGroup` objects for complex logic

Only contacts matching the full trigger group will enter the journey.

## Step 3: Add Steps

Click **Add Step** to add each journey step.

### Send Message Step

Deliver a message:

1. Click **Add Step > Send Message**
2. Select a creative or define an inline message
3. Optionally select an offer binding

```yaml theme={null}
Step: Send Message
Creative: "Welcome - 10% Off"
Offer: welcome_discount
```

You can also define messages inline directly in the step instead of referencing an existing creative:

```yaml theme={null}
Step: Send Message
Inline Message:
  body: "Welcome to {{brand_name}}! Use code WELCOME10 for 10% off: {{link1}}"
```

Inline messages support the same template variables as creatives (`{{brand_name}}`, `{{linkN}}`).

### Wait Step

Pause before the next step:

1. Click **Add Step > Wait**
2. Set duration and unit

```yaml theme={null}
Step: Wait
Duration: 24
Unit: hours
```

### Condition Step

Branch based on behavior:

1. Click **Add Step > Condition**
2. Configure the condition
3. Define Yes and No branches

```yaml theme={null}
Step: Condition
Type: Has Clicked (any)

Yes branch: → Go to step 5
No branch: → Go to step 6
```

Click conditions count clicks on messages this journey sent during the current enrollment. (Rolling out now — until condition evaluation is enabled for your account, every condition takes the No branch.)

### Wait Until Step

Wait until a specific time of day before proceeding:

1. Click **Add Step > Wait Until**
2. Set the target time (HH:MM)

```yaml theme={null}
Step: Wait Until
Time: "09:00"
```

This is different from a regular wait step, which pauses for a duration. `wait_until` holds the contact until the next occurrence of the specified time (e.g., 9:00 AM).

### Set Custom Field Step

Set a custom field value on the contact's ListContact record:

1. Click **Add Step > Set Custom Field**
2. Specify the field key and value

```yaml theme={null}
Step: Set Custom Field
Field: onboarding_stage
Value: "completed_welcome"
```

Use this to tag contacts as they progress, enabling audience segmentation and trigger conditions in other journeys.

### Unsubscribe Step

Unsubscribe the contact from the list:

1. Click **Add Step > Unsubscribe**

```yaml theme={null}
Step: Unsubscribe
```

The contact will be unsubscribed from the sending list associated with the journey. Use this at the end of a branch when a contact should no longer receive messages.

### Exit Step

End the journey:

1. Click **Add Step > Exit**

```yaml theme={null}
Step: Exit
```

## Step 4: Connect Steps

Steps flow sequentially by default. Use conditions to create branches.

### Linear Flow

```
Step 1 (Send) → Step 2 (Wait) → Step 3 (Send) → Step 4 (Exit)
```

### Branching Flow

```
Step 1 (Send)
    ↓
Step 2 (Wait 2 days)
    ↓
Step 3 (Condition: Clicked?)
   ↓ Yes        ↓ No
Step 4 (Exit)  Step 5 (Send reminder)
                    ↓
               Step 6 (Exit)
```

## Step 5: Review and Activate

### Preview

Before activating:

1. Click **Preview**
2. Review the flow visually
3. Check trigger conditions
4. Verify creatives are correct

### Activate

1. Click **Activate**
2. Journey starts enrolling new matching contacts
3. Existing contacts are NOT enrolled (only new matches)

<Warning>
  Activating a journey is immediate. Make sure everything is configured correctly.
</Warning>

## Example: Simple Welcome Series

Let's build a 3-message welcome:

<Steps>
  <Step title="Create journey">
    Name: "Simple Welcome Series"
  </Step>

  <Step title="Set trigger">
    List: Main Marketing List
  </Step>

  <Step title="Step 1: Send welcome">
    Creative: "Welcome! Here's 10% off your first order."
  </Step>

  <Step title="Step 2: Wait 24 hours">
    Duration: 24 hours
  </Step>

  <Step title="Step 3: Send bestsellers">
    Creative: "Check out our bestsellers"
  </Step>

  <Step title="Step 4: Wait 3 days">
    Duration: 3 days
  </Step>

  <Step title="Step 5: Send offer">
    Creative: "Last chance: 15% off expires today"
  </Step>

  <Step title="Step 6: Exit">
    End the journey
  </Step>

  <Step title="Activate">
    Turn on the journey
  </Step>
</Steps>

## Editing Active Journeys

You can edit active journeys, but be careful:

| Change          | Effect                                          |
| --------------- | ----------------------------------------------- |
| Add step at end | Safe - affects future enrollees                 |
| Change creative | Affects enrollees who haven't reached that step |
| Change timing   | Affects future waits, not in-progress waits     |
| Change trigger  | Only affects new enrollments                    |
| Delete step     | ⚠️ May break in-progress enrollments            |

<Tip>
  For major changes, create a new journey version and sunset the old one.
</Tip>

## Monitoring Journeys

### Enrollment Stats

View in the journey dashboard:

* Total enrollments
* Active enrollments (in progress)
* Completed
* Exited early

### Step Performance

See metrics per step:

* How many reached this step
* Conversion to next step
* Drop-off rate

## Troubleshooting

<AccordionGroup>
  <Accordion title="Contacts not entering">
    Check:

    * Is the journey active?
    * Do contacts match trigger conditions?
    * Are they already actively enrolled (one active enrollment per journey per list membership)?
  </Accordion>

  <Accordion title="Messages not sending">
    Check:

    * Is the contact still subscribed?
    * Is the creative active?
    * Are there sending list issues?
  </Accordion>

  <Accordion title="Stuck in wait step">
    Wait steps process on schedule. Check:

    * Is the job server running?
    * Is `next_step_at` set correctly?
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Conditions" icon="code-branch" href="/guides/journeys/conditions">
    Add branching logic
  </Card>

  <Card title="Wait Steps" icon="clock" href="/guides/journeys/waits">
    Timing best practices
  </Card>
</CardGroup>
