Clarify API
Guides

Schemas and Relationships

Behaviors and gotchas when managing fields, relationships, and custom objects

This guide covers the non-obvious behaviors of the schema, relationship, and custom-object endpoints. For the endpoint mechanics themselves, see the Schemas and Records Relationships reference.

Schema fields

Schemas describe the fields on each object. GET /schemas returns a JSON:API response whose data array is a flat list of every schema in the workspace, each identified by a schema URL. Built-in objects and custom objects alike appear under .../entities/*, for example .../entities/person and .../entities/c_sales_order. The .../core/* entries are the shared base definitions those schemas build on.

Use "type": "date" for date fields users need to edit: custom "date-time" fields render read-only in the UI. Enum values are case-sensitive: "Active" and "active" are treated as different values.

Editing enum values is partly destructive

Adding values to an existing enum is safe. Removing values is destructive: any record set to a removed value loses it (a single-select field is cleared to null; a multi-select field drops that option), and those records fall out of any lists that filter on the value. Always check which records use a value before removing it.

Relationships

Relationships connect records across object types: people to companies, deals to companies, people to deals. You can also set a relationship through a foreign-key field (e.g. company_id) at creation time.

PATCH .../relationships/{relationship} behaves differently by relationship kind. For many-to-many relationships (such as the people on a deal, or a person's meetings) it replaces the entire set: any related records not in the request body are unlinked. For one-to-many relationships (such as a company's people) it is additive: it links the records you send and leaves the rest attached, though linking a record that already belongs to another parent reassigns it. To remove specific records in either case, use DELETE on the same path.

Custom objects

Custom object names are normalized to a c_ prefix: "Sales Order" becomes c_sales_order. If a new object's name normalizes to one that already exists, creation is rejected with a 422. Once created, custom objects use the same record endpoints as standard objects (single and bulk) with the c_-prefixed name as the {object} path parameter.

User identifiers

Every record carries _created_by and _updated_by: opaque actor identifiers, not UUIDs. The value depends on who made the change:

  • A workspace user: that user's ID, whose exact format depends on the workspace's auth provider (for example, a Google OAuth subject like google-oauth2|106236165388989412707).
  • An automated actor: a system actor (system, agent, or rep).

Treat these values as opaque. Resolve a user identifier to a name and email through the Users endpoint; the system-actor values are not workspace users and won't resolve there.

On this page