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

# Custom Fields in Records

> How to read and set custom field values on any REST API record using the CustomFields array

# Custom Fields in Records

Custom fields allow you to store additional data on any record type in Nexudus (customers, invoices, bookings, products, and more). You can start using custom fields immediately via the API without any prior setup. If you need the field to be visible in the admin UI or member portal, you can optionally register it via the [Custom Fields API](/rest-api/crm/get-customfields).

## How it works

1. **Read custom field values** from any GET response — the `CustomFields` object is included in single-record (GET by ID) and list/search results.
2. **Set custom field values** by including the `CustomFields` object in your PUT request body.
3. **Optionally, register a custom field** using the `/api/crm/customfields` endpoints if you need the field to appear in the Nexudus admin UI or member portal. This is not required for API-only usage.

<Info>
  You do not need to pre-register custom fields to use them via the API. You can store and retrieve arbitrary key-value data on any record by simply including a `CustomFields` object in your PUT requests. Registration is only necessary when you want the field to be visible and editable in the Nexudus UI.
</Info>

## The CustomFields object

Every record that supports custom fields includes a `CustomFields` property with the following structure:

```json theme={null}
{
  "CustomFields": {
    "Data": [
      {
        "Name": "1414363299",
        "Value": "ABC1234",
        "JsonValue": null,
        "Type": "string"
      }
    ]
  }
}
```

<ParamField body="CustomFields.Data" type="array" required>
  Array of custom field entries for this record.
</ParamField>

<ParamField body="CustomFields.Data[].Name" type="string" required>
  The identifier for the custom field. This can be:

  * **Any arbitrary string** if you are using the API to store data without registering the field in the UI.
  * **The `Id` of a registered custom field definition** (as a string) if the field was created via `GET /api/crm/customfields/{id}`. When fields are registered, the UI uses the definition's `Id` as the `Name`.
</ParamField>

<ParamField body="CustomFields.Data[].Value" type="string" required>
  The value to store. All values are represented as strings regardless of the field's `FieldType`.
</ParamField>

<ParamField body="CustomFields.Data[].Type" type="string" required>
  The data type hint. Use `"string"` for most field types.
</ParamField>

<ParamField body="CustomFields.Data[].JsonValue" type="object">
  Read-only. Automatically populated when `Type` is `"json"` and `Value` contains a valid JSON structure. In that case, the field value is returned as a parsed JSON object rather than a string, making it easier to consume directly without additional parsing on the client side.
</ParamField>

## Reading custom field values

Custom field values are returned automatically in GET responses — both when retrieving a single record by ID and in list/search results.

### Example: GET a single invoice

```bash cURL theme={null}
curl -X GET \
  "https://spaces.nexudus.com/api/billing/coworkerinvoices/1428806532" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

The response includes the `CustomFields` property:

```json theme={null}
{
  "Id": 1428806532,
  "InvoiceNumber": "INV-0107",
  "Description": "HQ Teams (Tech 005)",
  "TotalAmount": 10.00,
  "CustomFields": {
    "Data": [
      {
        "Name": "1414363299",
        "Value": "ABC1234",
        "JsonValue": null,
        "Type": "string"
      }
    ]
  }
}
```

<Note>
  For registered custom fields, the `Name` in each entry corresponds to the `Id` of the custom field definition. Use `GET /api/crm/customfields` to look up the human-readable name and configuration. For unregistered fields, the `Name` is whatever string you chose when storing the value.
</Note>

## Setting custom field values

To set or update custom field values, include the `CustomFields` object in your PUT request body. You must send the full record as part of the PUT request (the API does not support PATCH).

### Example: Update an invoice with a custom field value

```bash cURL theme={null}
curl -X PUT \
  "https://spaces.nexudus.com/api/billing/coworkerinvoices" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "Id": 1428806532,
    "CoworkerId": 1418015221,
    "BusinessId": 1414890114,
    "CustomFields": {
      "Data": [
        {
          "Name": "1414363299",
          "Type": "string",
          "Value": "ABC1234"
        }
      ]
    }
  }'
```

```javascript JavaScript theme={null}
const response = await fetch(
  'https://spaces.nexudus.com/api/billing/coworkerinvoices',
  {
    method: 'PUT',
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      Id: 1428806532,
      CoworkerId: 1418015221,
      BusinessId: 1414890114,
      CustomFields: {
        Data: [
          {
            Name: '1414363299',
            Type: 'string',
            Value: 'ABC1234'
          }
        ]
      }
    })
  }
);
```

```python Python theme={null}
import requests

response = requests.put(
    'https://spaces.nexudus.com/api/billing/coworkerinvoices',
    headers={
        'Authorization': 'Bearer YOUR_TOKEN',
        'Content-Type': 'application/json'
    },
    json={
        'Id': 1428806532,
        'CoworkerId': 1418015221,
        'BusinessId': 1414890114,
        'CustomFields': {
            'Data': [
                {
                    'Name': '1414363299',
                    'Type': 'string',
                    'Value': 'ABC1234'
                }
            ]
        }
    }
)
```

<Warning>
  The Nexudus API does not support PATCH requests. Always read the full record first with a GET request, modify the `CustomFields` values, and then submit the complete record in your PUT request.
</Warning>

## Setting multiple custom field values

Include multiple entries in the `Data` array to set several custom fields at once:

```json theme={null}
{
  "CustomFields": {
    "Data": [
      {
        "Name": "1414363299",
        "Type": "string",
        "Value": "ABC1234"
      },
      {
        "Name": "1414363300",
        "Type": "string",
        "Value": "2026-06-01"
      }
    ]
  }
}
```

## Clearing a custom field value

To clear a custom field value, set `Value` to an empty string:

```json theme={null}
{
  "CustomFields": {
    "Data": [
      {
        "Name": "1414363299",
        "Type": "string",
        "Value": ""
      }
    ]
  }
}
```

## Supported record types

Every record in the Nexudus REST API supports the `CustomFields` property — you can read and set custom field values on any record via the API regardless of whether a custom field definition exists for that record type.

However, for custom fields to appear and be editable in the Nexudus admin UI, you must create a custom field definition with a matching `RecordType`. The following record types have UI support when [creating a custom field definition](/rest-api/crm/post-customfields):

| RecordType value | Entity              |
| ---------------- | ------------------- |
| 1                | Customer            |
| 2                | Team                |
| 3                | FloorPlanDesk       |
| 4                | CrmOpportunity      |
| 5                | Visitor             |
| 6                | Proposal            |
| 7                | Customer (Internal) |
| 8                | HelpDeskMessage     |
| 9                | HelpDeskDepartment  |
| 10               | Product             |
| 11               | Booking             |
| 12               | Invoice             |
| 13               | Location            |
| 14               | Contract            |
| 15               | Tariff              |
| 16               | Resource            |
| 17               | FloorPlan           |
| 18               | InventoryAsset      |

<Note>
  If you only need to store and retrieve data programmatically via the API, you can use the `CustomFields` array on any record without creating a custom field definition. The definition is only required if you want the field to be visible and editable in the admin dashboard or member portal.
</Note>

## Searching and filtering by custom field values

You can filter list/search results by custom field values using query string parameters. The filter parameter follows this pattern:

```
{EntityName}_CustomFields_{CustomFieldId}={value}
```

Where:

* `{EntityName}` is the API entity name (e.g. `CoworkerInvoice`, `Coworker`, `Booking`)
* `{CustomFieldId}` is the `Name` used when storing the custom field value — this is the `Id` of a registered custom field definition, or any arbitrary name you used when setting the value directly via the API
* `{value}` is the value to filter by

### Example: Find invoices by custom field value

```bash cURL theme={null}
curl -X GET \
  "https://spaces.nexudus.com/api/billing/coworkerinvoices?CoworkerInvoice_CustomFields_1414363299=ABC1234" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

```javascript JavaScript theme={null}
const response = await fetch(
  'https://spaces.nexudus.com/api/billing/coworkerinvoices?CoworkerInvoice_CustomFields_1414363299=ABC1234',
  {
    headers: {
      'Authorization': 'Bearer YOUR_TOKEN'
    }
  }
);
```

```python Python theme={null}
import requests

response = requests.get(
    'https://spaces.nexudus.com/api/billing/coworkerinvoices',
    params={
        'CoworkerInvoice_CustomFields_1414363299': 'ABC1234'
    },
    headers={
        'Authorization': 'Bearer YOUR_TOKEN'
    }
)
```

### More examples by entity type

| Entity   | Filter parameter example                   |
| -------- | ------------------------------------------ |
| Customer | `Coworker_CustomFields_12345=value`        |
| Booking  | `Booking_CustomFields_12345=value`         |
| Invoice  | `CoworkerInvoice_CustomFields_12345=value` |
| Product  | `Product_CustomFields_12345=value`         |
| Team     | `Team_CustomFields_12345=value`            |
| Contract | `ContractProduct_CustomFields_12345=value` |

<Note>
  The filter performs a case-insensitive string match on the custom field value. You can combine custom field filters with any other standard query filters on the same request.
</Note>

## Registered vs unregistered custom fields

There are two ways to use custom fields:

### Unregistered fields (API-only)

You can store custom data on any record without pre-registering the field. Simply choose a meaningful name and include it in your PUT request:

```json theme={null}
{
  "CustomFields": {
    "Data": [
      {
        "Name": "purchase_order_ref",
        "Type": "string",
        "Value": "PO-2026-001"
      }
    ]
  }
}
```

Unregistered fields are stored and returned in API responses, but they will not appear anywhere in the Nexudus admin UI or member portal.

### Registered fields (visible in the UI)

To make a custom field visible and editable in the UI, create a custom field definition via the `/api/crm/customfields` endpoint. Once registered, the field's `Id` is used as the `Name` when reading and writing values:

```bash cURL theme={null}
curl -X GET \
  "https://spaces.nexudus.com/api/crm/customfields?CustomField_RecordType=12" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

This returns all registered custom field definitions for invoices (RecordType 12). Use the `Id` from each result as the `Name` value in your `CustomFields.Data` entries.

<Note>
  When you register a custom field, the Nexudus UI uses the field definition's `Id` as the `Name` stored on each record. This is why registered fields have numeric names (e.g. `"1414363299"`) rather than human-readable ones.
</Note>
