Reverse Engineering

Herein lies the more complex matters that we have discovered about Shotgun while poking through it in order to create SGCache.


This information is as of v6.0.3 (build 04eae45), and only contains as much as we have discovered. There are very likely unknown edge cases everywhere.

Private Schema

For reverse-engineering purposes, it can be helpful to browse the private schema given to the Shotgun web page. This is available at:

Field Types

  • API type: bool
  • Not NULL-able; the API throws an error if you filter with a None here
  • API type: comma-delimited RGB integers, e.g.:


    or one of:

    {"Blue", "Orange", "Pink", "Red", "Green", "Purple", "Grey", "Black"}


    "pipeline_step" # to use the colour from the Task's pipeline Step.
  • NULL-able in general, but not on Task.color; throw the error:

    Unsupported format for Task color field. The Task color can not be nil, the expected format is r,g,b where the values of r,g and b are in the range 0-255. The value of the color can also be set using the legacy color strings which are; Blue, Orange, Pink, Red, Green, Purple, Grey and Black. The value can also be set to the value pipeline_step to indicate that the Gantt bar should render using the color of the Task’s Pipeline Step.

  • Python API type: object

  • JSON API type: (assumed) ISO 8601 encoded string, e.g.:

  • API type: int
  • API type: dict of a single entity; e.g.:

        "id": 2,
        "type": "Shot",
        "name": "Shot 1"
  • Must contain type and id, and often name

  • NULL-able

  • Not necessarily constrained to a single entity type

  • API type: str of type name
  • API type: float
  • API type: str of URL
  • May be influenced by api_return_image_urls passed via JSON API
  • API type: str, value of which is from a defined set
  • A better name would be “enumeration”
  • API type: int
  • This is used for IDs
  • API type: the literal string '*******'
  • Only used for ClientUser.password_proxy
  • API type: int from 0 to 100
  • Only used by Task.time_percent_of_est
  • Only in step_* fields
  • Not supported by the API in any way
  • API type: any JSON
  • Not filterable by the API
  • API type: str, value of which is from the set of statuses.
  • API type: list of ???.
  • API type: str
  • NULL-able.
  • API type: int
  • Only used by Shot.{src_in,src_out}
  • API type: dict with:
    • content_type
    • name
    • etc.,
  • Appears to be a link to the entity it belongs to, and so violates a core assumption that SGSession makes.

  • Cannot be used in filters

  • Not filterable by the API
  • Not used by default; only by by our {Shot,Version}.sg_viewer_link (which itself is deprecated)
  • API Type: str of typical UUID, e.g.:


Identifier Column

When reading an entity or multi_entity field, the API returns the entity type, id, and a name field. However, this field does not always exist:

>>> sg.find_one('Task', [], ['step'])
{'step': {'type': 'Step', 'id': 4, 'name': 'Matchmove'}, 'type': 'Task', 'id': 2}

# Note there is no "name" when we query the Step directly:
>>> sg.find_one('Step', [('id', 'is', 4)], ['name', 'code'])
{'code': 'Matchmove', 'type': 'Step', 'id': 4}

It appears that the private schema describes a identifier_column field per entity, which it uses for the name.

These include:

  • Note.subject
  • Playlist.code
  • Reply.content
  • Status.icon (although this one has a name set too)
  • Step.code
  • Task.content

As of now, we do not implement this behavior, and entities will not have a name field.