# Custom fields
Source: https://www.desktopaccountingapi.com/docs/quickbooks/custom-fields/

> Read QuickBooks custom fields on records and lines, set them on new transaction lines, and change them through passthrough.

QuickBooks Desktop lets users add their own fields, such as "Region" on customers or "Lot color" on invoice lines. QuickBooks calls them data extensions; the API calls them custom fields.

## Reading custom fields

Records and lines that can carry custom fields return them in `customFields`:

```json
"customFields": [
  { "ownerId": "0", "name": "Region", "value": "West" },
  { "ownerId": "0", "name": "Sales channel", "value": "Distributor" }
]
```

| Field | Meaning |
| --- | --- |
| `ownerId` | `"0"` for the custom fields people create and see in QuickBooks. Other values belong to fields an application created for its own use. |
| `name` | The field's name as defined in QuickBooks. |
| `value` | The value, always as a string. QuickBooks also stores numbers, dates and amounts as text here. |

Fields with no value on a record are not listed. More than 50 resource types carry `customFields`, including customers, vendors, employees, items, accounts and most transactions and their lines. The API reference shows `customFields` on each.

## Setting custom fields on new lines

When you create an invoice, estimate, sales order, sales receipt, credit memo, purchase order or bill, each item and expense line accepts `customFields`:

```json
POST /v1/quickbooks-desktop/invoices
{
  "customerId": "80000012-1730312001",
  "lines": [
    {
      "itemId": "80000003-1730311000",
      "quantity": 2,
      "rate": "125.00",
      "customFields": [{ "ownerId": "0", "name": "Lot color", "value": "Blue" }]
    }
  ]
}
```

The field must already be defined in the company file for that kind of line. QuickBooks rejects an unknown name with a `QBD_REQUEST_ERROR` that carries its status code and message.

## Changing custom fields on existing records

QuickBooks handles custom-field values on existing records through separate requests (`DataExtAdd`, `DataExtMod` and `DataExtDel`), not through the record's own update. Send them through [passthrough](https://www.desktopaccountingapi.com/docs/quickbooks/passthrough/):

```json
POST /v1/end-users/eu_01j9.../passthrough/quickbooks_desktop
{
  "DataExtModRq": {
    "DataExtMod": {
      "OwnerID": "0",
      "DataExtName": "Region",
      "ListDataExtType": "Customer",
      "ListObjRef": { "ListID": "80000012-1730312001" },
      "DataExtValue": "East"
    }
  }
}
```

Use `DataExtAddRq` when the record has no value for the field yet, and `DataExtDelRq` to remove a value. Defining new custom fields (`DataExtDefAdd`) also works through passthrough. Changing a company's field definitions affects how your customer sees their data, so do it only with their agreement.

## Fields owned by other applications

Custom fields with an `ownerId` other than `"0"` were created by an application for its own use and are hidden in the QuickBooks window. Leave them alone unless they are yours.

## The field we keep

After setup, our service stores one private data extension on the company itself: a random identifier that lets the connection recognize the company file, even after a backup is restored or the file is moved. It has its own owner ID, does not show in the QuickBooks window, and never appears in `customFields`. Do not delete it through passthrough; without it, the connection falls back to recognizing the company by its name and details.
