# Predicates


> The expression underneath every schedule. What the dashboard generates, and what to write when building a schedule through the API.
Every playlist has a **predicate**: a boolean expression that is true when the playlist is eligible to play. The rule editor is a friendly way to write one, and the schedule you build there is compiled into it.

You only need this when building schedules through the [API](/docs/developers/api/) or the [CLI](/docs/developers/cli/).

## The evaluation model

The predicate lives on the device and is evaluated continuously against the current moment, in that screen's local time. Nothing is polled and nothing waits for a sync: when the expression becomes true, the playlist becomes eligible.

The simplest predicate is `TRUE`, which is what a playlist with no rules carries.

## The variables

| Variable | What it holds |
| --- | --- |
| `$TIME` | Milliseconds since local midnight, so 08:00 is `28800000` |
| `$DATE` | A calendar day as an epoch timestamp in milliseconds |
| `$WEEKDAY` | Day of week, 0 for Monday through 6 for Sunday |

## The operators

`$DATE` takes `<=`, `=`, and `>=`.

`$TIME` takes `<=`, `>=`, and `BETWEEN {start, end}`, which is inclusive at both ends.

`$WEEKDAY` takes `IN {…}` and `NOT … IN {…}`.

Expressions combine with `AND` and `OR`, where `AND` binds more tightly than `OR`.

## What the dashboard generates

A schedule compiles to a chain opening with a literal:

```text
TRUE AND ($WEEKDAY IN {0, 1, 2, 3, 4}) AND ($TIME BETWEEN {28800000, 61200000})
```

That is weekdays, 08:00 to 17:00. Several rules become an `OR` chain of such groups, since any one rule matching is enough.

```text
FALSE OR (...) OR (...)
```

Anything expressible in that shape can be read back into the rule editor. Anything else shows as read-only. See [Complex schedules](/docs/scheduling/advanced/complex-schedules/).

## Writing one

Through the CLI, when creating a playlist:

```bash
screenly playlist create "Office Hours" 'TRUE AND ($WEEKDAY IN {0, 1, 2, 3, 4})'
```

Through the API, as a string field on the playlist.

> [!NOTE]
> Check the [v4.1 API reference](https://developer.screenly.io/api_v4_1/) for the playlist schema before writing predicates by hand.

## A caution

A predicate written by hand is a schedule nobody can edit in the dashboard, and one that no warning will tell you never matches. If the rule editor can express what you want, use it.