date_time
Stored and read as UTC YYYY-MM-DDTHH:MM:SSZ: a written offset is silently normalised, a zoneless string is taken as UTC, and a date-only filter value means midnight UTC, not the whole day.
Data type date_time, probed on Version.client_approved_at (stock, editable).
Across Version, Project, Shot, Task, Note, 3 of 14 date_time fields are editable: true:
Version.client_approved_at, Version.media_center_import_time,
Project.last_accessed_by_current_user. created_at/updated_at and the rest are server-managed. The
name does not predict it (client_approved_at is writable, viewed_by_current_user_at is not); read the
schema's editable flag.
Read Plain string in attributes, never relationships, identical from GET /entity/versions and
POST /entity/versions/_search:
created_at='2026-01-23T20:43:39Z' updated_at='2026-03-16T07:54:00Z'
Always YYYY-MM-DDTHH:MM:SSZ: second resolution, literal trailing Z, no numeric offset and no
site-local zone. A Version created at client UTC 2026-09-02T15:58:53.5Z read back
created_at='2026-09-02T15:58:53Z': 0.5s truncated, the same instant.
Write PUT /entity/versions/<id> with a JSON string.
| sent | result |
|---|---|
"2026-03-04T05:06:07Z" |
200, read back 2026-03-04T05:06:07Z |
"2026-03-04T05:06:07+05:00" |
200, read back 2026-03-04T00:06:07Z |
"2026-03-04T05:06:07-08:00" |
200, read back 2026-03-04T13:06:07Z |
"2026-03-04T05:06:07" |
200, read back 2026-03-04T05:06:07Z; zoneless is UTC |
"2026-03-04T05:06:07.123Z" |
200, read back 2026-03-04T05:06:07Z; sub-second dropped |
"2026-03-04" |
200, read back 2026-03-04T00:00:00Z |
"2026-03-04 05:06:07" |
400 Invalid date time format: 2026-03-04 05:06:07. Correct format is 2011-01-21T13:26:09Z (UTC), 2011-01-21T13:26:09-07:00 (UTC Offset) or any ISO8601 compatible string. |
"1772600767" (epoch string) |
400, same Invalid date time format message |
"not-a-time" |
400, same Invalid date time format message |
1772600767 (epoch int) |
400 API update() Version.client_approved_at expected [String, NilClass] data type(s) but got Integer: 1772600767 |
{"created_at": "2020-01-01T00:00:00Z"} |
400, code 103, API update() Version.created_at is editable on create only. |
A POST is the other half: created_at and updated_at are accepted in a create body and stored
exactly as sent, on Note, Task and Version, and created_at on Reply, although the schema flags
both editable: false (probe 070).
| timestamp, sent to | result |
|---|---|
POST /entity/<type> |
stored as sent; {"created_at": null} is 201 and leaves the row undated |
PUT /entity/<type>/<id> |
400 API update() <Type>.<field> is editable on create only. |
POST /entity/replies with updated_at |
400 API create() Reply.updated_at doesn't exist. |
Clear
| sent | result |
|---|---|
null |
cleared, reads back None |
"" |
400 Invalid date time format: . Correct format is 2011-01-21T13:26:09Z (UTC), 2011-01-21T13:26:09-07:00 (UTC Offset) or any ISO8601 compatible string. |
A cleared field is matched by ["field", "is", null] (1) and excluded by is_not null (0).
Filter The bogus-operator 400 (probe 017) on Version.created_at:
"title": "API read() Version.created_at's 'date_time' data type doesn't support
'definitely_not_an_operator' 'relation'",
"source": {"Version.created_at": " ... Valid relations: [\"is\", \"is_not\", \"greater_than\",
\"less_than\", \"in_last\", \"not_in_last\", \"in_next\", \"not_in_next\", \"in_calendar_week\",
\"in_calendar_month\", \"in_calendar_day\", \"in_calendar_year\", \"between\", \"in\", \"not_in\"]"}
Shot.sg_turnover_date, a date field, returns an identical list; the two types share every relation and
differ only in value format. There is no not_between and no is_null.
Every count below is one sandbox Version holding 2026-03-04T05:06:07Z, run on 2026-09-02: 1 is a match,
0 is a miss.
| 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"] |
A filter value takes the same formats as a write value, date-only included, and a date-only value is exactly midnight UTC rather than a day:
| stored | is "2026-03-04" |
greater_than "2026-03-04" |
less_than "2026-03-04" |
|---|---|---|---|
2026-03-03T23:30:00Z |
0 | 0 | 1 |
2026-03-04T00:00:00Z |
1 | 0 | 0 |
2026-03-04T00:30:00Z |
0 | 1 | 0 |
Re-stored on the current UTC date, the same row matched in_calendar_day 0 at both 00:30Z and
23:30Z and matched neither -1 nor +1, with _week, _month and _year at 0 each 1: the calendar
buckets are UTC-aligned, with no site-local offset.
Traps
- A written offset is not preserved:
05:06:07+05:00reads back as00:06:07Z. Convert to UTC yourself and keep the original zone in your own field if a client must redisplay local wall-clock time. - A zoneless string is assumed UTC, not site-local:
"2026-03-04T05:06:07"is not "5am here". isis exact-second equality, sois "2026-03-04"finds only rows at00:00:00Z. Match a day withbetween ["2026-03-04", "2026-03-05"]orin_calendar_day.""400s where atextfield accepts it; onlynullclears. There is no numeric form: epoch integers 400 with the[String, NilClass]type error, epoch strings with the format error.editable: falseon a timestamp means "not editable by aPUT", not "not settable". The 400 says so outright,is editable on create only, and a create body sets both (probe 070). Test the create path rather than reading the flag.