Filters
The relations each data_type accepts in a filter, and the value to send with each
one. Every list here is the API's own, taken from the 400 it returns when sent an operator it
does not know.
Read out of the field-type cards when this page is built, so the two cannot disagree. An unknown operator is always a 400 and never a silent no-op, so a typo in a filter cannot pass as "no filter". Measured by probe 017.
Operators, by family
Text
The only family with a substring vocabulary.
| Data type | Relations |
|---|---|
| text |
|
Temporal
There is no not_between and no is_null. All 2 return the identical list of 15.
| Data type | Relations |
|---|---|
| date |
|
| date_time |
|
Numeric
There is no >= and no <=. Bracket with between, or shift the bound by one. All 5 return the identical list of 7.
Entity
Trades the substring operators for name_* and type_is. All 2 return the identical list of 9.
| Data type | Relations |
|---|---|
| entity |
|
| multi_entity |
|
Containment
contains tests containment of a whole structure, not of a substring.
| Data type | Relations |
|---|---|
| jsonb |
|
List-like
Equality and set membership, on the stored code rather than the display name. All 5 return the identical list of 4.
| Data type | Relations |
|---|---|
| color |
|
| entity_type |
|
| list |
|
| status_list |
|
| uuid |
|
Presence
Two relations. Which values they accept is per type; the card says. All 3 return the identical list of 2.
| Data type | Relations |
|---|---|
| checkbox |
|
| image |
|
| pivot_column |
|
Not filterable
The 400 names no vocabulary, because there is none. Page the rows and compare in the client.
| Data type | Relations |
|---|---|
| calculated | No relation is accepted. |
| password | No relation is accepted. |
| serializable | No relation is accepted. |
| summary | No relation is accepted. |
| url | No relation is accepted. |
Values, by data type
272 rows across 24 data types. A matrix has one row per value shape, so an
operator can appear more than once, and it includes the operators the API refuses, whose matches is the 400. One row reads not measured: the operator is in the API's own list and the card
never sent it.
calculated
No relation is accepted.
checkbox
2 operators, 4 rows.
| Operator | Value | Matches |
|---|---|---|
is | true | ticked rows; "true" returns the same ids |
is | false | unticked rows; "false" returns the same ids |
is_not | true | unticked rows |
is_not | false | ticked rows |
color
4 operators, 9 rows.
| Operator | Value | Matches |
|---|---|---|
is | "pipeline_step" | 1900 of 1900, the stored keyword |
is | "PIPELINE_STEP" | 0; the value is case-sensitive |
is | "0,126,174" | 0; no Task stores a triple |
is | [0, 126, 174] | 400 'is' 'relation' expects a 1-element array: [0, 126, 174] |
is_not | "pipeline_step" | 0 |
is_not | null | 1900, every row holds a value |
in | "pipeline_step" (bare, outside a list) | accepted, a scalar where a list is expected |
in | ["zzprobe_nope"] | 0, the negative control |
not_in | ["pipeline_step"] | 0 |
date
15 operators, 15 rows. The card also records measured.
| Operator | Value | Matches |
|---|---|---|
is | "2026-09-02", null or "" | exact date |
is_not | "2026-09-02", null or "" | any other date, and null rows |
greater_than | "2026-09-02" | strictly after |
less_than | "2026-09-02" | strictly before |
between | ["2026-09-01", "2026-09-03"] | inside the range, inclusive both ends, order-insensitive |
in | ["2026-09-02"] | any listed date; a bare scalar also works |
not_in | ["2026-09-02"] | any unlisted date, and null rows; a bare scalar also works |
in_last | [10, "DAY"] | n units back, includes today; n positive, unit uppercase |
not_in_last | [10, "DAY"] | outside that range, and null rows |
in_next | [10, "DAY"] | n units forward, includes today |
not_in_next | [10, "DAY"] | outside that range, and null rows |
in_calendar_day | 0 | that calendar day, from a bare signed offset; [0] works too |
in_calendar_week | 0 | that calendar week |
in_calendar_month | 0 | that calendar month |
in_calendar_year | 0 | that calendar year |
date_time
15 operators, 23 rows.
| Operator | Value | Matches |
|---|---|---|
is | "2026-03-04T05:06:07Z" | 1 |
is | "2099-01-01T00:00:00Z" | 0 |
is | null | 0 |
is_not | "2026-03-04T05:06:07Z" | 0 |
greater_than | "2026-03-04T00:00:00Z" | 1 |
greater_than | "2026-03-05T00:00:00Z" | 0 |
less_than | "2026-03-05T00:00:00Z" | 1 |
less_than | "2026-03-04T00:00:00Z" | 0 |
between | ["2026-03-04T00:00:00Z", "2026-03-05T00:00:00Z"] | 1 |
between | ["1970-01-01T00:00:00Z", "1971-01-01T00:00:00Z"] | 0 |
in | ["2026-03-04T05:06:07Z"] | 1 |
in | ["2099-01-01T00:00:00Z"] | 0 |
not_in | ["2026-03-04T05:06:07Z"] | 0 |
in_last | [100, "YEAR"] | 1 |
not_in_last | [100, "YEAR"] | 0 |
in_next | [100, "YEAR"] | 0 |
not_in_next | [100, "YEAR"] | 1 |
in_calendar_year | 0 | 1 |
in_calendar_year | -50 | 0 |
in_calendar_day | 0 | 0; March 4 is a past day |
in_calendar_week | 0 | 0; a past week |
in_calendar_month | 0 | 0; a past month |
in_last | [1, "FORTNIGHT"] | 400 API read() 'in_last' 'relation' doesn't support the 'FORTNIGHT' time unit: [1, "FORTNIGHT"] Valid time units: ["HOUR", "DAY", "WEEK", "MONTH", "YEAR"] |
duration
7 operators, 22 rows.
| Operator | Value | Matches |
|---|---|---|
is | 480 | 1, the row holding it |
is | "480", 480.0, 480.6 | 1 each, the same row; a string and a float both coerce |
is | 0 | 1 |
is | None | 2; the row holding 0 is not matched |
is | "8:00" | 400 Invalid data for 'duration' data type. Value: 8:00 |
is_not | 480 | 3 |
is_not | None | 2 |
greater_than | 0 | 1 |
greater_than | 480 | 0 |
greater_than | -1 | 2 |
less_than | 480 | 1 |
less_than | 1 | 1 |
between | [0, 600] | 2 |
between | [600, 900] | 0 |
between | 480 | 400 API read() 'between' 'relation' expects a 2-element array: [480] |
in | [480, 0] | 2 |
in | ["480"] | 1 |
in | [999999] | 0 |
not_in | [480] | 3 |
not_in | [999999] | 4 |
contains | "48" | 400 API read() Shot.sg_bid___total's 'duration' data type doesn't support 'contains' 'relation' |
not_between | [0, 600] | 400 API read() Shot.sg_bid___total's 'duration' data type doesn't support 'not_between' 'relation' |
entity
9 operators, 9 rows.
| Operator | Value | Matches |
|---|---|---|
is | {"type": "Shot", "id": 862} | 3; null 0 |
is_not | {"type": "Shot", "id": 862} | 97; null 100 |
in | [{"type": "Shot", "id": 862}], or a bare hash | 3 for one hash, 6 for two |
not_in | [{"type": "Shot", "id": 862}], or a bare hash | 97 for one hash, 94 for two |
type_is | "Shot" | 99; a name string 0; null 0 |
type_is_not | "Shot" | 1; a name string 100; null 100 |
name_is | "sh010_0010" | 3; a type string 0 |
name_contains | "sh010_0010" | 3; a type string 0 |
name_not_contains | "sh010_0010" | 97; a type string 100 |
entity_type
4 operators, 17 rows.
| Operator | Value | Matches |
|---|---|---|
is | "Shot" | 12 |
is | "shot" (wrong case) or "shots" (REST slug) | 0 |
is | "ZzprobeNotAType", or a real type with no rows | 0 |
is | null or "" | 0 |
is_not | "Shot" | 23 |
is_not | null | 35 |
in | ["Shot", "Asset"] | 25 |
in | ["Shot", "ZzprobeNotAType"] | 12; the junk member is dropped, no error |
in | "Shot" (bare, not a list) | 12; a scalar is accepted where a list is expected |
in | ["ZzprobeNotAType"] | 0 |
not_in | ["Shot"] | 23 |
is | {"type": "Shot", "id": 1} | 400 expected [String, NilClass] data type(s) but got ActionDispatch::Http::ParamsHashWithIndifferentAccess |
in | {"type": "Shot", "id": 1} | 400, the same body |
contains | any | 400, same "doesn't support ... 'relation'" body |
starts_with | any | 400, the same body |
name_is | any | 400, the same body |
type_is | any | 400, the same body |
float
7 operators, 16 rows.
| Operator | Value | Matches |
|---|---|---|
is | 1.0 (Float) | 1 |
is | '1.0' (String) | 1 |
is | 0.0 | 1 |
is | None | 1 |
is_not | None | 2 |
greater_than | 0.0 | 1 |
less_than | 2.0 | 2 |
between | [0.0, 2.0] | 2 |
in | [1.0, 0.0] | 2 |
not_in | [1.0] | 2; includes the null row, unlike SQL NOT IN |
is | 99999.5 | 0 |
in | [99999.5] | 0 |
greater_than | 1e9 | 0 |
is | 1 (Integer) | 400 API read() ... expected [String, BigDecimal, Float, NilClass] data type(s) but got Integer: 1 |
greater_than | 0 (Integer) | 400, same error |
in | [1] (Integer) | 400, same error |
image
2 operators, 6 rows. The card also records code.
| Operator | Value | Matches |
|---|---|---|
is | null | 99 of 100 Versions, no thumbnail |
is_not | null | 1 of 100, has one, transcoded or not |
is | "" | 'is' 'relation' expects a nil value for 'image' data type: [""] |
is | "https://x/y.png" | same, … data type: ["https://x/y.png"] |
contains | "thumb" | doesn't support 'contains' … ["is", "is_not"] |
in | [null] | doesn't support 'in' … ["is", "is_not"] |
jsonb
4 operators, 6 rows.
| Operator | Value | Matches |
|---|---|---|
is | {"a":{"b":[1,2,3]}} | whole-value equality; key order in the filter is irrelevant |
is | an array, or null | the same equality, on those classes |
is_not | {"a":{"b":[1,2,3]}} | every other row, null rows included |
contains | {"a":{"b":[1]}} | containment: matches a stored {"a":{"b":[1,2,3]}} |
contains | {} | every row holding an object; array and null rows do not match |
not_contains | {"a":{"b":[1]}} | every other row, null rows included |
list
4 operators, 16 rows.
| Operator | Value | Matches |
|---|---|---|
is | 'Type A' | 99 |
is | 'type a' (wrong case) | 99 |
is | 'zzprobe_...' (not in schema) | 0 |
is | null | 1 |
is_not | 'Type A' | 1 |
is_not | null | 99 |
in | ['Type A'] | 99 |
in | ['Type A', 'Type B'] | 99 |
in | ['zzprobe_...'] (not in schema) | 0 |
in | ['Type A', 'zzprobe_...'] | 99, the union of the members, no error |
in | 'Type A' (bare, not a list) | 99; a scalar is accepted where a list is expected |
not_in | ['Type A'] | 1 |
contains | any | 400, same "doesn't support ... 'relation'" body |
not_contains | any | 400, the same body |
starts_with | any | 400, the same body |
ends_with | any | 400, the same body |
multi_entity
9 operators, 19 rows.
| Operator | Value | Matches |
|---|---|---|
is | A | AB A_only |
is | None | empty |
is | {"type": "Version", "id": 99999999} | none |
is | [A, B] | 400 API read() 'is' 'relation' expects a 1-element array: [...] |
is_not | A | B_only empty |
is_not | None | AB A_only B_only |
in | [A] | AB A_only |
in | [A, B] | AB A_only B_only |
in | [] | 400 API read() 'in' 'relation' expects at least a 1-element array: [] |
in | [26342], a bare id | 400 invalid/missing entity hash: 26342 |
in | [{"id": <A>}] | 400 missing 'type' |
not_in | [A] | B_only empty |
not_in | [A, B] | empty |
type_is | "Version" | AB A_only B_only |
type_is_not | "Version" | empty |
name_is | <A's code> | AB A_only |
name_contains | "_target_a" | AB A_only |
name_contains | "ZZZNOPE" | none |
name_not_contains | not measured | not measured |
number
7 operators, 19 rows.
| Operator | Value | Matches |
|---|---|---|
is | 1001 | 1 |
is | 0 | 1 |
is | '1001' | 1 |
is | None | 2; 0 is not matched |
is_not | 1001 | 3 |
is_not | None | 2 |
greater_than | 0 | 1 |
greater_than | -1 | 2 |
less_than | 1 | 1 |
less_than | 1001 | 1 |
in | [1001, 0] | 2 |
in | ['1001'] | 1 |
in | [999999] | 0 (negative control) |
not_in | [1001] | 3 |
not_in | [999999] | 4 |
between | [0, 2000] | 2 |
between | [2000, 3000] | 0 (negative control) |
between | 1001 | 400 API read() 'between' 'relation' expects a 2-element array: [1001] |
contains | '100' | 400 API read() Version.sg_first_frame's 'number' data type doesn't support 'contains' 'relation' |
password
No relation is accepted.
percent
7 operators, 15 rows.
| Operator | Value | Matches |
|---|---|---|
is | 50 | 2 |
is | 0 | 1 |
is | null | 2 |
is | 99999 | 0 |
is_not | 50 | 3 |
is_not | null | 3 |
in | [50, 0] | 3 |
in | [99999] | 0 |
not_in | [50] | 3 |
greater_than | 0 | 2 |
greater_than | -1 | 3 |
less_than | 1 | 1 |
less_than | 100 | 3 |
between | [0, 100] | 3 |
between | [200, 300] | 0 |
pivot_column
2 operators, 3 rows.
| Operator | Value | Matches |
|---|---|---|
is | null | 400 code 103 |
is | "fin" | 400 code 103 |
is_not | null | 400 code 103 |
serializable
No relation is accepted.
status_list
4 operators, 14 rows.
| Operator | Value | Matches |
|---|---|---|
is | "rev" | 29 |
is | "Pending Review" (display label) | 0 |
is | "zznope" (not in valid_values) | 0 |
is | "part" (hidden in the project) | 0 |
is | null | 0 (the sandbox rows cleared above matched 1) |
is_not | "rev" | 71 |
in | ["rev", "fin"] | 31 |
in | ["Pending Review", "Final"] | 0 |
in | ["zznope"] | 0 |
not_in | ["rev", "fin"] | 69 |
contains | "re" | 400 doesn't support ... 'relation' |
not_contains | "re" | 400, the same body |
starts_with | "r" | 400, the same body |
ends_with | "v" | 400, the same body |
summary
No relation is accepted.
text
8 operators, 21 rows.
| Operator | Value | Matches |
|---|---|---|
is | 'lighting' | value |
is | 'LIGHTING' | value; case-blind |
is | None | empty, null, omitted |
is | '' | empty, null, omitted; identical to is None |
is_not | 'lighting' | empty, null, omitted; null rows included |
is_not | None or '' | value |
contains | 'ight' | value |
contains | 'IGHT' | value; case-blind |
contains | '' | value; "has any value", not everything |
not_contains | 'ight' | empty, null, omitted |
starts_with | 'light' | value |
ends_with | 'ing' | value |
in | ['lighting','comp'] | value |
in | 'lighting' | value; a bare string is accepted where a list is expected, and matched whole. A fifth row holding 'g' is not returned |
in | [''] | nothing, unlike is '' |
in | [None] | 400 code 104 Read failed for entity type [Version], source null, detail null |
not_in | ['lighting'] | empty, null, omitted |
is | 'ZZZNOPE' | nothing; the baseline is 4 |
contains | 'ZZZNOPE' | nothing |
starts_with | 'ZZZNOPE' | nothing |
in | 'ZZZNOPE' | nothing |
timecode
7 operators, 23 rows.
| Operator | Value | Matches |
|---|---|---|
is | 3600000 | 1 |
is | 0 | 1 |
is | None | 2; the row holding 0 is not matched |
is | "01:00:00:00" | 400 expected [Integer, NilClass] data type(s) but got String: "01:00:00:00" |
is | "3600000", 3600000.0 | 400, the same message with String: "3600000" and Float: 3600000.0 |
is_not | 3600000 | 3 |
is_not | None | 2 |
greater_than | 0 | 1 |
greater_than | 3600000 | 0 |
greater_than | -1 | 2 |
less_than | 3600000 | 1 |
less_than | 1 | 1 |
between | [0, 7200000] | 2 |
between | [7200000, 9000000] | 0 |
between | 3600000 | 400 API read() 'between' 'relation' expects a 2-element array: [3600000] |
in | [3600000, 0] | 2 |
in | [999999999] | 0 |
in | ["3600000"] | 400 expected [Integer, NilClass] data type(s) but got String: "3600000" |
not_in | [3600000] | 3 |
not_in | [999999999] | 4 |
contains | "3600" | 400 API read() Sequence.sg_timecode's 'timecode' data type doesn't support 'contains' 'relation' |
starts_with | "01" | 400, the same body |
not_between | [0, 10] | 400, the same body |
url
No relation is accepted.
uuid
4 operators, 15 rows. The card also records filled rows returned and null rows returned.
| Operator | Value | Matches |
|---|---|---|
is | "11111111-2222-11df-8888-999999999999" | the one row holding it |
is | "" | the rows where the field is null |
is_not | "11111111-2222-11df-8888-999999999999" | every other row, null rows included |
is_not | "" | every row holding a uuid |
in | ["11111111-2222-11df-8888-999999999999", "22222222-3333-11DF-8888-999999999999"] | the rows holding either, mixed case and hyphenation |
in | "11111111-2222-11df-8888-999999999999" (bare, not a list) | one row; a scalar where a list is expected |
in | [] | 400 code 103 API read() 'in' 'relation' expects at least a 1-element array: [] |
in | [""] | 400 code 104, invalid input syntax for type uuid: "" |
in | [null] | 400 code 103, expected [String] data type(s) but got NilClass: nil |
not_in | ["11111111-2222-11df-8888-999999999999", "22222222-3333-11DF-8888-999999999999"] | every other row, null rows included |
contains | any | 400, the Valid relations list again |
not_contains | any | 400, the same body |
starts_with | any | 400, the same body |
ends_with | any | 400, the same body |
greater_than | any | 400, the same body |