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. UsePOST /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 unknownfield_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
label, key, and type.
keyis immutable after creation. Use stable, descriptive identifiers such aslead_sourceorcompany_tax_id.typeis also immutable. Choose the correct type before creating the field.- For
selectandmulti_select, thevalue.select_listfield is required and defines the available options. - The
show_people,show_companies, andshow_dealsflags control which entities display the field. The default istruefor people and companies,falsefor 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, includecustom_fields in the request body when creating or updating a record. Each item requires field_key and value.
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
Theassociation_mode parameter controls the behavior when updating a record via PATCH:
append(default): sets or replaces the value for eachfield_keysent, 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.
long_text
String with line breaks represented as \n.
number
JSON number without quotes. Accepts integers or decimals.
date
String in YYYY-MM-DD format, without time.
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.
multi_select
JSON array of selected option keys.
cpf
String with or without punctuation.
cnpj
String with or without punctuation.
link
Full URL with protocol.
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 |
Read values on a record
When retrieving a record by ID, associated values are returned in thecustom_fields array with the field object embedded:
Full example
The example below creates a person with fields of every type, assuming each field was already created viaPOST /v1/custom-fields.