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

# Custom Fields

> How to create, configure, and associate custom fields with people, companies, and deals in the Vendaze API.

Custom fields let each workspace capture information specific to its sales process that is not part of the Vendaze standard schema: tax IDs, lead sources, market segments, internal scores, or any other relevant data.

Each field belongs to the workspace, has a fixed type, and can be displayed on people, companies, and/or deals based on its visibility configuration.

## Correct usage flow

Using custom fields safely follows a specific order that prevents type mismatches and data inconsistencies.

**1. Create the field in the workspace**

Before associating values with any record, the field must exist with the correct type configured. Use `POST /v1/custom-fields` for this.

**2. Associate values on records**

Once the field exists, pass `custom_fields` in the body of `POST` or `PATCH` requests on people, companies, or deals, referencing the field by its `key`.

### Why you should create the field first

When you send an unknown `field_key` through the people, companies, or deals routes, the API automatically creates the field with `type: text`. This may seem convenient, but it creates a real problem: if the field was meant to be `select`, `date`, `number`, or any other type, it will have been created with the wrong type. Fixing it later requires a separate update call and can produce inconsistencies in values already stored.

Always create the field with the correct type before writing values.

***

## Create a custom field

```bash theme={null}
POST /v1/custom-fields
```

Required fields: `label`, `key`, and `type`.

```json theme={null}
{
  "label": "Lead Source",
  "key": "lead_source",
  "type": "select",
  "value": {
    "select_list": [
      { "key": "sl_referral", "option": "Referral" },
      { "key": "sl_inbound", "option": "Inbound" },
      { "key": "sl_event", "option": "Event" }
    ]
  },
  "show_people": true,
  "show_companies": false,
  "show_deals": true
}
```

Creation rules:

* `key` is immutable after creation. Use stable, descriptive identifiers such as `lead_source` or `company_tax_id`.
* `type` is also immutable. Choose the correct type before creating the field.
* For `select` and `multi_select`, the `value.select_list` field is required and defines the available options.
* The `show_people`, `show_companies`, and `show_deals` flags control which entities display the field. The default is `true` for people and companies, `false` for deals.

### Available types

| Type           | Description                                |
| -------------- | ------------------------------------------ |
| `text`         | Single line of text                        |
| `long_text`    | Multi-line text                            |
| `number`       | Integer or decimal numeric value           |
| `date`         | Date in `YYYY-MM-DD` format                |
| `select`       | One option from a predefined list          |
| `multi_select` | Multiple options from a predefined list    |
| `cpf`          | Brazilian individual tax ID                |
| `cnpj`         | Brazilian company tax ID                   |
| `link`         | Full URL                                   |
| `address`      | Physical address structured into subfields |

***

## Associate values with records

With the field created, include `custom_fields` in the request body when creating or updating a record. Each item requires `field_key` and `value`.

```bash theme={null}
POST /v1/people
```

```json theme={null}
{
  "full_name": "Ana Costa",
  "emails": [{ "email": "ana@acme.com", "type": "work" }],
  "custom_fields": [
    { "field_key": "lead_source", "value": "sl_referral" },
    { "field_key": "score", "value": 85 }
  ]
}
```

The API resolves `field_key` to the field's internal ID. If no field with that key exists in the workspace, it is created automatically with `type: text`. See the section above on why this should be avoided.

### Association mode

The `association_mode` parameter controls the behavior when updating a record via `PATCH`:

* `append` (default): sets or replaces the value for each `field_key` sent, without affecting other fields already associated with the record.
* `replace`: removes all custom field values from the record and inserts only the ones sent in this request.

***

## Value format reference by type

### `text`

Plain string, single line.

```json theme={null}
{ "field_key": "internal_role", "value": "Sales Manager" }
```

### `long_text`

String with line breaks represented as `\n`.

```json theme={null}
{ "field_key": "notes", "value": "Preferred customer.\nContact by email only." }
```

### `number`

JSON number without quotes. Accepts integers or decimals.

```json theme={null}
{ "field_key": "employee_count", "value": 120 }
```

```json theme={null}
{ "field_key": "internal_score", "value": 7.5 }
```

### `date`

String in `YYYY-MM-DD` format, without time.

```json theme={null}
{ "field_key": "contract_date", "value": "2026-08-15" }
```

### `select`

Key of a single option from the field's predefined list. To retrieve available keys, use `GET /v1/custom-fields/:id` and inspect `value.select_list`.

```json theme={null}
{ "field_key": "segment", "value": "sl_technology" }
```

Sending a key that does not exist in the list returns a validation error.

### `multi_select`

JSON array of selected option keys.

```json theme={null}
{ "field_key": "products_of_interest", "value": ["sl_basic_plan", "sl_advanced_plan"] }
```

To select a single option, pass an array with one element. To clear all selections, pass an empty array.

```json theme={null}
{ "field_key": "products_of_interest", "value": [] }
```

### `cpf`

String with or without punctuation.

```json theme={null}
{ "field_key": "responsible_cpf", "value": "123.456.789-09" }
```

### `cnpj`

String with or without punctuation.

```json theme={null}
{ "field_key": "company_cnpj", "value": "12.345.678/0001-90" }
```

### `link`

Full URL with protocol.

```json theme={null}
{ "field_key": "linkedin", "value": "https://linkedin.com/in/ana-costa" }
```

### `address`

JSON object with the subfields below. All are optional: send only the ones available. Subfields not sent are stored as an empty string.

| Subfield         | Description                     |
| ---------------- | ------------------------------- |
| `address_line_1` | Street address and number       |
| `address_line_2` | Complement (suite, floor, unit) |
| `city`           | City                            |
| `region`         | State or region                 |
| `postal_code`    | ZIP or postal code              |
| `country`        | Country                         |

```json theme={null}
{
  "field_key": "headquarters_address",
  "value": {
    "address_line_1": "1000 Market Street",
    "address_line_2": "Suite 42",
    "city": "San Francisco",
    "region": "CA",
    "postal_code": "94103",
    "country": "United States"
  }
}
```

***

## Read values on a record

When retrieving a record by ID, associated values are returned in the `custom_fields` array with the `field` object embedded:

```json theme={null}
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "full_name": "Ana Costa",
    "custom_fields": [
      {
        "id": "cf-assoc-uuid",
        "value": "sl_referral",
        "field": {
          "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "label": "Lead Source",
          "key": "lead_source",
          "type": "select"
        }
      }
    ]
  }
}
```

***

## Full example

The example below creates a person with fields of every type, assuming each field was already created via `POST /v1/custom-fields`.

```json theme={null}
POST /v1/people

{
  "full_name": "Ana Costa",
  "emails": [{ "email": "ana@acme.com", "type": "work" }],
  "custom_fields": [
    { "field_key": "responsible_cpf",      "value": "123.456.789-09" },
    { "field_key": "company_cnpj",         "value": "12.345.678/0001-90" },
    { "field_key": "segment",              "value": "sl_technology" },
    { "field_key": "products_of_interest", "value": ["sl_basic_plan", "sl_advanced_plan"] },
    { "field_key": "employee_count",       "value": 120 },
    { "field_key": "contract_date",        "value": "2026-08-15" },
    { "field_key": "linkedin",             "value": "https://linkedin.com/in/ana-costa" },
    { "field_key": "notes",                "value": "Referred by Acme partner." },
    {
      "field_key": "headquarters_address",
      "value": {
        "address_line_1": "1000 Market Street",
        "address_line_2": "Suite 42",
        "city": "San Francisco",
        "region": "CA",
        "postal_code": "94103",
        "country": "United States"
      }
    }
  ]
}
```
