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

# Automation triggers

> The seven ways a contact can enter an automation — list joins, segment changes, API events, schedules, email engagement, form submissions and website events.

Each automation has exactly one trigger. It decides which contacts enter and when. To add one, drag it from the **Triggers** section of the **Step palette** onto the canvas, then click it to set it up.

Every trigger enters only contacts whose status is **Active**. A new form signup who hasn't confirmed double opt-in yet is held back and enters the form's journeys when they click the confirmation link, with what they submitted available as trigger data. **Send Email** steps never mail a contact who is unsubscribed, bounced, complained or unconfirmed. They skip that contact and record the reason in **Logs**. The exception is a step that uses a **Transactional** send policy, which can still mail unsubscribed contacts. **Enrollment frequency** in the journey settings decides whether a contact can enter more than once (see [Automations](/guides/audience-and-campaigns/automations#journey-settings)).

| Trigger                   | Starts the journey when…                                               | Timing                    |
| ------------------------- | ---------------------------------------------------------------------- | ------------------------- |
| **Contact Added to List** | a contact is added to a list                                           | immediately               |
| **Segment Change**        | a contact enters or leaves a segment                                   | checked every few minutes |
| **API Event**             | your system calls the journey trigger API, or records a matching event | immediately               |
| **Schedule**              | a date or time you set arrives                                         | at the scheduled time     |
| **Email Engagement**      | contacts in an audience opened, clicked or didn't open                 | checked every few minutes |
| **Form Submission**       | someone submits a signup form                                          | immediately               |
| **Website Event**         | an identified visitor fires a tracked event on your site               | immediately               |

## Contact Added to List

Choose a **Contact list**. Only contacts added to the list after you activate the journey enter. People already on the list at that point don't. With double opt-in on, a new subscriber enters after they confirm. See [Lists](/guides/audience-and-campaigns/lists).

## Segment Change

Choose a **Segment**, then an **Event**: **Entered segment** or **Exited segment**. When you activate the journey, InstantCampaign records who is in the segment at that moment. Those people don't enter. From then on, only contacts who join (or leave) the segment enter. See [Segments](/guides/audience-and-campaigns/segments).

## API Event

Use this trigger to start a journey from your own backend, for example after an order or a signup in your app.

<Steps>
  <Step title="Name the event">
    Enter an **Event name**, for example `purchase`. The name is a label, and it is also the event name that starts this journey when you record custom events.
  </Step>

  <Step title="Activate the journey">
    A unique **Trigger key** is created when you activate. The trigger panel then shows the endpoint, the request format, and cURL and JavaScript examples, with **Copy trigger key** and **Copy full URL** buttons.
  </Step>

  <Step title="Call it">
    Send a request with two headers: your API key (`Authorization: Bearer …`, from **Settings → API Keys**) and the journey's key (`X-Trigger-Key`). Both must belong to the same workspace. The body needs the contact's `email`. You can also send a `data` object.
  </Step>
</Steps>

```json theme={null}
{ "email": "contact@example.com", "data": { "orderId": "ORD-123", "amount": 99.99, "plan": "pro" } }
```

The email must match an existing, active contact, and that contact enters: there's no audience to pick for this trigger. To act on only some of the contacts your system sends, add an **If/Else Condition** after the trigger. Everything in `data` is available to later steps. In email subjects and bodies, write Liquid such as `{{ data.orderId }}`. In **If/Else Condition** steps, use **Payload value (data.\*)**.

A journey with this trigger also starts when you record a custom event with the same name through the events API. See [Events and goals](/guides/audience-and-campaigns/events-and-goals) and the [API reference](/api-reference/introduction).

<Warning>
  Keep the trigger key secret. The API key is required too, so a leaked trigger key can't be used on its own.
</Warning>

## Schedule

Choose who enters under **Audience source**: a **Segment** or a **Contact list** (only active list subscribers). Then pick a **Schedule type**:

* **Recurring (daily/weekly)**: set **Frequency** to **Daily**, **Weekly** (with a **Day of week**) or **Monthly** (with a **Day of month**, 1–28, so that every month has the day, February included).
* **Based on contact date field**: enter a **Date field**, for example `birthday` or `renewal_date`. The box suggests the built-in dates and your **Date** [custom fields](/guides/audience-and-campaigns/custom-fields). A contact enters on the day the month and day of their date match today, every year. The name is looked up in this order, and the next place is tried when a contact has no value in the one before:

  1. a built-in date: `birthday`, `createdAt`, `subscribedAt` or `lastActivityAt`
  2. the custom field with that key
  3. the key in the contact's `metadata` (set through the contacts API or by an **Update Contact** step)

  To read only one place, write `customField.renewal_date` or `metadata.renewal_date`. Store dates as `YYYY-MM-DD`.
* **One-time on specific date**: pick a **Date**. The audience enters once and never again.

Set the **Send time** and **Timezone**. The time is read in the timezone you choose. With recurring and date-field schedules, a contact can enter again once their previous run has finished.

## Email Engagement

Choose an **Audience source** (segment or list) and an **Engagement type**: **Opened email**, **Clicked link** or **Did not open**. You can also limit it to one campaign with **Campaign (optional)**. Leave that blank for **Any campaign**. Contacts in the audience who match enter the journey.

<Tip>
  Engagement triggers work well with **Once** enrollment. For example, use **Did not open** plus a specific campaign to send a single follow-up.
</Tip>

## Form Submission

Choose a **Form**. Only active forms are listed. The journey starts as soon as someone submits the form. The answers are available as `data`, under a name made from each field's label: `{{ data.email }}` for the email address, `{{ data.company }}` for a field labelled "Company", `{{ data.first_name }}` for "First name". The form editor shows each field's name under it. A field labelled "First name" or "Name" also fills in the contact's `{{ first_name }}`. See [Signup forms](/guides/audience-and-campaigns/signup-forms#fields).

## Website Event

Enter the **Event name** your site sends, for example `page_view` or `button_click`. The journey starts when a visitor who has been identified by email fires that event through the InstantCampaign tracking snippet:

```html theme={null}
<script src="https://YOUR-APP-HOST/track.js" data-site-id="ict_xxx"></script>
<script>
  ICTrack.identify("user@example.com");
  ICTrack.event("your_event_name", { plan: "pro", amount: 99 });
</script>
```

`ICTrack.identify()` must run on the same page, before the event: the snippet stores nothing between pages. Get the `ict_…` tracking token under **Settings → Tracking Tokens**. The event's properties are available to later steps as `data`, and the event itself as `event` (for example `{{ event.name }}`). An event with the same name recorded from your server through the events API also starts this journey.

<Note>
  The snippet uses a tracking token in `data-site-id` (from **Settings → Tracking Tokens**). A tracking token can only send events, so it's safe to put on a public web page. Never put an API key on a web page.
</Note>

## Troubleshooting

* **API call returns "Contact not found"**: create the contact first, for example through the contacts API. The trigger doesn't create contacts.
* **API call returns an enrollment error**: the journey's **Enrollment frequency** doesn't allow this contact to enter again. With **Multiple times**, it also means the contact is still in the journey.
* **API call returns "Journey is not active"**: activate the journey, or call the trigger key of the version that's live now.
* **A birthday journey never fires**: check that the **Date field** is spelled exactly like the custom field's key (or the metadata key), that the dates are stored as `YYYY-MM-DD`, and that the **Timezone** matches your audience.
* **Nobody entered a Segment Change journey right after activation**: this is expected. People already in the segment when you activate don't count as a change.
