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

# Triggers vs Alerts

> Triggers run work on a schedule. Alerts watch for a condition and tell you. Which one you want, and where the seam is.

A **trigger** runs work. An **alert** watches and tells you.

Both are configured per namespace and both can end in a Slack message, which is why they get confused.

## Which one do I want

| You want to | Use |
| - | - |
| Re-cluster a collection every night | Trigger |
| Re-run enrichment after a taxonomy changes | Trigger |
| Re-process a batch that failed | Trigger |
| Know when a search starts returning nothing | Alert |
| Know when a search starts returning too much | Alert |
| Get a Slack message when a data-plane condition is met | Alert |

The short test: if the outcome is **work that happened**, you want a trigger. If the outcome is **someone finding out**, you want an alert.

## Triggers

A trigger is a schedule plus an action.

| `trigger_type` | Fires |
| - | - |
| `cron` | On a cron expression |
| `interval` | Every N seconds |
| `event` | When a named event occurs |
| `conditional` | When a condition evaluates true |

| `action_type` | Runs |
| - | - |
| `cluster` | Clustering over a collection |
| `taxonomy_enrichment` | Taxonomy enrichment |
| `batch_rerun` | A batch again |
| `collection_trigger` | A collection's processing |

```bash cURL theme={null}
curl -X POST https://api.mixpeek.com/v1/triggers \
  -H "Authorization: Bearer YOUR_MIXPEEK_API_KEY" \
  -H "X-Namespace: ns_your_namespace_id" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "nightly recluster",
    "trigger_type": "cron",
    "schedule_config": {"cron": "0 3 * * *"},
    "action_type": "cluster",
    "action_config": {"collection_id": "col_your_collection_id"}
  }'
```

A trigger's output is its run history. Read it to see what ran and what failed.

## Alerts

An alert is a source plus a condition plus somewhere to send the news.

| `source` | Watches |
| - | - |
| `retriever` | A retriever's results. Set `trigger_on` to `results` or `no_results` |
| `system` | A built-in data-plane condition, via `system_condition` |

`notification_config.channels` takes one or more of `webhook`, `slack`, and `email`.

```bash cURL theme={null}
curl -X POST https://api.mixpeek.com/v1/alerts \
  -H "Authorization: Bearer YOUR_MIXPEEK_API_KEY" \
  -H "X-Namespace: ns_your_namespace_id" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "search returning nothing",
    "source": "retriever",
    "retriever_id": "ret_your_retriever_id",
    "trigger_on": "no_results",
    "notification_config": {
      "channels": [
        {"channel_type": "slack", "config": {"webhook_url": "https://hooks.slack.com/..."}}
      ]
    }
  }'
```

## The seam worth knowing about

`execution_mode` takes `on_ingest`, `scheduled`, or `on_demand`.

<Warning>
  **`scheduled` does not run today.** The name implies a trigger drives the alert on a schedule, and no trigger action executes an alert. An alert set to `scheduled` is accepted and never fires.

  Use `on_ingest`, which evaluates the alert as data arrives, or `on_demand` and call it yourself.
</Warning>

`on_ingest` is what most alerts want. It rides the ingestion pipeline, so the alert is evaluated against data at the moment that data lands.

## Related

<CardGroup cols={2}>
  <Card title="Webhooks" icon="webhook" href="/docs/operations/webhooks">
    Where an alert's `webhook` channel delivers.
  </Card>

  <Card title="Change feed" icon="rss" href="/docs/operations/change-feed">
    Reading what changed, rather than being told.
  </Card>
</CardGroup>
