Custom Fields
Manage custom fields for contacts. Custom fields let you define org-specific attributes beyond the built-in contact properties.
All endpoints require authentication via the X-API-Key header. See Authentication.
List categories
GET /contacts/custom-fields/categories
List custom field category names used in your org.
Example request
Response
Create a custom field
POST /contacts/custom-fields
Uses a transaction to atomically create the field and increment the org's field count.
Limit: Maximum 50 custom fields per org.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
label | string | Yes | Display name. Must be unique within the org. |
type | string | Yes | Field type (e.g. text, number, boolean, date, select). Immutable after creation. |
category | string | No | Optional grouping category. |
values | string[] | No | select and multi-select only: the option labels, in display order, created with the field in the same request. Ignored for other types. |
Example request
Response
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Custom field limit reached (max 50). Have N, requested M. | Org already has 50 custom fields. |
| 400 | Validation error | Missing or invalid label or type. |
| 400 | Custom field with label ... already exists | Duplicate label within the org. |
List custom fields
GET /contacts/custom-fields
Returns all custom fields for your org, sorted alphabetically by label.
Example request
Response
Update a custom field
PUT /contacts/custom-fields/:id
Updates a custom field's label or category. The field type cannot be changed after creation.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Custom field ID. |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
label | string | No | New display name. |
category | string | No | Grouping category, or null to clear it. |
Example request
Response
Errors
| Status | Message | Cause |
|---|---|---|
| 404 | Custom field not found | No field with that ID in your org. |
| 400 | Custom field with label ... already exists | Another field of the org already has that label. |
Delete a custom field
DELETE /contacts/custom-fields/:id
Deletes a custom field. Also removes the field's values from all contacts and boards in a transaction.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Custom field ID. |
Example request
Response
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Field does not exist | No field with that ID in your org. |
| 400 | Field Id missing from params | Missing or invalid ID parameter. |
Add field values
POST /contacts/custom-fields/:id/values
Add values to a custom field (for select-type fields).
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Custom field ID. |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
values | string[] | Yes | Values to add. |
Example request
Response
Standard success envelope with the updated field in data.
Update a field value
PUT /contacts/custom-fields/:id/values/:valueId
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Custom field ID. |
valueId | string | Value ID to update. |
Example request
Response
Standard success envelope with the updated field in data.
Delete a field value
DELETE /contacts/custom-fields/:id/values/:valueId
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Custom field ID. |
valueId | string | Value ID to delete. |
Example request
Response
Standard success envelope confirming deletion.
Response envelope
All endpoints use the standard envelope:
Error responses:
data is null for a general failure, such as a database error or an upstream timeout. When the request is rejected because of a specific field, data carries the field(s) at fault instead:
Each issue carries a path (the dotted path into the request body) and a message. A label is added when the path is not self-describing, which today means custom fields only, for example "path": "fields.68b0a1f39c2e4d0012ab77e5", "label": "Class Year". issues is an array, but treat it as holding at most one entry: validation stops at the first failure.