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

# Entities

> Define and validate structured data types like names, dates, and phone numbers in flow steps.

Entities are structured values the agent can collect and reuse during a flow. Each entity has a **type** that determines what validation is applied. Entity names must be unique across all entities in your project.

Mark an entity as required on a condition so the LLM won't consider that condition satisfied without a valid value. In Function steps, you must enforce this yourself in code.

## Entity types and configuration

<AccordionGroup>
  <Accordion title="Free text">
    Open-ended responses with no validation. Use when you need to capture unstructured input like comments or descriptions.
  </Accordion>

  <Accordion title="Number (numeric)">
    Numeric values. Configure:

    * **Decimal** -- toggle to accept decimal values (float) or restrict to integers
    * **Range** -- optionally set a **minimum** and **maximum** value (up to 1,000,000)
  </Accordion>

  <Accordion title="Alphanumeric">
    Any mix of letters and numbers. Useful for booking references, confirmation codes, or postal codes. Configure:

    * **Validation type** -- choose a built-in preset or custom regex:
      * **Zip code** -- US zip code format (e.g. `12345` or `12345-6789`)
      * **Postal code** -- UK postal code format
      * **Custom** -- your own regular expression
  </Accordion>

  <Accordion title="Phone number">
    Telephone numbers. Configure:

    * **Country codes** -- restrict to specific countries (26 supported, including US, CA, GB, AU, DE, FR, and others)
  </Accordion>

  <Accordion title="Date">
    Calendar dates. No additional configuration.
  </Accordion>

  <Accordion title="Time">
    Clock times. Configure:

    * **Time range** -- set a start and end time to restrict valid values
  </Accordion>

  <Accordion title="Multiple choice (enum)">
    Selection from a predefined list. Configure:

    * **Options** -- the accepted values the caller can choose from
  </Accordion>

  <Accordion title="Name">
    Personal names (first name, last name, or both). No additional configuration.
  </Accordion>

  <Accordion title="Address">
    Street addresses or locations. No additional configuration.
  </Accordion>
</AccordionGroup>

## Entity visibility in a step

Entities extracted in a step are immediately available in that same step. You can:

* **Reference entities in the prompt** using `{{entity:entity_name}}` – the system resolves the value at runtime, so the prompt can adapt based on what the caller just provided.
* **Use entities in redirect conditions** – mark an entity as a [required entity](/flows/no-code/introduction#conditions) on a condition so the LLM won't activate that path until the entity has been collected **and validated**.

Extraction and evaluation happen in the same step execution – you do not need a separate step to use an entity you just collected.

<Note>
  Entity extraction is a flow-only feature. [Managed Topics](/managed-topics/introduction) don't support entity extraction directly. To collect structured data when a topic is matched, use the topic's action to [trigger a flow](/flows/triggering-flows) and configure entity extraction in that flow's steps.
</Note>

## When entities count as "collected"

An entity only counts as collected once it passes validation. If a caller provides a value in the wrong format or outside the allowed range, the agent asks them to try again – and any condition that requires that entity will not activate until a valid value is provided.

This means a condition with **required entities** will only trigger after every required entity has a valid value. If you are debugging why a condition is not firing, check whether the entity passed validation – not just whether the caller said something.

In [Conversation Review](/analytics/conversations/review), system-generated events show entity validation and condition evaluation results, helping you identify whether an entity was rejected or a condition was skipped.

## Validation and retries

Depending on the entity type:

* Valid values allow the flow to continue.
* Invalid values trigger re-asking or fallback routing.

Because there is no automatic cap on retries, always design your flow with a **fallback condition** (e.g. "caller unable to provide") so the conversation can exit the step gracefully if collection stalls.

If a branch depends on an entity being present, always include a clear fallback path for when it is not collected or fails validation.

## Accessing entities in code

Validated entities are available in Function steps two ways:

* `conv.state.entity_name` -- the value coerced to its native Python type. Recommended for new code.
* `conv.entities.entity_name.value` -- the raw string value, with validation metadata on the surrounding object. Use when you need the original string or the [`EntityValidationResult`](/tools/classes/conv-object#entities) fields.

Both are kept in sync. An entity only appears in `conv.state` after it passes validation, so failed extractions never overwrite earlier values.

### Native types in `conv.state`

The type stored in `conv.state` is derived from the entity's configuration:

| Entity type      | Stored as | Example                         |
| ---------------- | --------- | ------------------------------- |
| Number (integer) | `int`     | `conv.state.party_size == 4`    |
| Number (decimal) | `float`   | `conv.state.weight_kg == 12.5`  |
| Currency         | `float`   | `conv.state.amount == 19.99`    |
| Everything else  | `str`     | `conv.state.email == "a@b.com"` |

If coercion fails for any reason, the original string value is stored so your function still receives a value to work with.

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Recommended – native int, no cast needed
if conv.state.party_size > 15:
    flow.goto_step("Group Booking")

# Still supported – raw string from conv.entities
party_size = int(conv.entities.party_size.value)
if party_size > 15:
    flow.goto_step("Group Booking")
```

<Warning>
  `conv.entities.entity_name.value` is **always a string**, even for numeric types. Cast to `int()` or `float()` before numeric comparisons, otherwise string comparison rules apply and `"9" > "10"` evaluates to `True`. Use `conv.state.entity_name` to skip the cast.
</Warning>

See [no-code flows – accessing entities in a function](/flows/no-code/introduction#accessing-collected-entities-in-a-function) for more examples.

## Related pages

<CardGroup cols={3}>
  <Card title="No-code flows overview" icon="diagram-project" href="/flows/no-code/introduction">
    Step types, routing logic, and canvas controls.
  </Card>

  <Card title="Quickstart" icon="rocket" href="/flows/no-code/quickstart">
    Build your first no-code flow step by step.
  </Card>

  <Card title="Advanced steps" icon="gear" href="/flows/no-code/advanced-steps">
    ASR biasing, DTMF, and rich text references.
  </Card>
</CardGroup>
