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

# Triggers

> Event-driven automation that fires actions in response to customer events and data changes.

<Note>
  **See also**: [Triggers REST API reference](/api-reference/triggers) for request/response shapes, status codes, and error semantics.
</Note>

## Overview

**Triggers** enable event-driven automation in KaireonAI. When a customer event occurs -- a transaction, a profile update, a behavioral signal -- a trigger can automatically enroll the customer in a journey, fire a real-time recommendation, call an external webhook, or update customer attributes.

## How Triggers Work

```
Event Source → Trigger Rule → Condition Evaluation → Action Execution
```

1. An **event** arrives from a connected data source (streaming connector, API call, or schema update)
2. The **trigger rule** matches events by type and optional filters
3. **Conditions** are evaluated to determine if the trigger should fire
4. The configured **action** is executed

### Runtime Behavior

When an event is received, the engine performs the following sequence:

1. **Event matching** -- All active trigger rules with a matching `eventType` are retrieved, ordered by `priority` (descending).
2. **Condition evaluation** -- For each matching trigger, the `condition` object is evaluated against the event payload. Conditions support nested `all` (AND) and `any` (OR) groups with field-level operators (`eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `exists`).
3. **Cooldown check** -- If the trigger has a `cooldownMs` value greater than zero, the engine checks whether the same trigger has already fired for this customer within the cooldown window. If it has, the trigger is skipped.
4. **Action dispatch** -- If all conditions pass and the cooldown has not been exceeded, the configured action is dispatched (journey enrollment, recommend call, webhook POST, or attribute update).
5. **Audit logging** -- Every trigger firing is recorded in the audit log with the trigger ID, customer ID, event type, and action taken.

<Info>
  Multiple triggers can match the same event. They are evaluated in priority order, and each fires independently as long as its own conditions and cooldown are satisfied.
</Info>

## Event Types

Triggers listen for events from your connected data sources:

| Event Type          | Description                                                                 |
| ------------------- | --------------------------------------------------------------------------- |
| `outcome.recorded`  | An outcome (impression, click, conversion) was recorded via the Respond API |
| `customer.created`  | A new customer record was inserted into a schema table                      |
| `customer.updated`  | An existing customer record was modified                                    |
| `segment.entered`   | A customer entered a segment (met the segment criteria)                     |
| `segment.exited`    | A customer exited a segment (no longer meets criteria)                      |
| `journey.completed` | A customer completed a journey                                              |
| `offer.expired`     | An offer reached its end date                                               |
| `budget.exhausted`  | An offer's budget allocation was fully consumed                             |

## Action Types

| Action Type        | Description                                                    |
| ------------------ | -------------------------------------------------------------- |
| `enroll_journey`   | Enroll the customer in a specified [journey](/studio/journeys) |
| `fire_recommend`   | Execute a Decision Flow and deliver the result immediately     |
| `webhook`          | Send an HTTP POST to an external URL with event data           |
| `update_attribute` | Update one or more customer attributes in a schema table       |

### enroll\_journey

```json theme={null}
{
  "actionType": "enroll_journey",
  "config": {
    "journeyId": "jrn_loan_nurture",
    "deduplication": "skip_if_active"
  }
}
```

<Info>
  The `deduplication` option prevents enrolling a customer who is already active in the same journey. Options: `skip_if_active` (default), `restart`, `allow_multiple`.
</Info>

### fire\_recommend

```json theme={null}
{
  "actionType": "fire_recommend",
  "config": {
    "decisionFlowId": "df_realtime_offers",
    "channelId": "ch_push",
    "limit": 1,
    "deliverImmediately": true
  }
}
```

### webhook

```json theme={null}
{
  "actionType": "webhook",
  "config": {
    "url": "https://api.yourcompany.com/events/handle",
    "method": "POST",
    "headers": {
      "Authorization": "Bearer {{secret.webhook_token}}"
    },
    "bodyTemplate": {
      "customerId": "{{event.customerId}}",
      "eventType": "{{event.type}}",
      "triggerId": "{{trigger.id}}"
    }
  }
}
```

### update\_attribute

```json theme={null}
{
  "actionType": "update_attribute",
  "config": {
    "schemaId": "schema_customer_profile",
    "updates": [
      { "field": "last_event_date", "value": "{{event.timestamp}}" },
      { "field": "event_count", "expression": "event_count + 1" }
    ]
  }
}
```

## Cooldown Mechanics

Each trigger has a configurable **cooldown period** (`cooldownMs`, in milliseconds) to prevent rapid re-firing for the same customer.

**How cooldown works:**

1. When a trigger fires for a customer, the engine records the firing timestamp.
2. On the next matching event for the same customer, the engine checks if `now - lastFiredAt < cooldownMs`.
3. If the cooldown has not elapsed, the trigger is silently skipped for that customer. The event is not queued for later -- it is dropped.
4. The cooldown is per-customer, per-trigger. Customer A's cooldown does not affect Customer B.

| Cooldown Value     | Behavior                                   |
| ------------------ | ------------------------------------------ |
| `0`                | No cooldown; fires on every matching event |
| `60000` (1 min)    | At most once per minute per customer       |
| `3600000` (1 hr)   | At most once per hour per customer         |
| `86400000` (24 hr) | At most once per day per customer          |

<Warning>
  Without a cooldown, high-frequency events (e.g., page views, transaction streams) can cause a trigger to fire hundreds of times per customer. Always set an appropriate cooldown.
</Warning>

## Priority

When multiple triggers match the same event, they are executed in priority order:

| Priority | Value Range | Description                        |
| -------- | ----------- | ---------------------------------- |
| Critical | 90-100      | Compliance and regulatory triggers |
| High     | 70-89       | Revenue-critical automations       |
| Medium   | 40-69       | Standard engagement triggers       |
| Low      | 1-39        | Background/informational triggers  |

## Worked Example

A retail bank wants to trigger a real-time recommendation whenever a customer completes a purchase over \$500:

<Steps>
  <Step title="Event arrives">
    The Respond API records an `outcome.recorded` event for customer `cust_78` with `outcomeType: "conversion"` and `metadata.amount: 750`.
  </Step>

  <Step title="Trigger matches">
    The engine finds the "High-Value Purchase" trigger with `eventType: "outcome.recorded"` and `priority: 75`.
  </Step>

  <Step title="Condition evaluates">
    The trigger's condition is checked: `{ "all": [{ "field": "metadata.amount", "operator": "gt", "value": 500 }] }`. The event's amount (750) is greater than 500, so the condition passes.
  </Step>

  <Step title="Cooldown check">
    The trigger has `cooldownMs: 86400000` (24 hours). The last firing for `cust_78` was 3 days ago, so the cooldown has elapsed.
  </Step>

  <Step title="Action dispatches">
    The `fire_recommend` action executes Decision Flow `df_cross_sell` with `channelId: "ch_push"` and `maxOffers: 1`. The customer receives a personalized push notification with a cross-sell offer.
  </Step>
</Steps>

## Field Reference

| Field          | Type   | Required | Default  | Description                                                               |
| -------------- | ------ | -------- | -------- | ------------------------------------------------------------------------- |
| `name`         | string | Yes      | --       | Trigger name (min 1 character)                                            |
| `description`  | string | No       | `""`     | Human-readable description                                                |
| `eventType`    | string | Yes      | --       | Event type to listen for (see Event Types table)                          |
| `condition`    | object | No       | `{}`     | Nested condition groups with `all`/`any` logic and field-level operators  |
| `actionType`   | enum   | Yes      | --       | One of: `enroll_journey`, `fire_recommend`, `webhook`, `update_attribute` |
| `actionConfig` | object | No       | `{}`     | Action-specific configuration (see Action Types section)                  |
| `priority`     | number | No       | `50`     | Execution priority (0-100, higher = first)                                |
| `cooldownMs`   | number | No       | `0`      | Minimum milliseconds between firings for the same customer                |
| `status`       | enum   | Auto     | `active` | Trigger status: `active`, `paused`, `disabled`                            |

### Condition Operators

| Operator | Description           | Example                                                                |
| -------- | --------------------- | ---------------------------------------------------------------------- |
| `eq`     | Equals                | `{ "field": "eventType", "operator": "eq", "value": "conversion" }`    |
| `neq`    | Not equals            | `{ "field": "channel", "operator": "neq", "value": "sms" }`            |
| `gt`     | Greater than          | `{ "field": "amount", "operator": "gt", "value": 500 }`                |
| `gte`    | Greater than or equal | `{ "field": "score", "operator": "gte", "value": 0.8 }`                |
| `lt`     | Less than             | `{ "field": "age", "operator": "lt", "value": 30 }`                    |
| `lte`    | Less than or equal    | `{ "field": "count", "operator": "lte", "value": 5 }`                  |
| `in`     | Value in list         | `{ "field": "tier", "operator": "in", "value": ["gold", "platinum"] }` |
| `exists` | Field exists          | `{ "field": "email", "operator": "exists" }`                           |

## Creating a Trigger

<Steps>
  <Step title="Navigate to Triggers">
    Go to **Studio > Triggers** in the sidebar.
  </Step>

  <Step title="Click Create Trigger">
    Click the **+ New Trigger** button.
  </Step>

  <Step title="Name and describe">
    Enter a name and description for the trigger.
  </Step>

  <Step title="Select event type">
    Choose the event type that will activate this trigger.
  </Step>

  <Step title="Define conditions (optional)">
    Add filter conditions to narrow when the trigger fires (e.g., `metadata.amount > 500`).
  </Step>

  <Step title="Select action type">
    Choose the action: enroll in journey, fire recommendation, call webhook, or update attribute.
  </Step>

  <Step title="Configure action">
    Fill in the action-specific configuration (journey ID, Decision Flow, webhook URL, etc.).
  </Step>

  <Step title="Set cooldown and priority">
    Configure the cooldown period and execution priority.
  </Step>

  <Step title="Save and enable">
    Save the trigger. Toggle it to **enabled** when ready.
  </Step>
</Steps>

## API Reference

### Create a Trigger

```bash theme={null}
POST /api/v1/triggers
Content-Type: application/json
```

**Request body:**

```json theme={null}
{
  "name": "High-Value Purchase Cross-Sell",
  "description": "Fire real-time recommendation after a purchase over $500",
  "eventType": "outcome.recorded",
  "condition": {
    "all": [
      { "field": "metadata.amount", "operator": "gt", "value": 500 },
      { "field": "outcomeType", "operator": "eq", "value": "conversion" }
    ]
  },
  "actionType": "fire_recommend",
  "actionConfig": {
    "decisionFlowId": "df_cross_sell",
    "channelId": "ch_push",
    "limit": 1,
    "deliverImmediately": true
  },
  "cooldownMs": 86400000,
  "priority": 75
}
```

**Response (201 Created):**

```json theme={null}
{
  "id": "trg_high_value_purchase",
  "name": "High-Value Purchase Cross-Sell",
  "eventType": "outcome.recorded",
  "actionType": "fire_recommend",
  "cooldownMs": 86400000,
  "priority": 75,
  "status": "active",
  "createdAt": "2026-03-10T14:30:00Z",
  "updatedAt": "2026-03-10T14:30:00Z"
}
```

### List Triggers

```bash theme={null}
GET /api/v1/triggers?status=active&eventType=outcome.recorded&limit=50&offset=0
```

**Query parameters:**

| Parameter   | Type   | Default | Description              |
| ----------- | ------ | ------- | ------------------------ |
| `status`    | string | all     | Filter by trigger status |
| `eventType` | string | all     | Filter by event type     |
| `limit`     | number | 50      | Page size (max 200)      |
| `offset`    | number | 0       | Pagination offset        |

### Update a Trigger

```bash theme={null}
PUT /api/v1/triggers/:id
```

### Delete a Trigger

```bash theme={null}
DELETE /api/v1/triggers/:id
```

### Enable/Disable a Trigger

Use the update endpoint to change a trigger's status:

```bash theme={null}
PUT /api/v1/triggers/:id
Content-Type: application/json

{ "status": "paused" }
```

Allowed status transitions: `active` to `paused` or `disabled`, `paused` to `active` or `disabled`, `disabled` to `active`.

## Next Steps

<CardGroup cols={2}>
  <Card title="Journeys" icon="route" href="/studio/journeys">
    Build multi-step workflows that triggers can enroll customers into.
  </Card>

  <Card title="Runs" icon="play" href="/operations-reporting/runs">
    Execute Decision Flows in batch for campaign delivery.
  </Card>
</CardGroup>
