Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /schema | Full workspace schema, grouped by object type |
GET | /schema/:object_type | Attributes defined for one object type |
POST | /schema/:object_type/attributes | Add an attribute definition |
PATCH | /schema/:object_type/attributes/:key | Modify (metadata + append enums + toggle required) |
DELETE | /schema/:object_type/attributes/:key | Soft-delete (sets deprecated_at) |
:object_type is one of person, company, deal, note, task, activity, or a custom object’s UUID (not its slug).
Add an attribute
Constraints by data_type
enumrequires non-emptyenum_values. Otherwise →400 enum_values_required.referencerequiresreference_object_type∈{person, company, deal}. Otherwise →400 reference_object_type_required.- All keys must match
^[a-z][a-z0-9_]*$(lowercase snake_case, max 64 chars). - Duplicate
(workspace_id, object_type, attribute_key)→409 attribute_exists.
Modify (PATCH)
display_namedefault_valueis_required(both directions; doesn’t backfill existing rows)enum_values_append— array of new values to add. Duplicates are deduped server-side.
data_type— frozen after creation. Changing it would require a data migration.enum_values— only appendable in v1. Removing values silently invalidates existing rows; the v1.1 endpoint will require explicit migration semantics.
Deprecate (DELETE)
deprecated_at = now(). Existing data with the key stays readable. New writes of the key return 400 attribute_deprecated. The attribute still shows up in GET /schema with "deprecated": true.