# Rules

Webhooks push every completed analysis. **Rules** push only when signal values
cross a line you care about, and take an action: an email, a Slack message or
a webhook.

```json
{
  "name": "scammer alert",
  "when": "is_scammer >= 90 and trust_score < 1",
  "action_type": "slack",
  "action_config": { "webhook_url": "https://hooks.slack.com/services/T000/B000/XXXX" },
  "cooldown_seconds": 3600
}
```

cURL:

```bash
curl -X POST "$API/v1/rules?api_key=$ANALYZE_API_KEY" \
  -H "Authorization: Bearer $(sign)" -H 'Content-Type: application/json' \
  -d '{"name":"scammer alert","when":"is_scammer >= 90",
       "action_type":"email","action_config":{"to":"trust@acme.com"}}'
```

Node.js:

```ts
await analyze.rules.create({
  name: "scammer alert",
  when: "is_scammer >= 90",
  action_type: "email",
  action_config: { to: "trust@acme.com" },
});
```

Python:

```python
analyze.rules.create(
    name="scammer alert",
    when="is_scammer >= 90",
    action_type="email",
    action_config={"to": "trust@acme.com"},
)
```

## Conditions

`when` uses the [search and conditions](https://sigwise.ai/docs/guides/queries.md) language: noul values
are percentages (`>= 90`), scores are raw (`trust_score < 1`), and choices
compare with `=` or `!=` (`buyer_intent = ready_to_buy`). Conditions are
validated against your signals when you create or update the rule.

## Actions

| `action_type` | `action_config` | Does |
|---------------|-----------------|------|
| `email` | `{"to": "trust@acme.com", "subject": "…"}` (`subject` optional) | Sends an alert email. |
| `slack` | `{"webhook_url": "https://hooks.slack.com/…"}` | Posts to a Slack incoming webhook. |
| `webhook` | `{"endpoint_id": ""}` | Sends `rule.triggered` to one of your [webhook endpoints](https://sigwise.ai/docs/guides/webhooks.md), with the same signing, retries and dead-letter queue. The endpoint must be subscribed to `rule.triggered`; subscribe it to only that event to receive rule firings without every analysis. |

## When a rule fires

Rules are evaluated after every analysis, asynchronous or
[direct](https://sigwise.ai/docs/guides/moderation.md), against the new answers.

- A rule fires when its condition **turns true** for an object, and does not
  fire again while it stays true.
- With `cooldown_seconds` above 0, it may fire again once that long has passed
  since it last fired, if the condition is still true.
- It fires again after the condition has been false in between.

This is tracked per rule and object.

## Audit

Every firing is recorded with the condition, the signal values that satisfied
it and the action's outcome (`dispatched` or `error`):

```bash
curl "$API/v1/rule_firings?rule_id=$RULE_ID&api_key=$ANALYZE_API_KEY" -H "Authorization: Bearer $(sign)"
```

Pause a rule with `PATCH /v1/rules/{rule_id}` and `{"enabled": false}`, and
remove it with `DELETE`.
