# Agent Custom Properties

**Custom Properties** are dynamic attributes used to extract, store, and process specific information from conversations. Unlike fixed fields, their flexibility allows the system to adapt to the unique needs of each client.

## 📋 Property Attributes
Each custom property is defined by the following fields:

* **Name:** The property's unique identifier.
* **Description:** Crucial context for the LLM. It explains *when* the value should be extracted and *what* it represents.
* **Data Type:** Defines whether the information is text, number, boolean, date, etc.
* **Default Value:** The value assigned if the property cannot be detected.
* **Include in LLM:** A toggle that determines if the value of this property is sent back to the model as part of the context for future analysis.
* **Check until conditions are met (`check_until_match`):** Controls whether the extractor keeps re-evaluating a property *after it already has a value*. This is not just an optimization — for any property that **gates automation**, leaving it off silently freezes stale values. See ["Gating properties must use Check Until Match"](#-gating-properties--check-until-match) below.

---

## ⚙️ Logic and Analysis
The data extraction process is dynamic and occurs at two levels of intensity:

### 1. Real-Time Analysis (Lean)
As the conversation unfolds, the agent processes incoming messages.

* **Triggers:** The agent utilizes **tool calling**. For example, if the agent detects a specific pattern (such as a phone number), a signal is triggered to execute the property analysis.
* **Intensity:** This is a lightweight analysis designed to maintain low response latency.

### 2. Batch Analysis (Deep)
There is a specific **"Analyze Conversations"** button that performs an exhaustive sweep of the entire history.

* Used to ensure no property was missed during the live flow.
* Ideal for processing complex business rules that require the full context of the dialogue.

---

## ⚠️ Gating Properties & `Check Until Match`

A property that **gates automation** — a terminal contact limit that silences the agent, a
follow-up lock, or a conversion notification — must be created with **`check_until_match = true`**
and its terminal target value set (for a boolean, target = `true`). If you skip this, the automation
will fire unreliably and the agent can keep messaging (and spending on) an already-converted lead
indefinitely.

### How the extractor actually decides to re-evaluate

On each new message, a property is included in the extraction pass only when:

1. **It has no value yet** for this contact → always re-evaluated until it gets *some* value; **or**
2. **It already has a value AND `check_until_match = true` AND the current value ≠ the target** →
   keeps being re-evaluated every message until it reaches the target, then stops.

The trap is what happens once a property holds *any* value with `check_until_match = false`: **it is
frozen permanently and never re-evaluated.** A terminal boolean (`vip_access_granted`,
`deposit_confirmed`, `call_booked`, `phone_shared`, …) is very likely to be set to `false` early in
the conversation — before the converting signal appears. With `check_until_match = false` that early
`false` freezes, and the later terminal signal (the VIP link sent, the deposit screenshot, the
booking) **never flips it to `true`**. Every downstream automation is gated on that boolean, so none
of it ever fires. One missed early evaluation = the agent active forever on that conversation.

### The rule

> **Any boolean/number property that gates agent shutdown, a follow-up lock, or a conversion
> notification MUST be `check_until_match = true` with its terminal target value.** Set it at
> creation time. When calling the MCP, pass `checkUntilMatch: true` plus the matching
> `checkUntilValueBoolean` / `checkUntilValueInt` — the tool defaults `checkUntilMatch` to `false`,
> which is only safe for descriptive properties you never gate on.

Symptom to recognize in the wild: "the agent never shuts off / keeps DMing converted leads." Diagnose
by comparing a reliably-fired terminal property (one that has `check_until_match = true`) against the
gated ones — if their counts barely overlap even though the signal is present in the transcript, the
gated ones are frozen. (First seen 2026-07-07 on a betting-VIP agency: `vip_access_granted` was
frozen `false` on 93 of 98 flow-completed leads.)

This is a companion to the boolean-gating rule in `prompt-antipatterns.md` (gating properties must be
boolean/number, never string) and the "an agent is a **system**, not a prompt" doctrine: a property
is inert until something consumes it, *and* it must stay live long enough to reach its terminal value.

---

## 🚀 Configuration Guide
To learn how to create and configure these properties from the admin panel, check out our interactive guide:

👉 [**Step-by-Step Guide: How to configure and create Custom Properties (Scribe)**](https://scribehow.com/viewer/Create_a_Property_with_Default_Text_Value__TdDkswDeQ4u0RfwTfRDN7A)
