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

# Add a taxonomy

> Classify an existing Studio with new fields

Add a taxonomy when you want new fields on a [Studio you created](/sdk/create-studio).
Categorical and boolean fields use Studio search and deep reranking. Numeric
fields use structured analysis so you can filter their values by threshold.
Both run in the background. Use the Studio ID from its URL.

```python theme={null}
import os
from typing import Literal
from pydantic import BaseModel, Field
from nomadic import NomadicAI

client = NomadicAI(api_key=os.environ["NOMADIC_API_KEY"])
studio_id = "STUDIO_ID"

class SceneConditions(BaseModel):
    weather: Literal["clear", "rain", "snow"] = Field(
        description="Weather visible in the scene"
    )
    lighting: Literal["day", "night"] = Field(
        description="Lighting conditions in the scene"
    )

run = client.studio.add_taxonomy(studio_id, SceneConditions)
print(run.id, run.status)  # A run ID and "processing"
run.wait(timeout=3600)

schema = client.studio.taxonomy_schema(studio_id)
results = client.studio.filter(studio_id, filters={"weather": "rain"})
print(results.total)
```

Use fields that describe **one observation** in a single call. Descriptions
guide search or structured analysis. `run.wait()` raises if classification fails
or exceeds the timeout. You can call `run.refresh()` to check progress.

New fields appear in [Filter a Studio](/sdk/studio-filters) after the run
completes. Field names already present on the Studio are rejected; create a
new name if you need a different taxonomy.

## Fields and filters

| Field type | Example definition | Example filter |
| - | - | - |
| Number | `speed_mps: float` | `{"speed_mps": "< 5"}` or `{"speed_mps": "> 20"}` |
| Boolean | `is_moving: bool` | `{"is_moving": True}` or `{"is_moving": False}` |
| Category | `weather: Literal["clear", "rain", "snow"]` | `{"weather": "rain"}` |
| Several values of one field | `weather` above | `{"weather": ["rain", "snow"]}` (OR) |
| Several fields | `speed_mps` and `is_moving` | `{"speed_mps": "< 5", "is_moving": True}` (AND) |

To add numeric speed and a true/false field to an existing Studio:

```python theme={null}
class Motion(BaseModel):
    speed_mps: float = Field(description="Speed in metres per second")
    is_moving: bool = Field(description="Subject is visibly moving")

run = client.studio.add_taxonomy(studio_id, Motion)
run.wait()
print(run.failed_videos)  # Failed videos, if the structured run was partial

slow_motion = client.studio.filter(
    studio_id,
    filters={"speed_mps": "< 5", "is_moving": True},
)
fast_motion = client.studio.filter(studio_id, filters={"speed_mps": "> 20"})
```

Numeric filters accept `<`, `=`, or `>` followed by a finite number; they do
not accept `<=` or `>=`. Numeric taxonomy fields run structured analysis,
which can take longer than search-based labeling. Speed values are only as
accurate as the source data and analysis allow. For numeric fields you already
know at analysis time, you can also define them in
[Structured Output](/sdk/structured-output) and create a Studio from that batch.
Search-based labels may be absent when no matching event is retrieved. For a
search-based boolean field, an absent label is not the same as `False`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.