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

# Custom behaviors

> Define your own behavior from scratch, or adapt a pre-built behavior's language for your specific context.

A custom behavior is any `BehaviorDef` where you supply the UUID and write the descriptions yourself. The schema is identical to a pre-built behavior — the difference is that you control everything in it.

## Required fields

Every custom behavior needs all four required fields:

| Field                  | What to provide                                                                                   |
| ---------------------- | ------------------------------------------------------------------------------------------------- |
| `behavior_uuid`        | A UUID v4 you generate. This is how Velma identifies the behavior in `behavior_detection` events. |
| `name`                 | A short label, ideally under five words.                                                          |
| `short_description`    | One sentence — the dictionary definition of what you're detecting.                                |
| `detailed_description` | The detection criteria. This is what Velma actually reads to evaluate the behavior.               |

**Generating a UUID:**

<CodeGroup>
  ```python Python theme={null}
  import uuid
  print(str(uuid.uuid4()))
  # e.g. "f47ac10b-58cc-4372-a567-0e02b2c3d479"
  ```

  ```bash shell theme={null}
  uuidgen
  # e.g. "F47AC10B-58CC-4372-A567-0E02B2C3D479"
  ```
</CodeGroup>

## A minimal custom behavior

```json theme={null}
{
  "behavior_uuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "name": "Agent Script Deviation",
  "short_description": "Agent departs from the required call opening script.",
  "detailed_description": "This behavior is present if the agent fails to state the required disclosure within the first 60 seconds of the call. The disclosure must include the company name, the agent's name, and an acknowledgment that the call may be recorded. Absence of any one of these three elements qualifies. Do not flag if the agent states all three elements, even if phrased differently from the standard script."
}
```

## Adapting a pre-built behavior

If a pre-built behavior is close to what you need but the detection language doesn't fit your context, start from its definition and modify it. The critical step is to **use a new UUID** — this tells Velma to apply your description, not the original.

<Steps>
  <Step title="Get the pre-built definition">
    Call `GET /api/velma-2-streaming/list-presets` and find the behavior you want to adapt. Copy the full object.
  </Step>

  <Step title="Generate a new UUID">
    Replace `behavior_uuid` with a UUID you generate. This decouples your custom version from the original.
  </Step>

  <Step title="Rewrite the descriptions">
    Update `name`, `short_description`, and `detailed_description` to match your context. See [Best practices](/velma/behaviors/best-practices) for guidance on writing effective criteria.
  </Step>

  <Step title="Include it in your BatchConfig">
    Add the modified object to `BatchConfig.behaviors`. If you also include the original preset slug in `presets`, your custom version takes precedence because user-supplied entries override preset entries.
  </Step>
</Steps>

<Note>
  If you include the same behavior UUID as a pre-built behavior, Velma will use the pre-built language — not your modified description. Always use a different UUID for a custom version.
</Note>

**Example — adapting "Coercion Manipulation" for a specific context:**

<Tabs>
  <Tab title="Pre-built (from list-presets)">
    ```json theme={null}
    {
      "behavior_uuid": "33333333-3333-4333-8333-033333333008",
      "name": "Coercion Manipulation",
      "short_description": "Social engineering through intimidation or threats.",
      "detailed_description": "To qualify as coercion-based manipulation, the speech must contain a threatened or implied negative consequence tied to compliance and at least one additional qualifying signal..."
    }
    ```
  </Tab>

  <Tab title="Custom version (scoped to returns context)">
    ```json theme={null}
    {
      "behavior_uuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "name": "Return Threat",
      "short_description": "Customer uses implied consequences to pressure a return approval.",
      "detailed_description": "This behavior is present if the speech meets all of the following criteria: the speaker is the customer role; the speech features a conditional statement tying a negative action (such as a negative review, escalation to a supervisor, or public complaint) to whether the return is approved; the speech does not feature a mutual negotiation or question directed at the agent. Do not flag if the speaker is an agent, or if the statement is a factual description of a past event without conditional framing."
    }
    ```
  </Tab>
</Tabs>

## Optional fields

| Field                                | Type       | What it does                                                                              |
| ------------------------------------ | ---------- | ----------------------------------------------------------------------------------------- |
| `applies_to_conversation_type_uuids` | UUID array | Restricts detection to the specified conversation types. Null or omitted means all types. |
| `applies_to_participant_role_uuids`  | UUID array | Restricts detection to speakers assigned those roles. Null or omitted means all roles.    |

Scoping behaviors to specific roles is one of the most powerful ways to reduce false positives. If a behavior only makes sense when a customer does it — not when an agent does — restrict it accordingly:

```json theme={null}
{
  "behavior_uuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "name": "Return Threat",
  "short_description": "Customer uses implied consequences to pressure a return approval.",
  "detailed_description": "...",
  "applies_to_participant_role_uuids": ["22222222-2222-4222-8222-222222222017"]
}
```

## Storing your configurations

Velma does not offer a server-side endpoint for persisting behavior definitions. Your full `BatchConfig` — including all behavior UUIDs and descriptions — must be sent in the first text frame of every new connection. Keep your configurations in your own codebase or config system so you can reproduce them reliably.

## Related

* [Using behaviors](/velma/behaviors/using-behaviors) — how to include behaviors in a request
* [Best practices](/velma/behaviors/best-practices) — how to write `detailed_description` effectively
