Skip to content

Filter Builder Reference

This document is intended to help an AI assistant understand valid filter structures and values for Lucit campaign and item filters.

Generated by bin/docs/generate-filter-builder-reference.php from the filter-builder catalogs and model-class constants. Update the generator rather than editing this build artifact. Group/condition rules describe the current frontend builder; they do not replace the receiving API contract.

Scope

  • This covers the valid field catalog, data types, logical-group operators, filter operators, and the final JSON object shape used by the Lucit filter builder.
  • Export / inventory item filtering used in the Schedule Builder dialog and Item Filter dialog is based on: date/time, the item_filter object (including dynamic key/value fields from the current account key-value stores, typically populated by data source apps), and digital_board_filter (a combination of the documented digital-board filter fields plus any dynamic key/value fields for digital boards for that account from data source apps).
  • The Campaign Settings dialog has an Item Filter for restricting which inventory items are loaded into a campaign; that filter uses the InventoryFieldOptions catalog.
  • InventoryExportFields, AccountFields, UserFields, LightningDeviceFields, and InventoryFeedFields are currently used only by automation flows/apps that create automations; they are not the primary UI item-filter catalogs.
  • The schedule editor is separate from the item filter/editor. A schedule is managed by date_range, days_of_the_week, and time_range entries in the schedules array, while the item filter uses item_filter entries with filter_fields and filter_functions.
  • The screen selection filter uses the same filter_fields / filter_functions envelope as the item filter, but is stored on digital_board_filter.

Filter JSON envelope

For a nonempty builder-authored filter, filter_fields contains one root logical group. The root operator is selected from the requested logic; it is NOT always and. Function conditions can be children in this same tree; the builder still emits filter_functions: [].

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "type": "filter_field",
                    "field_name": "digital_board.location.country",
                    "function_name": null,
                    "objectClass": "App\\DigitalBoard",
                    "value": "US",
                    "operator": "equals",
                    "group": "Screen"
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

A full item filter is typically stored as a schedule entry like this:

[
    {
        "type": "date_range",
        "startDate": "2026-01-01T00:00:00Z",
        "endDate": "2026-01-31T23:59:59Z"
    },
    {
        "type": "item_filter",
        "filter_fields": [
            {
                "field_name": "__logical_group",
                "operator": "and",
                "value": [
                    {
                        "type": "filter_field",
                        "field_name": "title",
                        "function_name": null,
                        "objectClass": "App\\InventoryItem",
                        "value": "ford",
                        "operator": "like"
                    }
                ],
                "isDirty": true,
                "isGroup": true
            }
        ],
        "filter_functions": []
    }
]

This schedule example uses UI date names (startDate / endDate). Endpoint DTOs may use start_datetime / end_datetime; use the receiving service contract, rather than mixing these forms. Construct the filter as an object first and let the service apply any required JSON-string serialization.

Logical group marker

  • __logical_group identifies EVERY logical group, not only the root.
  • Every group MUST have isGroup: true. The UI tests this flag to distinguish a group from a condition; field_name: "__logical_group" alone is insufficient. This applies recursively at all nesting levels.
  • Group operators are exactly and (all children must match) and or (at least one child must match). Each operator combines only its immediate children; a child group is evaluated as one subexpression.
  • A group contains field_name: "__logical_group", operator, a nonempty value array of conditions and/or groups, and isGroup: true. Include isDirty: true when authoring builder-shaped groups, matching createLogicalGroup() output. isDirty is UI bookkeeping, not the group discriminator.
  • Groups do not use type: "filter_field" or type: "filter_function", function_name, objectClass, or group. Those describe conditions. Do not serialize isRoot; the UI derives it.
  • Nested groups and mixtures of conditions/groups are supported. The current UI allows adding groups while path.length < maxTreeDepth (maxTreeDepth: 2): root depth 0, child depth 1, grandchild depth 2. This is an add-button constraint, NOT a documented backend nesting limit; do not reject or flatten existing deeper trees merely because of that setting.
  • Never leave empty groups in a nonempty authored filter. To intentionally clear filtering, use the receiving UI/API contract (commonly { "filter_fields": [], "filter_functions": [] }), not a group with an empty value.

Condition nodes and field metadata

Node kind type field_name function_name value
Logical group Omit __logical_group Omit Nonempty array of child nodes
Field condition filter_field Exact field-option id null Operator-specific comparison value
Function condition filter_function null Exact function-option id Operator-specific comparison value
  • For conditions, copy objectClass and group from the selected field option. Keep function_name: null for field conditions and field_name: null for function conditions. If a field option has no group, omit it; do not invent a group.
  • Catalog type: "field" / "function" becomes condition type: "filter_field" / "filter_function". A name that looks like a method may be a function option: for example, digital_board.getLatitudeLongitude uses function_name, NOT field_name.
  • objectClass is the model class string, not a JS expression or display name: e.g. App\DigitalBoard as displayed text, encoded as "App\\DigitalBoard" in JSON. Copy the resolved catalog value exactly.
  • group is field-picker metadata (e.g. Weather or Screen), NOT a logical grouping instruction. Only a group node and its operator express AND/OR.
  • A condition must not have isGroup: true. Leaf isDirty is optional UI bookkeeping; it is not a comparison operator or an evaluation flag.

Values, operators, and dynamic fields

  • Choose an operator from the Default operators table that supports the discovered field data type. Use the exact operator token, including case and punctuation; do not replace equals with eq or guess a negation token.
  • Unary operators (e.g. is_false, is_true, datetime_is_future) need no comparison operand. Builder payloads use value: ""; do not encode is_false as a string comparison against "false".
  • List operators use the comma-separated string form shown by the builder, e.g. "401,40101,40102", NOT a JSON array unless the specific operator explicitly requires an array. Negative list operators are not interchangeable: preserve not_any_of versus not_like_any_of according to exact membership versus pattern-matching intent.
  • Numeric comparisons in working campaigns can have numeric strings ("80", "69"); other builder examples use JSON numbers. Preserve existing values and the field/operator contract rather than globally coercing every value. Use booleans, strings, dates, or geometry according to their field and operator.
  • Enum values must be underlying API values, never translated picker labels. Boolean, enum, list, and geo values must not be guessed from a label.
  • The static catalogs are NOT the entire account field set. Query /accounts/{accountId}/unique-key-value-store-keys with object_type for the target model. The UI requests App\DigitalBoard for screen keys and App\Account for account/data-source keys.
  • For discovered keys, use the returned macro exactly as the field id / condition field_name; key_name is the label, not the identifier. The UI uses returned dataType or falls back to scalar, and takes group from inventory_feed.name (fallback Screen or Account) and objectClass from the queried model.
  • The Weather1 fields in the examples are real keys from the supplied working campaign, NOT universally available built-in fields. Confirm the account exposes them and confirm their values/data types. Do not invent a Weather1 key, assume all weather providers use it, or substitute a condition code for a condition group code.

Sports data-source filters for a campaign item

The sports examples below come from the Data Source Filter for an item in a campaign. They restrict when that creative is eligible using the feed's account-level data; they are NOT screen-weather filters or campaign-wide inventory selection rules. The examples show the filter envelope edited by the builder. For a schedule payload, put that envelope on the appropriate type: "item_filter" entry and preserve the other schedule entries; do not move these predicates to digital_board_filter merely because the creative plays on a screen.

  • Sports feed flags here use account.store.*, objectClass: "App\\Account" in JSON, type: "filter_field", and function_name: null. Copy the discovered feed name into group; it is metadata, not a logical group.
  • Each supplied flag uses unary operator: "is_true" with value: "". The field itself carries the boolean result; do not compare its value with the text "true" or use a game-count predicate invented from a label.
  • Scope is the configured feed: "no games scheduled" means no games for the teams configured in that data source, NOT no games anywhere in MLB. Likewise, "all games" and "has games today" concern the games selected by that feed. A name containing (All Games) does not override its team configuration.
  • In the NCAA example, BOTH all_games_in_pregame AND has_games_today must be true. Keep the explicit games-today predicate: an all-games status alone does not establish that there is any game today. No games today, or a game that is no longer pregame, must not activate that example.
  • The NFL example uses the Baltimore Ravens' team-result flag for the requested "won their game today" behavior. It does not test whether any NFL team won, and it does not predict a win before the result is available. Confirm the feed's current-day/result semantics and freshness; do not assume the suffix _won independently guarantees a date or fabricate a date-field key.

Discover sports fields before authoring

  1. Configure the actual sports data source, including the desired team or teams, then run it at least once with valid data so the resulting keys can be observed. Team-result keys depend on team names and may not be known before that run.
  2. Inspect its output and query the account's available key/value-store fields with object_type: "App\\Account" in JSON. Copy the returned macro, data type, and feed metadata exactly.
  3. Select flags from the intended feed instance. LF1092, LF1174, and LF1387 are identifiers in these supplied examples, not portable constants. Do not reuse them for another feed, manufacture a new identifier, derive a team-key slug from its display name, or combine flags from unrelated feeds unless that cross-feed logic is explicitly requested.
  4. Verify that the desired flag exists and has current valid data before saving. A missing key, an unrun feed, or stale output is not evidence of "no games scheduled" or a win. If the needed key has not appeared, obtain valid feed output and rediscover it rather than guessing.
  5. Check the expression against matching and nonmatching feed states. For the pregame example, (true, true) activates; (true, false), (false, true), and (false, false) do not. For a no-games or team-win flag, only a true flag activates.

Constructing complex filters safely

  1. Determine the storage target: screen selection (digital_board_filter), a schedule item_filter, campaign settings inventory filtering, or an automation. Load that target's static AND dynamic field options.
  2. Write a fully parenthesized expression in plain language before constructing JSON. Identify which alternatives share an OR and which restrictions must all hold under AND.
  3. Map each predicate to one condition with exact identifiers, copied metadata, a supported operator, and the correct value shape.
  4. Translate each parenthesized AND/OR subexpression into a group, including isGroup: true and isDirty: true on EVERY group. Choose the root operator from the expression; do not add an AND wrapper by habit.
  5. Prefer the simplest equivalent tree for NEW filters: rain OR snow is one root OR with two leaves. An AND containing only a correctly marked OR is logically equivalent but unnecessary. Never flatten an OR into its AND parent, or vice versa; that changes meaning. Preserve existing campaign trees unless explicitly asked to simplify them.
  6. Put the one root in filter_fields and keep filter_functions: [] for builder-shaped payloads, even when function conditions appear inside the tree. Preserve legacy function arrays only when the receiving contract explicitly requires them.
  7. Validate recursively, then check the truth conditions against representative matching and nonmatching cases. A syntactically valid JSON object or the UI's permissive isValid check alone does not establish correct semantics or backend acceptance.

Recursive preflight checklist

  • Envelope has both arrays; a nonempty authored tree has one root group.
  • Each group has field_name: "__logical_group", isGroup: true, isDirty: true, operator: "and" or "or", and a nonempty array of individually validated children.
  • Each leaf has the correct condition type, exactly one non-null identifier, copied objectClass and available group, a supported operator, and an appropriate value. No leaf is marked as a group.
  • All field identifiers and enum values exist for this account and target; dynamic weather and sports keys have been discovered rather than assumed. Sports flags refer to the intended configured feed/team scope and have current valid output.
  • No accidental singleton AND wrapper, dropped group flags, mixed identifier types, JSON-array list operand, or incorrect scope has been introduced.
  • Describe the final tree back as a fully parenthesized expression and verify it matches the request. Check the service DTO/serialization and test in the receiving application before changing a live campaign.

Common failure: a nested group without isGroup

The previously failing rain/snow payload had a root AND containing an inner OR with only field_name, operator, and value. The inner object lacked isGroup: true; the UI renders it as a condition instead of recursively rendering its children. Nesting itself is not the problem. Mark EVERY group correctly and, for this simple expression, use the root OR example below. Adding isDirty alone does not repair group recognition. The frontend evidence explains the UI failure; backend evaluation requirements must be checked separately.

Geo filter value shape for is_within_geo

The value for is_within_geo is a JSON array of geo objects. The UI supports multiple geofences in one filter, and each element must be one of the following shapes.

Radius / circle

[
  {
    "id": "geo-1",
    "geo_source": "map_drawing",
    "geo_type": "radius",
    "label": "Circle on map",
    "bounds": { "north": 41.0, "east": -72.0, "south": 40.0, "west": -73.0 },
    "centerpoint": { "lat": 40.5, "long": -72.5 },
    "units": "m",
    "radius": 2500
  }
]

Polygon

[
  {
    "id": "geo-2",
    "geo_source": "map_drawing",
    "geo_type": "polygon",
    "label": "Polygon on map",
    "bounds": { "north": 41.0, "east": -72.0, "south": 40.0, "west": -73.0 },
    "coordinates": [[41.0, -72.0], [41.0, -73.0], [40.0, -73.0], [40.0, -72.0]]
  }
]

Rectangle

[
  {
    "id": "geo-3",
    "geo_source": "map_drawing",
    "geo_type": "rectangle",
    "label": "Rectangle on map",
    "bounds": { "north": 41.0, "east": -72.0, "south": 40.0, "west": -73.0 },
    "coordinates": [[41.0, -72.0], [41.0, -73.0], [40.0, -73.0], [40.0, -72.0]]
  }
]

Important constraints:

  • value is an array, not a single object.
  • geo_type must be one of: radius, polygon, or rectangle.
  • geo_source is typically either google_place or map_drawing.
  • Radius filters use centerpoint, radius, and units (typically "m" for meters).
  • Polygon and rectangle filters use coordinates as an array of [latitude, longitude] pairs.
  • bounds is optional metadata used by the map UI, but the essential geometry is the centerpoint/radius or coordinates fields.

Data types

id label
scalar Scalar (Could be any of text or number)
string Text
float Decimal Number
integer Whole Number
boolean True/False
datetime Date/Time
tags Tags
geo_location Geo Location
geo_tags Geo Tags
array Array (List)

Logical group operators

id operator label
and and all of the following are true
or or at least one of the following is true

Default operators

Each operator is valid only for certain data types. The runtime logic in useFilterBuilder.ts filters available operators by dataTypes.

id operator label dataTypes isUnary isList help
like like Contains scalar, string false false Any text, not case sensitive
not_like not_like Does not Contain scalar, string false false Any text
like_one_of like_one_of Contains One Of scalar, string, tags false true Multiple items separated by commas
like_all_of like_all_of Contains All Of scalar, string, tags false true Multiple items separated by commas
not_like_any_of not_like_any_of Contains None Of scalar, string, tags false true Multiple items separated by commas
equals equals Equals scalar, string, float, integer, boolean false false Any value, case sensitive, matches exactly
does_not_equals does_not_equals Does Not Equal scalar, string, float, integer, boolean false false Any value
is_one_of is_one_of Is One Of scalar, string, float, integer false true Multiple items separated by commas
not_any_of not_any_of Is Not One Of scalar, string, float, integer false true Multiple items separated by commas
greater_than > Greater Than scalar, float, integer, datetime false false
less_than < Less Than scalar, float, integer, datetime false false
greater_than_or_equal_to >= Greater Than Or Equal To scalar, float, integer, datetime false false
less_than_or_equal_to <= Less Than Or Equal To scalar, float, integer, datetime false false
is_between is_between Is Between scalar, float, integer, datetime false false Inclusive of two numbers separated by a comma (min,max)
is_true is_true Is True scalar, string, boolean true false Must be true or true'ish value
is_false is_false Is False scalar, string, boolean true false Must be false or falsy value
is_empty is_empty Is Empty scalar, string, float, integer, boolean true false Must be empty, blank, null or false value
is_not_empty is_not_empty Is Not Empty scalar, string, float, integer, boolean true false Must be a value
datetime_is_future datetime_is_future Is In Future scalar, datetime true false Must be a future date or time
datetime_is_past datetime_is_past Is In Past scalar, datetime true false Must be a past date or time
datetime_is_today datetime_is_today Is Today scalar, datetime true false Must be today's date or time
datetime_is_older_than_seconds datetime_is_older_than_seconds Is Older Than Seconds scalar, datetime false false Must be older than a number of seconds
datetime_is_younger_than_seconds datetime_is_younger_than_seconds Is Younger Than Seconds scalar, datetime false false Must be younger than a number of seconds
matches_regexp matches_regexp Matches Regular Expression scalar, string false false Must match a regular expression in PCRE format /{pattern}/{modifiers}
does_not_match_regexp does_not_match_regexp Does Not Match Regular Expression scalar, string false false Must not match a regular expression in PCRE format /{pattern}/{modifiers}
is_within_geo is_within_geo Within Geo scalar, geo_location, geo_tags false false Must be within a geo location
array_like array_like List Contains array false false List contains a value
array_like_one_of array_like_one_of List Contains One Of array false true Multiple items separated by commas
array_not_like array_not_like List Does Not Contain array false false List does not contain a value
array_not_like_any_of array_not_like_any_of List Contains None Of array false true Multiple items separated by commas
array_contains_one_of array_contains_one_of List Contains One Of (Exact) array false true Multiple items separated by commas
array_contains_none_of array_contains_none_of List Contains None Of (Exact) array false true Multiple items separated by commas
array_contains_one_true array_contains_one_true List Contains At Least One True array true false At least one item in the list is true
array_contains_one_false array_contains_one_false List Contains At Least One False array true false At least one item in the list is false
array_is_all_true array_is_all_true List Is All True array true false All items in the list are true
array_is_all_false array_is_all_false List Is All False array true false All items in the list are false

Model field catalogs

Inventory item fields

id label type dataType group objectClass enum docs_reference
title Title field string App\InventoryItem false
description Description field string App\InventoryItem false
price Price field float App\InventoryItem false
price_original Original Price field float App\InventoryItem false
unqique_id Unique ID field string App\InventoryItem false
dealer_stock_number Stock Number field string App\InventoryItem false
year Year field integer App\InventoryItem false
make Make field string App\InventoryItem false
model Model field string App\InventoryItem false
sub_model Sub Model field string App\InventoryItem false
new_used New field boolean App\InventoryItem false
basePhotoCount Photo Count function integer App\InventoryItem false
primaryPhotoAspectRatio Photo Aspect Ratio function float App\InventoryItem false
mileage Mileage function integer App\InventoryItem false
current_date_time Current Date/Time field datetime App\InventoryItem false
random_number_to_one_hundred Random Number (1-100) function integer App\InventoryItem false
cached_tags Tags field tags App\InventoryItem false
geoTagLatLongs Location (GeoTags) function geo_tags App\InventoryItem false
account.name Item Account Name field string App\InventoryItem false
account.lcuid Item Account LCUID field string App\InventoryItem false
user.name Item User Name field string App\InventoryItem false
user.lcuid Item User LCUID field string App\InventoryItem false
drive_template.name Item Drive Template Name field string App\InventoryItem false
drive_template.lcuid Item Drive Template LCUID field string App\InventoryItem false

Digital board fields

id label type dataType group objectClass enum docs_reference
digital_board.name Screen Name field string Screen App\DigitalBoard false
digital_board.board_identifier Screen ID field string Screen App\DigitalBoard false
digital_board.agency.name Media Owner Name field string Screen App\DigitalBoard false
digital_board.venue_taxonomy_id Venue Taxonomy ID field integer Screen App\DigitalBoard true See https://github.com/openooh/venue-taxonomy for list off valid types
digital_board.digital_board_format Screen Format field string Screen App\DigitalBoard true See https://lucit.app/docs/guides/screen-format-reference/ for a valid list of screen formats
digital_board.location.city Screen City field string Screen App\DigitalBoard false
digital_board.location.region Screen State/Province field string Screen App\DigitalBoard false Typically a 2 CharacterUS state or Canadian Provice, but can be any worldwide region
digital_board.location.postal_code Postal Code field string Screen App\DigitalBoard false
digital_board.location.usa_dma_code DMA Code (US) field string Screen App\DigitalBoard true Any valid North American DMA Code
digital_board.location.country Screen Country field string Screen App\DigitalBoard false
digital_board.location.datetime_current Screen Current Date/Time field datetime Screen App\DigitalBoard false The current date and time at the physical location of the screen
digital_board.location.timezone Screen Timezone field string Screen App\DigitalBoard true Any valid timezone name, e.g., 'America/New_York'
digital_board.location.timezone_offset_seconds Screen Timezone Offset Seconds field integer Screen App\DigitalBoard false
digital_board.getLatitudeLongitude Screen Latitude/Longitude Location function geo_location Screen App\DigitalBoard false
digital_board.cached_tags Screen Tags field tags Screen App\DigitalBoard false

Account fields

id label type dataType group objectClass enum docs_reference
account.name Account Name field string App\Account false
account.description Account Description field string App\Account false
account.website Account Website field string App\Account false
account.is_parent_account Account Is Parent Account field boolean App\Account false
account.agency.lcuid Account Agency LCUID field string App\Account false
account.agency.name Account Agency Name field string App\Account false
account.created_by_user.name Account Created By User Name field string App\Account false
account.created_by_user.lcuid Account Created By User LCUID field string App\Account false

Inventory export fields

id label type dataType group objectClass enum docs_reference
inventory_export.name Campaign Name field string App\InventoryExport false
inventory_export.created_by_user.name Campaign Created By User Name field string App\InventoryExport false
inventory_export.created_by_user.lcuid Campaign Created By User LCUID field string App\InventoryExport false
inventory_export.account.name Campaign Account Name field string App\InventoryExport false
inventory_export.account.lcuid Campaign Account LCUID field string App\InventoryExport false
inventory_export.active Campaign Active field boolean App\InventoryExport false
inventory_export.status Campaign Creative Build Status field integer App\InventoryExport true Any valid ExportStatus
inventory_export.last_run_at Campaign Last Run At field datetime App\InventoryExport false
inventory_export.campaign_state Campaign State field integer App\InventoryExport true Any valid CampaignState
inventory_export.campaign_state_changed_at Campaign State Changed At field datetime App\InventoryExport false
inventory_export.campaign_class Campaign Class field string App\InventoryExport true Any valid InventoryExportCampaignClasses

Inventory feed fields

id label type dataType group objectClass enum docs_reference
inventory_feed.name Feed Name field string App\InventoryFeed false
inventory_feed.active Feed Active field boolean App\InventoryFeed false
inventory_feed.status Feed Status field integer App\InventoryFeed true Any valid FeedStatus
inventory_feed.last_run_at Feed Last Run At field datetime App\InventoryFeed false
inventory_feed.last_changed_at Feed Last Changed At field datetime App\InventoryFeed false
inventory_feed.account.name Feed Account Name field string App\InventoryFeed false
inventory_feed.account.lcuid Feed Account LCUID field string App\InventoryFeed false
inventory_feed.created_by_user.name Feed Created By User Name field string App\InventoryFeed false
inventory_feed.created_by_user.lcuid Feed Created By User LCUID field string App\InventoryFeed false
inventory_feed.inventory_feed_provider.name Feed Provider Name field string App\InventoryFeed false
inventory_feed.inventory_feed_provider.lcuid Feed Provider LCUID field string App\InventoryFeed false

Lightning device fields

id label type dataType group objectClass enum docs_reference
lightning_device.name Lightning Device Name field string Lightning Device App\LightningDevice false
lightning_device.description Lightning Device Description field string Lightning Device App\LightningDevice false
lightning_device.status Lightning Device Status field integer Lightning Device App\LightningDevice true Any valid LightningDeviceStatus
lightning_device.venue_taxonomy_id Venue Taxonomy ID field integer Lightning Device App\LightningDevice true See https://github.com/openooh/venue-taxonomy for list off valid types
lightning_device.digital_board_format Screen Format field string Lightning Device App\LightningDevice true See https://lucit.app/docs/guides/screen-format-reference/ for a valid list of screen formats
lightning_device.location.city Device City field string Lightning Device App\LightningDevice false
lightning_device.location.region Device State/Province field string Lightning Device App\LightningDevice false
lightning_device.location.postal_code Postal Code field string Lightning Device App\LightningDevice false
lightning_device.location.usa_dma_code DMA Code (US) field string Lightning Device App\LightningDevice true Any valid North American DMA Code
lightning_device.location.country Device Country field string Lightning Device App\LightningDevice false
lightning_device.location.datetime_current Device Current Date/Time field datetime Lightning Device App\LightningDevice false
lightning_device.location.timezone Device Timezone field string Lightning Device App\LightningDevice false
lightning_device.location.timezone_offset_seconds Device Timezone Offset Seconds field integer Lightning Device App\LightningDevice false
lightning_device.getLatitudeLongitude Device Latitude/Longitude Location function geo_location Lightning Device App\LightningDevice false
lightning_device.cached_tags Device Tags field tags Lightning Device App\LightningDevice false

User fields

id label type dataType group objectClass enum docs_reference
user.name Name field string App\User false
user.email Email field string App\User false
user.title Title field string App\User false
user.roles Roles field string App\User false
user.can_log_in Can Log In field boolean App\User false
user.last_visit_seconds_ago Last Visit (seconds ago) field integer App\User false
has_visited_layout Has Visited field boolean App\User false
accounts.name Has Account with Name field array App\User false
accounts.account_class Has Account with Class field array App\User true
accounts.inventory_item_class Has Account with Inventory Item Class field array App\User true
agencies.name Has Agency with Name field array App\User false
accounts.has_active_campaigns Has Account with Active Campaigns field array App\User false
accounts.has_completed_campaigns Has Account with Completed Campaigns field array App\User false
accounts.has_never_run_a_campaign Has Account that have Never Run a Campaign field array App\User false
agencies.agency_class Has Agency with Class field array App\User true
user.has_accounts Has Accounts field boolean App\User false
user.has_agencies Has Agencies field boolean App\User false
user.has_created_drive_templates Has Created Templates field boolean App\User false
user.has_inventory_items Owns Creatives field boolean App\User false
user.has_created_inventory_items Has Created Creatives field boolean App\User false

Notes for AI-assisted authoring

  • Author the builder tree in filter_fields; function conditions can appear in that tree and do NOT require a nonempty filter_functions array. The current builder always emits filter_functions: [].
  • For screen filters, use digital_board_filter.filter_fields and digital_board_filter.filter_functions.
  • For item filters, the schedule entry is stored as part of a schedule array and should be keyed by type: "item_filter".
  • For export / inventory-item filtering in the Schedule Builder and Item Filter dialogs, include date/time logic plus the current account’s dynamic key/value fields in the item filter and digital-board filter payloads.
  • The Campaign Settings dialog item filter uses the InventoryFieldOptions catalog, while automation-only catalogs such as InventoryExportFields, AccountFields, UserFields, LightningDeviceFields, and InventoryFeedFields should not be assumed to be part of the standard item filter UI.
  • In order to determine the full slate of available fields for the item_filter and the digital_board_filter, you must query the available key/value fields for the account object and the digitalboard object. This is typically handled via the unique-key-value-store-keys endpoint on the accounts object and by passing in the correct object_type.
  • Use the objectClass and field_name / function_name values in this document as the canonical field identifiers that the UI accepts.
  • For enum-backed values, use the underlying API value rather than the display label; back-end enum conversion is handled by getEnumOptions.

Examples

All filter examples below include complete builder-shaped group flags and condition metadata, including correct field/function identifiers. They are logical objects before endpoint-layer serialization. Dynamic Weather1 and sports examples require the matching account/provider/feed keys; discover the actual identifiers before adapting them to another account or feed.

1. Show a creative when it is raining OR snowing

Expression: (condition_group = rain OR condition_group = snow). Rain matches, snow matches, a different group (e.g. clear) does not. Both predicates belong directly under the root OR; do not use AND between rain and snow on the same single-valued field.

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "or",
            "value": [
                {
                    "type": "filter_field",
                    "field_name": "digital_board.store.Weather1_current_condition_group_code",
                    "function_name": null,
                    "objectClass": "App\\DigitalBoard",
                    "value": "rain",
                    "operator": "equals",
                    "group": "Weather"
                },
                {
                    "type": "filter_field",
                    "field_name": "digital_board.store.Weather1_current_condition_group_code",
                    "function_name": null,
                    "objectClass": "App\\DigitalBoard",
                    "value": "snow",
                    "operator": "equals",
                    "group": "Weather"
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

2. Country restriction AND (rain OR snow)

Expression: (country = US AND (condition_group = rain OR condition_group = snow)). A US screen in rain or snow matches; a US screen in clear weather does not; a non-US screen never matches even when raining. This needs a root AND and a nested OR, both marked as groups.

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "type": "filter_field",
                    "field_name": "digital_board.location.country",
                    "function_name": null,
                    "objectClass": "App\\DigitalBoard",
                    "value": "US",
                    "operator": "equals",
                    "group": "Screen"
                },
                {
                    "field_name": "__logical_group",
                    "operator": "or",
                    "value": [
                        {
                            "type": "filter_field",
                            "field_name": "digital_board.store.Weather1_current_condition_group_code",
                            "function_name": null,
                            "objectClass": "App\\DigitalBoard",
                            "value": "rain",
                            "operator": "equals",
                            "group": "Weather"
                        },
                        {
                            "type": "filter_field",
                            "field_name": "digital_board.store.Weather1_current_condition_group_code",
                            "function_name": null,
                            "objectClass": "App\\DigitalBoard",
                            "value": "snow",
                            "operator": "equals",
                            "group": "Weather"
                        }
                    ],
                    "isDirty": true,
                    "isGroup": true
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

3. Complex working live campaign: weather AND venue restrictions

This reproduces the supplied working campaign structure and comparison values, including its intentional singleton groups. It is a reference for nesting and metadata, not a universal weather policy. Do not assume its dynamic fields are available on another account. The root AND has seven children: five weather groups, one direct venue condition, and one OR containing two AND branches. The final OR means either the venue is outside 401,40101,40102, or it is inside that set AND its agency name matches Zoom. It is NOT a global Zoom requirement.

Fully parenthesized expression (short aliases for the exact fields in the JSON below; uppercase operator names here are explanatory, not JSON tokens):

(
    (sun_is_up IS FALSE OR forecast_max_temp_f > 69)
    AND (sun_is_up IS FALSE OR current_temp_f < 80)
    AND (condition_code NOT_LIKE_ANY_OF "1183,1189,1195,1198,1201,1204,1207,1240,1243,1246,1249,1252,1276")
    AND (current_temp_f < 80 OR current_humidity < 60)
    AND (sun_is_up IS FALSE OR current_cloud < 80)
    AND venue_taxonomy_id NOT_ANY_OF "301,30101,30102,302,303"
    AND (
        (venue_taxonomy_id NOT_ANY_OF "401,40101,40102")
        OR (venue_taxonomy_id IS_ONE_OF "401,40101,40102" AND agency_name LIKE "Zoom")
    )
)

For example, when sun-up is false and temperature is below 80, the first, second, fourth, and fifth clauses match, but the excluded condition-code and venue clauses must still match independently. An allowed venue outside the 401 set does not need the Zoom name; a venue inside that set must also satisfy the agency-name condition (operator: "like", value: "Zoom"). Preserve < versus <= and > versus >=: exactly 80 does not satisfy < 80, and exactly 69 does not satisfy > 69.

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "field_name": "__logical_group",
                    "operator": "or",
                    "value": [
                        {
                            "type": "filter_field",
                            "field_name": "digital_board.store.Weather1_today_astro_is_sun_up",
                            "function_name": null,
                            "objectClass": "App\\DigitalBoard",
                            "value": "",
                            "operator": "is_false",
                            "group": "Weather"
                        },
                        {
                            "type": "filter_field",
                            "field_name": "digital_board.store.Weather1_forecast_maxtemp_f",
                            "function_name": null,
                            "objectClass": "App\\DigitalBoard",
                            "value": "69",
                            "operator": ">",
                            "group": "Weather"
                        }
                    ],
                    "isDirty": true,
                    "isGroup": true
                },
                {
                    "field_name": "__logical_group",
                    "operator": "or",
                    "value": [
                        {
                            "type": "filter_field",
                            "field_name": "digital_board.store.Weather1_today_astro_is_sun_up",
                            "function_name": null,
                            "objectClass": "App\\DigitalBoard",
                            "value": "",
                            "operator": "is_false",
                            "group": "Weather"
                        },
                        {
                            "type": "filter_field",
                            "field_name": "digital_board.store.Weather1_current_temp_f",
                            "function_name": null,
                            "objectClass": "App\\DigitalBoard",
                            "value": "80",
                            "operator": "<",
                            "group": "Weather"
                        }
                    ],
                    "isDirty": true,
                    "isGroup": true
                },
                {
                    "field_name": "__logical_group",
                    "operator": "or",
                    "value": [
                        {
                            "type": "filter_field",
                            "field_name": "digital_board.store.Weather1_current_condition_code",
                            "function_name": null,
                            "objectClass": "App\\DigitalBoard",
                            "value": "1183,1189,1195,1198,1201,1204,1207,1240,1243,1246,1249,1252,1276",
                            "operator": "not_like_any_of",
                            "group": "Weather"
                        }
                    ],
                    "isDirty": true,
                    "isGroup": true
                },
                {
                    "field_name": "__logical_group",
                    "operator": "or",
                    "value": [
                        {
                            "type": "filter_field",
                            "field_name": "digital_board.store.Weather1_current_temp_f",
                            "function_name": null,
                            "objectClass": "App\\DigitalBoard",
                            "value": "80",
                            "operator": "<",
                            "group": "Weather"
                        },
                        {
                            "type": "filter_field",
                            "field_name": "digital_board.store.Weather1_current_humidity",
                            "function_name": null,
                            "objectClass": "App\\DigitalBoard",
                            "value": "60",
                            "operator": "<",
                            "group": "Weather"
                        }
                    ],
                    "isDirty": true,
                    "isGroup": true
                },
                {
                    "field_name": "__logical_group",
                    "operator": "or",
                    "value": [
                        {
                            "type": "filter_field",
                            "field_name": "digital_board.store.Weather1_today_astro_is_sun_up",
                            "function_name": null,
                            "objectClass": "App\\DigitalBoard",
                            "value": "",
                            "operator": "is_false",
                            "group": "Weather"
                        },
                        {
                            "type": "filter_field",
                            "field_name": "digital_board.store.Weather1_current_cloud",
                            "function_name": null,
                            "objectClass": "App\\DigitalBoard",
                            "value": "80",
                            "operator": "<",
                            "group": "Weather"
                        }
                    ],
                    "isDirty": true,
                    "isGroup": true
                },
                {
                    "type": "filter_field",
                    "field_name": "digital_board.venue_taxonomy_id",
                    "function_name": null,
                    "objectClass": "App\\DigitalBoard",
                    "value": "301,30101,30102,302,303",
                    "operator": "not_any_of",
                    "group": "Screen"
                },
                {
                    "field_name": "__logical_group",
                    "operator": "or",
                    "value": [
                        {
                            "field_name": "__logical_group",
                            "operator": "and",
                            "value": [
                                {
                                    "type": "filter_field",
                                    "field_name": "digital_board.venue_taxonomy_id",
                                    "function_name": null,
                                    "objectClass": "App\\DigitalBoard",
                                    "value": "401,40101,40102",
                                    "operator": "not_any_of",
                                    "group": "Screen"
                                }
                            ],
                            "isDirty": true,
                            "isGroup": true
                        },
                        {
                            "field_name": "__logical_group",
                            "operator": "and",
                            "value": [
                                {
                                    "type": "filter_field",
                                    "field_name": "digital_board.venue_taxonomy_id",
                                    "function_name": null,
                                    "objectClass": "App\\DigitalBoard",
                                    "value": "401,40101,40102",
                                    "operator": "is_one_of",
                                    "group": "Screen"
                                },
                                {
                                    "type": "filter_field",
                                    "field_name": "digital_board.agency.name",
                                    "function_name": null,
                                    "objectClass": "App\\DigitalBoard",
                                    "value": "Zoom",
                                    "operator": "like",
                                    "group": "Screen"
                                }
                            ],
                            "isDirty": true,
                            "isGroup": true
                        }
                    ],
                    "isDirty": true,
                    "isGroup": true
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

4. Function condition within the builder tree

Expression: (basePhotoCount >= 1). The catalog marks this identifier as a function, so the leaf uses type: "filter_function", field_name: null, and function_name: "basePhotoCount". The envelope still has an empty filter_functions array.

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "type": "filter_function",
                    "field_name": null,
                    "function_name": "basePhotoCount",
                    "objectClass": "App\\InventoryItem",
                    "value": 1,
                    "operator": ">="
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

5. Sports data-source filter: no MLB games scheduled for the configured teams

Expression: (feed_no_games_scheduled IS TRUE). Activate this creative only when the configured MLB data-source feed reports no games scheduled for its selected team or teams. Games involving other teams outside that feed do not change the scope of this predicate. A false flag does not activate it; a missing flag must not be interpreted as true. This reproduces the supplied LF1092 account-store key; discover the actual key for another feed.

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "type": "filter_field",
                    "field_name": "account.store.MlbLiveGameScoresAllGames_LF1092_retriever_no_games_scheduled",
                    "function_name": null,
                    "objectClass": "App\\Account",
                    "value": "",
                    "operator": "is_true",
                    "group": "MLB Live Game Scores (All Games)"
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

6. Sports data-source filter: NCAA games today AND all games still in pregame

Expression: (feed_all_games_in_pregame IS TRUE AND feed_has_games_today IS TRUE). Activate this creative only when there are games today within the configured NCAA feed AND all those games have not yet started. Both conditions use the same LF1174 feed. Keep the root AND and both predicates; do not replace it with OR or drop has_games_today. Either a false pregame flag or a false games-today flag prevents activation.

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "type": "filter_field",
                    "field_name": "account.store.NcaaCollegeFootballLiveGameScoresAllGames_LF1174_retriever_all_games_in_pregame",
                    "function_name": null,
                    "objectClass": "App\\Account",
                    "value": "",
                    "operator": "is_true",
                    "group": "NCAA College Football Live Game Scores (All Games)"
                },
                {
                    "type": "filter_field",
                    "field_name": "account.store.NcaaCollegeFootballLiveGameScoresAllGames_LF1174_retriever_has_games_today",
                    "function_name": null,
                    "objectClass": "App\\Account",
                    "value": "",
                    "operator": "is_true",
                    "group": "NCAA College Football Live Game Scores (All Games)"
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

7. Sports data-source filter: Baltimore Ravens won their game today

Expression: (feed_team_result_baltimore_ravens_won IS TRUE). Activate this creative when the configured NFL feed reports that the Baltimore Ravens won their game today, subject to the feed's current-day result semantics. A false result flag does not activate it; another team's win is not a substitute. This reproduces the supplied LF1387 key. Team-result keys are dynamic: configure the sports data source, run it once with valid data, and inspect/discover the resulting key rather than constructing a key from a team name.

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "type": "filter_field",
                    "field_name": "account.store.NflLiveGameScoresAllGames_LF1387_retriever_team_result_baltimore_ravens_won",
                    "function_name": null,
                    "objectClass": "App\\Account",
                    "value": "",
                    "operator": "is_true",
                    "group": "NFL Live Game Scores (All Games)"
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

8. Simple text search for inventory item title

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "type": "filter_field",
                    "field_name": "title",
                    "function_name": null,
                    "objectClass": "App\\InventoryItem",
                    "value": "ford",
                    "operator": "like"
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

9. Numeric comparison on price

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "type": "filter_field",
                    "field_name": "price",
                    "function_name": null,
                    "objectClass": "App\\InventoryItem",
                    "value": 25000,
                    "operator": ">="
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

10. Boolean condition for new vs used inventory

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "type": "filter_field",
                    "field_name": "new_used",
                    "function_name": null,
                    "objectClass": "App\\InventoryItem",
                    "value": true,
                    "operator": "equals"
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

11. Multiple tag match with OR logic

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "or",
            "value": [
                {
                    "type": "filter_field",
                    "field_name": "cached_tags",
                    "function_name": null,
                    "objectClass": "App\\InventoryItem",
                    "value": "truck,commercial",
                    "operator": "like_one_of"
                },
                {
                    "type": "filter_field",
                    "field_name": "cached_tags",
                    "function_name": null,
                    "objectClass": "App\\InventoryItem",
                    "value": "fleet,local",
                    "operator": "like_all_of"
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

12. Date and time condition for a future campaign window

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "type": "filter_field",
                    "field_name": "inventory_export.last_run_at",
                    "function_name": null,
                    "objectClass": "App\\InventoryExport",
                    "value": "",
                    "operator": "datetime_is_future"
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

13. Screen filter for a specific country and format

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "type": "filter_field",
                    "field_name": "digital_board.location.country",
                    "function_name": null,
                    "objectClass": "App\\DigitalBoard",
                    "value": "US",
                    "operator": "equals",
                    "group": "Screen"
                },
                {
                    "type": "filter_field",
                    "field_name": "digital_board.digital_board_format",
                    "function_name": null,
                    "objectClass": "App\\DigitalBoard",
                    "value": "bulletin",
                    "operator": "equals",
                    "group": "Screen"
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

14. Geo radius filter for a local ad area

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "type": "filter_function",
                    "field_name": null,
                    "function_name": "digital_board.getLatitudeLongitude",
                    "objectClass": "App\\DigitalBoard",
                    "value": [
                        {
                            "id": "radius-1",
                            "geo_source": "map_drawing",
                            "geo_type": "radius",
                            "label": "Downtown radius",
                            "centerpoint": {
                                "lat": 40.7128,
                                "long": -74.006
                            },
                            "units": "m",
                            "radius": 5000
                        }
                    ],
                    "operator": "is_within_geo",
                    "group": "Screen"
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

15. Geo polygon filter for a service area

{
    "filter_fields": [
        {
            "field_name": "__logical_group",
            "operator": "and",
            "value": [
                {
                    "type": "filter_function",
                    "field_name": null,
                    "function_name": "digital_board.getLatitudeLongitude",
                    "objectClass": "App\\DigitalBoard",
                    "value": [
                        {
                            "id": "poly-1",
                            "geo_source": "map_drawing",
                            "geo_type": "polygon",
                            "label": "City polygon",
                            "coordinates": [
                                [
                                    40.75,
                                    -74.01
                                ],
                                [
                                    40.78,
                                    -73.95
                                ],
                                [
                                    40.72,
                                    -73.9
                                ],
                                [
                                    40.7,
                                    -74.02
                                ]
                            ]
                        }
                    ],
                    "operator": "is_within_geo",
                    "group": "Screen"
                }
            ],
            "isDirty": true,
            "isGroup": true
        }
    ],
    "filter_functions": []
}

16. Schedule/export filter example: date range, day-of-week, time-range, and item filter

{
    "filter": [
        {
            "type": "days_of_the_week",
            "start_datetime": null,
            "end_datetime": null,
            "start_time": null,
            "end_time": null,
            "days": [
                1,
                2,
                3,
                4,
                5
            ],
            "filter_fields": null,
            "filter_functions": null
        },
        {
            "type": "date_range",
            "start_datetime": "2026-01-01T00:00:00Z",
            "end_datetime": "2026-12-31T23:59:59Z",
            "start_time": null,
            "end_time": null,
            "days": null,
            "filter_fields": null,
            "filter_functions": null
        },
        {
            "type": "time_range",
            "start_datetime": null,
            "end_datetime": null,
            "start_time": "2026-01-01T09:00:00Z",
            "end_time": "2026-01-01T17:00:00Z",
            "days": null,
            "filter_fields": null,
            "filter_functions": null
        },
        {
            "type": "item_filter",
            "start_datetime": null,
            "end_datetime": null,
            "start_time": null,
            "end_time": null,
            "days": null,
            "filter_fields": [
                {
                    "field_name": "__logical_group",
                    "operator": "and",
                    "value": [
                        {
                            "type": "filter_field",
                            "field_name": "account.lcuid",
                            "function_name": null,
                            "objectClass": "App\\InventoryItem",
                            "value": "LA_EXAMPLE_ACCOUNT",
                            "operator": "equals"
                        },
                        {
                            "type": "filter_field",
                            "field_name": "account.name",
                            "function_name": null,
                            "objectClass": "App\\Account",
                            "value": "retail",
                            "operator": "like"
                        }
                    ],
                    "isDirty": true,
                    "isGroup": true
                }
            ],
            "filter_functions": []
        }
    ]
}

17. Board filter example: country, board format, and geo radius

{
    "digital_board_filter": {
        "filter_fields": [
            {
                "field_name": "__logical_group",
                "operator": "and",
                "value": [
                    {
                        "type": "filter_field",
                        "field_name": "digital_board.location.country",
                        "function_name": null,
                        "objectClass": "App\\DigitalBoard",
                        "value": "US",
                        "operator": "equals",
                        "group": "Screen"
                    },
                    {
                        "type": "filter_field",
                        "field_name": "digital_board.digital_board_format",
                        "function_name": null,
                        "objectClass": "App\\DigitalBoard",
                        "value": "bulletin",
                        "operator": "equals",
                        "group": "Screen"
                    },
                    {
                        "type": "filter_function",
                        "field_name": null,
                        "function_name": "digital_board.getLatitudeLongitude",
                        "objectClass": "App\\DigitalBoard",
                        "value": [
                            {
                                "id": "radius-geo",
                                "geo_source": "map_drawing",
                                "geo_type": "radius",
                                "label": "Downtown catchment",
                                "centerpoint": {
                                    "lat": 40.7128,
                                    "long": -74.006
                                },
                                "units": "m",
                                "radius": 7500
                            }
                        ],
                        "operator": "is_within_geo",
                        "group": "Screen"
                    }
                ],
                "isDirty": true,
                "isGroup": true
            }
        ],
        "filter_functions": []
    }
}