duration
A duration is a bare integer of minutes and the unit is on the site: GET /preferences gives hours_per_day and duration_units. A Float truncates toward zero at 200, so round before writing.
Data type duration, probed on Shot.sg_bid___total.
| field | access |
|---|---|
Shot.sg_bid___total, Shot.sg_bid___ani/___comp/___fx/___lit |
stock, editable |
Task.duration, Task.est_in_mins, TimeLog.duration |
stock, editable |
Task.time_logs_sum, Task.time_vs_est |
read-only |
Unit The stored integer is minutes. The field schema names no unit: properties holds
default_value and summary_default and nothing else.
GET /schema/Shot/fields/sg_bid___total
properties keys: ['default_value', 'summary_default']
{"default_value": {"value": null, "editable": false},
"summary_default": {"value": "none", "editable": true}}
Task/fields/duration properties={"default_value": null, "summary_default": "sum"}
Task/fields/est_in_mins properties={"default_value": null, "summary_default": "sum"}
TimeLog/fields/duration properties={"default_value": 0, "summary_default": "sum"}
| evidence | reading |
|---|---|
the stock field is named est_in_mins |
the one place the API states a unit |
Task.time_logs_sum 246 = sum of TimeLog.duration [180, 66]; 247 = sum of [60, 120, 45, 22] |
same unit, plain addition |
500 Task.duration on demo_show: gcd 600, distinct [0, 600, 1200, … 6000] |
10-hour multiples, not whole days |
GET /preferences returns 200 with 17 keys, two of them about durations. On the probed site
hours_per_day is 8.0 and duration_units is "days": render days as minutes / (60 * hours_per_day).
Read A plain JSON integer under attributes, never a string and never wrapped. An unset field is
null.
duration=2400(int) est_in_mins=360(int) time_logs_sum=246(int)
Write PUT /entity/shots/<id> with Content-Type: application/json and a bare
{"sg_bid___total": 90}; POST /entity/shots takes the same value shape. The accepted set is stated in
the rejection: [String, Integer, NilClass, Float], one member wider than number.
| sent | result |
|---|---|
90, 1440, -30 |
200, reads back unchanged |
"90" |
200, reads back 90 |
" 90 " |
200, reads back 90; whitespace stripped |
null |
200, reads back null |
2147483647 (2**31-1) |
200, exact |
2147483648 |
400 Update failed for [Shot.sg_bid___total]: Invalid statement. |
1.5 |
200, stored as 1 |
90.4, 90.5, 90.6, 90.9 |
200, stored as 90 |
-1.5, -90.6 |
200, stored as -1, -90 |
0.4 |
200, stored as 0, not null |
"2:30", "1h", "90m", "1d", "" |
400 Invalid data for 'duration' data type |
true |
400 API update() Shot.sg_bid___total expected [String, Integer, NilClass, Float] data type(s) but got TrueClass: true |
A Float truncates toward zero, with no rounding.
PUT sg_bid___total="2:30" -> 400
{"status": 400, "code": 103, "title": "Invalid data for 'duration' data type",
"source": {"sg_bid___total": "Invalid data for 'duration' data type. Value: 2:30"},
"detail": null, "meta": null}
Clear
| sent | result |
|---|---|
null |
cleared, reads back None |
0 |
200, stored as 0; a value, not a clear |
"" |
400 Invalid data for 'duration' data type. Value: ; the old value survives |
| never set | reads None |
Filter POST /entity/shots/_search, Content-Type: application/vnd+shotgun.api3_array+json.
A bogus relation 400s with the whole vocabulary (probe 017), the same list number returns:
Valid relations: ["is", "is_not", "greater_than", "less_than", "between", "in", "not_in"]
There is no >= or <=: bracket with between, or shift the bound by one.
Against 4 sandbox rows holding 480, 0, null, null:
| 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' |
Each of those two 400s repeats the sent filter and the Valid relations list above under source.
Traps
- The unit is on the site, not on the field. No
/schemaroute names it. Readhours_per_dayandduration_unitsonce fromGET /preferences, then render. - A Float truncates instead of failing.
number400s on3.7(field_types/number);durationtakes90.9and stores90. Round before writing an average, a ratio ortotal/2. "2:30"is not a duration. The only string the API accepts is one that parses as a number.- Negation includes nulls; comparison excludes them.
is_not 480andnot_in [999999]return the null rows too (3 and 4 of 4);greater_than -1returns only the 2 rows holding a value. A row holding0isis_not None, so a field full of zeroes scans as fully populated (probe 007); rank bygreater_than 0.