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

# Using Skills

> Model provider attributes and enforce scheduling constraints with a flexible, composable skill system.

## Overview

Skills are a generic abstraction for any provider attribute your organization cares about — licensed regions, enrollments, spoken languages, clinical specialties, and more. Rather than building separate systems for each attribute type, you define **skills**, assign **values** to providers, and enforce **skill requirements**.

This gives you a single, composable mechanism that covers a wide range of scheduling constraints without custom logic for each one.

## Core concepts

### Skills

A skill is a named category of provider attribute. Each skill has an `id` and a set of possible **values**.

| Example skill       | Possible values                                    |
| ------------------- | -------------------------------------------------- |
| Licensed Region     | `US-KY`, `US-OH`, `US-IN`, …                       |
| Hospital Enrollment | `st_mary`, `general_east`, `childrens_central`, …  |
| Language            | `en`, `es`, `fr`, `zh`, …                          |
| Specialty           | `cardiology`, `radiology`, `emergency_medicine`, … |

### Skill assignments

A provider can hold zero or more values for each skill, as well as a valid range for the assignment:

| Provider | Skill           | Value   | Range              |
| -------- | --------------- | ------- | ------------------ |
| Dr. Reed | Licensed Region | `US-KY` | —                  |
| Dr. Reed | Licensed Region | `US-OH` | 2026-01-10 onwards |
| Dr. Reed | Licensed Region | `US-WI` | until 2028-12-31   |

### Skill requirements

A skill requirement is a constraint — typically placed on a shift — that a provider must satisfy in order to be eligible. Requirements are **composable**: you can combine simple checks with `and` / `or` logic to express complex eligibility rules.

## Requirement schema

Skill requirements use a recursive, tree-structured schema. There are two node types: **leaf** nodes that check a single skill value, and **logical** nodes that combine other requirements.

### `equal` — leaf requirement

Asserts that a provider holds a specific value for a specific skill.

```json theme={null}
{
  "type": "equal",
  "skill": "licensed-region-id",
  "value": "US-KY"
}
```

### `and` — all must match

```json theme={null}
{
  "type": "and",
  "entries": [
    { "type": "equal", "skill": "licensed-region-id", "value": "US-KY" },
    { "type": "equal", "skill": "enrollment-id", "value": "st_mary" }
  ]
}
```

### `or` — at least one must match

```json theme={null}
{
  "type": "or",
  "entries": [
    { "type": "equal", "skill": "licensed-region-id", "value": "US-KY" },
    { "type": "equal", "skill": "licensed-region-id", "value": "US-OH" }
  ]
}
```

### Full type definition

The schema is recursive — `and` and `or` nodes can contain any mix of `equal`, `and`, and `or` children, allowing arbitrary nesting depth.

<CodeGroup>
  ```typescript TypeScript theme={null}
  type SkillRequirement =
    | {
        type: "equal";
        skill: string;
        value: string;
      }
    | {
        type: "and" | "or";
        entries: SkillRequirement[];
      };
  ```

  ```python Python (Pydantic) theme={null}
  from pydantic import BaseModel
  from typing import Union, Literal

  class EqualSkillRequirement(BaseModel):
      type: Literal['equal']
      skill: str
      value: str

  class LogicalSkillRequirement(BaseModel):
      type: Literal['and', 'or']
      entries: list['SkillRequirement']

  SkillRequirement = Union[EqualSkillRequirement, LogicalSkillRequirement]
  ```
</CodeGroup>
