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

# Custom Fields

> User-defined fields on contacts, companies, emails, and custom activities.

Custom fields let you store your own data on RevyOps records. They're typed: a field is defined once with a type, and every value written to it is checked against that type. Custom fields exist for contacts, companies, and custom activity types; emails have their own lighter-weight [custom fields](/data-model/emails#custom-fields-on-emails) that aren't part of this schema.

## The five field types

| Type                    | Accepts                                            | Notes                                                                                                |
| ----------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `text`                  | Any string                                         | Default type if none is specified                                                                    |
| `number`                | A numeric string, e.g. `"123"`, `"45.67"`, `"-10"` |                                                                                                      |
| `date`                  | `YYYY-MM-DD`                                       | Any other format is rejected                                                                         |
| `dropdown_singleselect` | One value from `available_options`                 | Requires `available_options` when the field is defined                                               |
| `dropdown_multiselect`  | A list of values, each from `available_options`    | Requires `available_options`; a multi-value field arrives as a JSON-encoded string in filter results |

`available_options` is capped at 50 values.

## Configuration

|                      |                                                |
| -------------------- | ---------------------------------------------- |
| Schema API path      | `/public/custom-fields/schema`                 |
| Contact field values | `/public/contacts/{contact_id}/custom-fields`  |
| Company field values | `/public/companies/{company_id}/custom-fields` |
| MCP tools            | `list_custom_fields`, `create_custom_field`    |

## Defining a field

`GET /public/custom-fields/schema?object=contact` (or `company`) lists every field the client can read or write.

`POST /public/custom-fields/schema` defines a field and sets its type, so it exists on every record and in the filter schema before any value is written. Repeating the call for a field this workspace owns updates its type; setting `type: "text"` again does not remove it (removal isn't exposed through this endpoint).

| Attribute         | API field           | Type             | Writable?                   | Notes                                                                                                     |
| ----------------- | ------------------- | ---------------- | --------------------------- | --------------------------------------------------------------------------------------------------------- |
| Object            | `object`            | string           | **Required.**               | `contact` or `company`                                                                                    |
| Field Name        | `field_name`        | string           | **Required.**               | Max 255 characters                                                                                        |
| Type              | `type`              | string           | Yes                         | One of the [five types](#the-five-field-types) above, default `text`                                      |
| Available Options | `available_options` | array of strings | Required for dropdown types | Max 50 values, each up to 255 characters                                                                  |
| Source            | `source`            | string           | No                          | Returned only. `agency` if the agency master schema owns the field, `client` if this workspace defines it |
| Created By        | `created_by`        | string           | No                          | Returned only. The UI user who added it, or null if it was created via the API, MCP, or an import         |
| Filter Key        | `filter_key`        | string           | No                          | Returned only. The field id to use in filter conditions, e.g. `custom.fit_score`                          |

Existing values are checked against the new type before it's applied: a number field rejects non-numeric values, a date field rejects anything but `YYYY-MM-DD`, and a dropdown rejects values outside `available_options`. Defining or redefining a field that already has out-of-type values fails (400) and names them.

## Agency vs. client fields

Every custom field has a `source`: `agency` or `client`.

* **`agency`**: defined in the agency's master schema, shared across every client workspace under that agency. Its type is managed at the agency level; a client-level `POST /public/custom-fields/schema` call against an agency-owned field is rejected with 409.
* **`client`**: defined for one workspace only, through that workspace's own API key or MCP session.

The agency Schema Settings page in the UI shows both agency and client fields for a client, and lets an agency promote a client field into the agency master schema.

## Writing values

Once a field is defined, values are written per record:

* `POST /public/contacts/{contact_id}/custom-fields` and `PATCH .../custom-fields/{field_id}` set or update a contact's value for a field.
* `POST /public/companies/{company_id}/custom-fields` and `PATCH .../custom-fields/{field_id}` do the same for companies.
* `DELETE .../custom-fields/{field_id}` removes a value.

Each of these takes `field_name` and `field_value`; the value is validated against the field's type the same way schema values are.

Custom fields on custom activity types follow the same five types but are defined as part of the activity type's `schema` rather than through this endpoint; see [Custom activity types and custom activities](/data-model/activities#custom-activity-types-and-custom-activities).

## Related endpoints and MCP tools

**Public API**

* `GET`/`POST /public/custom-fields/schema`
* `POST /public/contacts/{contact_id}/custom-fields`, `PATCH`/`DELETE .../custom-fields/{field_id}`
* `POST /public/companies/{company_id}/custom-fields`, `PATCH`/`DELETE .../custom-fields/{field_id}`

**MCP tools**

* `list_custom_fields`, `create_custom_field`
* `update_contact`, `update_company` (accept a `custom_fields` object of key-value updates)
* `get_filter_schema`, `get_field_options` (custom fields appear as `custom.<name>`)
