create fields
Custom fields are creatable over REST, but you pass a display name and a duplicate silently becomes <name>_1: an idempotent ensure() must read /schema first, never POST-and-hope.
API
Q Can a client create its own custom fields over REST, and what breaks when it tries twice?
Endpoint POST /schema/Version/fields ; DELETE /schema/Version/fields/<name> ; GET /schema/Version/fields
Docs claim Custom fields can be created over REST and names are forced to an sg_ prefix; silent on duplicate display names and on whether a delete frees the name.
Actual
=== data types (POST /schema/Version/fields)
text float number date date_time list url duration percent footage -> 201, nothing extra
checkbox + default_value -> 201 (bare: 500 "Only true or false allowed in checkbox")
entity + valid_types [OneType] -> 201 (bare: 400 missing required 'properties')
multi_entity + valid_types [OneType] -> 201 (bare: 400 missing required 'properties')
color, image -> 400 {"data_type": ["data_type is not valid"]} ; calculated -> 500 NoMethodError
valid_types ["Version"] -> 201 ; ["Shot","Asset"] -> 400 "'valid_types' value expected Array with one element"
=== multi_entity holds lineage
write [{"type": "Version", "id": 26264}] -> 201, reads back under relationships not attributes:
{"data": [{"id": 26264, "name": "charA_v001", "type": "Version"}]}
=== display name -> programmatic name (sg_ prefix, lowercased, non-alphanumeric -> _)
'zzprobe 019 With (Parens)' -> sg_zzprobe_019_with__parens_
'sg_zzprobe_019_already_prefixed' -> sg_sg_zzprobe_019_already_prefixed <- DOUBLE prefixed
the programmatic name is NOT in the body; it is the last segment of links.self
=== duplicate display name: no error, silent suffix
first -> 201 sg_zzprobe_019_collide ; second -> 201 sg_zzprobe_019_collide_1
=== seed size (64-bit ids and seeds reach 2**64-1)
number 2147483647 -> 201, reads back exactly ; number 9223372036854775808 -> 400 Create failed
=== delete, and the name afterwards
DELETE /schema/Version/fields/<name> -> 204 ; GET that field -> 404 ; absent from the /schema list
recreate the SAME display name -> 400 schema_field_create() failed
=== litter, re-read read-only today
GET /schema/Version/fields -> 71 fields, 9 of them sg_ai_*: prompt seed (text), model sampler
generator negative_prompt (text), steps (number), cfg (float), generated_from (multi_entity/Version)
Teaches
- Trap. A duplicate display name does not error: it creates
<name>_1, and it keeps going. Three creates of one display name gavesg_zzprobe_041_dup,sg_zzprobe_041_dup_1andsg_zzprobe_041_dup_2, all at 201, all three live at once and all three reading back the identical display name. - A display name identifies nothing, so a client that looks a field up by the name a person typed can match several fields or the wrong one. Match on the programmatic name. An idempotent
ensure()must GET/schema/Version/fieldsand match first, never POST-and-hope. - Trap.
DELETEreturns 204 and the field vanishes from/schema, but the name is not freed: re-creating it 400s, and the trashed field cannot be enumerated, so the collision is invisible. - That is one delete-and-recreate cycle on one field name, observed once; settling whether every deleted name behaves this way costs another name, which this repo does not spend. Treat a name you have created as spent.
- On the probed site Version has 71 fields against the 61 of
probe 002, and the ninesg_ai_*fields are the difference; none follow thesg_zzprobe_<nnn>_*conventiondocs/quirks.mdmandates. Attribution of those nine to this probe is<unverified>: the committed code createszzprobe 019 *names, and no creator is recorded anywhere. - You pass a display name and the
sg_prefix is added for you, sosg_foobecomessg_sg_foo. The programmatic name is absent from the response body; take the last segment oflinks.self. - Most creation 400s are a missing
properties, not a refusal. Onlycolor,imageandcalculatedare rejected outright;entityandmulti_entityneedvalid_typesholding exactly one type, andcheckboxneedsdefault_value.multi_entityround-trips lineage underrelationships(field_types/multi_entity). - A seed must be a text field:
numberis signed 32-bit, and 64-bit ids and seeds reach 2**64-1 (field_types/number).