> ## Documentation Index
> Fetch the complete documentation index at: https://leonar.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom fields

> Read field definitions and manage custom field values on contacts and companies.

Custom fields let each workspace store extra CRM data on contacts and companies. In the public API:

* field definitions are exposed as read-only metadata
* field values are stored in `custom_data`
* updates to `custom_data` use **partial merge** semantics

## 1. Read field definitions

Use the dedicated definition endpoints to discover valid field keys and types before writing values.

<CodeGroup>
  ```bash Contacts theme={null}
  curl -X GET "https://app.leonar.app/api/v1/contacts/custom-fields" \
    -H "Authorization: Bearer leo_your_api_key"
  ```

  ```bash Companies theme={null}
  curl -X GET "https://app.leonar.app/api/v1/companies/custom-fields" \
    -H "Authorization: Bearer leo_your_api_key"
  ```
</CodeGroup>

Example response:

```json theme={null}
{
  "data": [
    {
      "id": "cf2b8df3-1c85-4e5d-8f50-0c10b3994e90",
      "key": "crm_tier",
      "label": "CRM Tier",
      "type": "select",
      "options": [
        { "value": "enterprise", "label": "Enterprise" },
        { "value": "mid_market", "label": "Mid-market" }
      ],
      "is_required": false,
      "position": 0
    }
  ],
  "meta": {
    "total": 1,
    "limit": 1,
    "offset": 0,
    "has_more": false
  }
}
```

## 2. Read custom field values

Custom field values are returned in the `custom_data` object on contact and company responses.

```json theme={null}
{
  "data": {
    "id": "contact-uuid",
    "first_name": "Sophie",
    "custom_data": {
      "industry_code": "A12",
      "vip": true
    }
  }
}
```

## 3. Update custom field values

`PUT /contacts/{id}` and `PUT /companies/{id}` merge `custom_data` into the existing object:

* sent keys are created or updated
* keys set to `null` are removed
* omitted keys are preserved

```bash theme={null}
curl -X PUT "https://app.leonar.app/api/v1/contacts/contact-uuid" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "custom_data": {
      "industry_code": "A12",
      "vip": null
    }
  }'
```

If the contact already had:

```json theme={null}
{
  "custom_data": {
    "crm_owner": "alice",
    "vip": true
  }
}
```

the result becomes:

```json theme={null}
{
  "custom_data": {
    "crm_owner": "alice",
    "industry_code": "A12"
  }
}
```

## 4. Validation rules

The API validates `custom_data` against the workspace definitions:

* unknown keys are rejected
* `select` values must match an allowed option
* `multiselect` values must all match allowed options
* `number`, `currency`, `boolean`, `date`, `datetime`, `url`, and `email` values must match the field type
* required fields cannot be removed with `null`

## 5. Recommended integration flow

1. Read definitions from `/contacts/custom-fields` or `/companies/custom-fields`
2. Cache `key`, `type`, and `options`
3. Read entities and inspect `custom_data`
4. Send partial `custom_data` updates only for the keys you want to change
