one record beyond crud
POST on one record is revive, not update: ?revive=1 is required and the body is ignored. /<field> reads image and attachment fields only, and relationships/<field> is the same data, unpaged.
API
Q What else answers on one record besides GET, PUT and DELETE?
Endpoint POST /entity/shots/{id} ; GET /entity/versions/{id}/{field} ; GET /entity/versions/{id}/relationships/{field} ; PUT /entity/projects/{id}/_update_last_accessed ; GET /exports/page/{id}.csv
Docs claim The site's own /spec.json names all six. It calls the POST "Revive a record", the
field read "Read file field", and it gives csv as the only value of <format>.
Actual
GET /entity/versions/17055/<field>
code, sg_status_list, id, entity, playlists -> 400 "Field Version.code is not an image or attachment."
image -> 200 {"data": "<presigned URL>", "links": {...}} empty -> 200 {"data": null}
sg_uploaded_movie -> 200 data keys [content_type, id, link_type, name, type, url]
entity.Shot.code -> 406 text/html 1 byte sg_not_a_field -> 404 "Field 'Version.sg_not_a_field' does not exist."
?alt=original|thumbnail -> 302 to storage; followed: 200 image/jpeg 51730 bytes; empty field -> 404
?alt=original with Range: bytes=0-100 -> 206 image/jpeg, Content-Range: bytes 0-100/196291
?alt=nope -> 400 {"alt": ["alt must be one of: original, thumbnail"]}
GET /entity/versions/17055/relationships/<field>
entity -> 200 {"data": {"id": 1230, "name": "charA", "type": "Asset"}, "links": {"self": ...}}
playlists -> 200 {"data": []} code, image -> 400 "Field 'code' is not a relationship field"
a 60-link multi_entity: page[size], page[number], fields and sort all ignored, 60 rows, no links.next
same ids in the same order as ?fields; 3048 bytes against 3231, and 120 against 353 for one link
POST /entity/shots/7683
?revive=1, retired row -> 200 {"data": {"type": "Shot", "id": 7683}, "meta": {"did_revive": true}}
?revive=1, live row -> 200 meta {"did_revive": false}
1, true and yes accepted; 0 and false -> 400 {"revive": ["revive must be true"]}; none -> "revive is missing"
a body alongside revive=1 -> 200, not applied ?fields=code ignored logs Shotgun_Shot_Revival
PUT /entity/projects/1180/_update_last_accessed
{"user_id": 3} -> 200 {"data": {"type": "Project", "id": 1180}, "links": {...}} {} -> 400 "user_id is missing"
{"user_id": 999999999} -> 200, identical body project 999999999 -> 400 code 104 "Api::Errors::CrudError"
GET the same path -> 404 "Field 'Project._update_last_accessed' does not exist."; under shots -> 404 detail null
last_accessed_by_current_user null before and after, 0 event_log_entries
GET /exports/page/3074.csv -> 422 text/csv "Export for Page id=3074 not available"; 3074/<view>.csv the same
.json .xml .txt set Content-Type from the extension, same 422 body; no extension -> 404 code 103
999999999.csv -> 422 "Trying to perform export for retired Page id=999999999"; abc.csv -> id=0; 52 pages over 27 page_type values: 52 x 422, 0 x 200
Teaches
| call | what it is | what a caller assumes |
|---|---|---|
POST /entity/<type>/<id> |
revive a retired row | an update, or a create with an id |
GET /entity/<type>/<id>/<field> |
one image or attachment field, with a download | any field, read cheaply |
GET .../relationships/<related_field> |
the link list, unwrapped | a paged sub-collection |
PUT /entity/projects/<id>/_update_last_accessed |
stamps a user's project history | something readable back |
GET /exports/page/<page_id>.<format> |
a saved page view as CSV | any page, any format |
POSTon a single record isDELETErun backwards.?revive=1is required,revivemust be truthy (0andfalseare refused withrevive must be true), and a JSON body is accepted and discarded, so a client reaching for it as aPUTalias gets a 400 telling it about a parameter it never sent. The row comes back with the field values it had when it was retired.- The revive response is
{"data": {"type", "id"}, "links", "meta": {"did_revive"}}and has noattributeskey, less than any other write returns (probe 024).did_reviveisfalseon a row that was already live, at 200, which is the only way to tell a revive from a no-op. ?fieldsis ignored here as on every other write. On the probed site a successful revive logged oneShotgun_Shot_Revivalevent and a no-op logged none./<field>is not a cheap single-field read. Every non-file field is a 400 naming the field:Field Version.code is not an image or attachment.A dotted path is a 406 with a one-byte body, because the last dotted segment is parsed as a format extension. Use?fields=onGET /entity/<type>/<id>for anything else.?alt=originaland?alt=thumbnailturn the same path into a download: a 302 to the presigned storage URL, which a redirect-following client fetches as the bytes.Rangeis forwarded to storage and answers 206 withContent-Range, so a client can read a header off a large movie without pulling the file.Rangewithoutaltis ignored and the field hash comes back at 200.relationships/<related_field>returns the identicaldataa normal read puts underrelationships, minus thelinks.relatedpointer, and it is not paged: a 60-link field answered all 60 rows with nolinks.next, andpage[size],page[number],fieldsandsortwere all accepted and ignored.- It saves 233 bytes on a single entity link and 183 on 60 of them, so it is worth a call only when the link list is the whole request.
_update_last_accessedanswers 200 for auser_idthat does not exist and returns the same{data, links}either way, so nothing in the response says whether it did anything.- On the probed site
Project.last_accessed_by_current_userreadnullbefore and after, and noEventLogEntrywas written, because that field is relative to the requesting user and a script is not the user it stamps. There is no read-back over REST; treat the call as write-only. - The path is fixed to
projects.PUT /entity/shots/<id>/_update_last_accessedis a 404 with a nulldetail, andGETon the project path falls through to the file-field route and answersField 'Project._update_last_accessed' does not exist., which names a field nobody asked for. <format>is not validated..json,.xmland.txtall answer, and the extension sets the responseContent-Typewhile the body stays the same plain-text string. Drop the extension and the route stops matching: 404, code 103. Whether a successful export honours anything butcsvis unmeasured, because nothing exported.- Export is off by default and there is no field that says so. A page id that does not exist
answers
Trying to perform export for retired Page id=999999999, and a non-numeric id is read asid=0, so a 422 does not distinguish a missing page from a page whose view is not marked exportable. - On the probed site 52 pages across all 27
page_typevalues answered 422 and none answered 200;Pagehas noexportablefield and the flag is not in the layoutsettings_jsonprobe 023 reads, so a client cannot discover which pages will work without trying each one.