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

# Rule suggestions

> Produce AI-suggested match rules, review them in a human-in-the-loop queue, and approve or reject each candidate before any rule is created.

Matcher can propose config-only match rules from a context's history using AI — but **AI output is never authoritative**. Producing a suggestion creates no rule; a rule is created only when a human approves a suggestion. This guide covers the human-in-the-loop (HITL) rule-suggestion queue.

<Note>The lane is gated by a global advisor kill-switch **and** a per-tenant opt-in (fail-closed: a non-opted-in tenant gets `403`). The egress payload is **aggregates only** — no raw transaction, money, or PII leaves your deployment.</Note>

## Produce suggestions

***

Build aggregate, privacy-safe history features for a context, ask the AI advisor for candidate rules, and enqueue each surviving candidate in the review queue.

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/matching/contexts/{contextId}/rule-suggestions" \
  -H "Authorization: Bearer $TOKEN"
```

The response returns the newly created `PENDING_REVIEW` reviews — producing them creates no rule:

```json theme={null}
{
  "items": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "contextId": "550e8400-e29b-41d4-a716-446655440000",
      "candidate": {
        "type": "TOLERANCE",
        "priority": 10,
        "config": { "tolerance": 0.01 },
        "rationale": "near-miss amounts cluster under 1%",
        "expectedImprovement": "+8% auto-match",
        "confidence": 0.82
      },
      "status": "PENDING_REVIEW",
      "version": 1,
      "createdAt": "2026-06-16T10:30:00Z",
      "updatedAt": "2026-06-16T10:30:00Z"
    }
  ],
  "count": 1
}
```

Candidate types are drawn from the closed vocabulary: `EXACT` (strict equality), `TOLERANCE` (within an amount band), or `DATE_LAG` (allowing a settlement-date offset). The candidate is **config only** — it never carries a monetary value or a transaction.

## List suggestions

***

Cursor-paginated list of rule suggestions for a context, optionally filtered by status.

```bash theme={null}
curl -X GET "https://api.matcher.example.com/v1/matching/contexts/{contextId}/rule-suggestions?status=PENDING_REVIEW&limit=20" \
  -H "Authorization: Bearer $TOKEN"
```

Query parameters: `status` (`PENDING_REVIEW`, `APPROVED`, `REJECTED`), `limit` (1–200), and `cursor`. Reading the queue egresses nothing.

## Approve a suggestion

***

Approving a `PENDING_REVIEW` suggestion creates the match rule through the deterministic configuration write path. This is the **only** path from an AI suggestion to an active match rule, and it runs only on explicit human approval.

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/matching/contexts/{contextId}/rule-suggestions/{suggestionId}/approve" \
  -H "Authorization: Bearer $TOKEN"
```

```json theme={null}
{
  "reviewId": "550e8400-e29b-41d4-a716-446655440000",
  "createdRuleId": "550e8400-e29b-41d4-a716-446655440000"
}
```

## Reject a suggestion

***

Rejecting a `PENDING_REVIEW` suggestion discards it — nothing is created. The body is optional.

```bash theme={null}
curl -X POST "https://api.matcher.example.com/v1/matching/contexts/{contextId}/rule-suggestions/{suggestionId}/reject" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "too aggressive" }'
```

The approving/rejecting principal is recorded for audit.

## Lifecycle after approval

***

Once a suggestion is `APPROVED`, its `createdRuleId` links to a real match rule that participates in match runs exactly like a hand-authored rule. A review is a one-way state machine: a `PENDING_REVIEW` suggestion transitions to `APPROVED` or `REJECTED` once and cannot be re-decided. Attempting to re-decide, or to approve an already-linked review, returns `409`. An approved candidate that fails validation returns `422`.

<Tip>Preview how a candidate rule would behave before you approve it with the read-only simulate endpoint — see [Simulation](/en/matcher/matching/matcher-simulate).</Tip>

## Response codes

***

| Status | Meaning                                                          |
| ------ | ---------------------------------------------------------------- |
| `200`  | Suggestions produced, listed, approved, or rejected              |
| `400`  | Invalid status filter or suggestion id                           |
| `403`  | Tenant not opted into rule suggestions                           |
| `404`  | Rule suggestion not found                                        |
| `409`  | Invalid state transition / already linked                        |
| `422`  | Approved suggestion failed validation                            |
| `503`  | Rule suggestion or advisor not available (author rules manually) |
