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

# Custom Fields: Record Types, Types, and Limits

> Add custom fields to DualEntry records: which record types accept them, the nine field types available, company scoping, API access, and reporting behavior.

Custom fields let you store data DualEntry does not model natively, such as an external system's transaction ID, a receipt reference, or a contract owner. You define a field once, choose which record types it applies to, and it then appears on those records in the app, in the public API, and in reports. This page covers which records accept custom fields, the field types available, how many you can create, and where custom field values can be used once populated.

## Record types that accept custom fields

A custom field is defined against one or more record types, and it appears only on the records you select. A field applied to journal entries does not appear on bills unless you also apply it there, so a field intended for several record types must list each one on its definition.

Define and enable custom fields under **Configuration → Accounting Setup → Custom Fields**. Custom fields are a subscribed capability, so if the section is missing on your organization, check your subscription before assuming a permissions problem.

Transaction records that accept custom fields include journal entries, bills, invoices, direct expenses, sales orders, cash sales, and the customer and vendor payment, prepayment, credit, refund, and deposit records. Master data and long-lived records that accept custom fields include customers, vendors, contracts, and fixed assets. Items do not accept custom fields. The applies-to list on the field definition is the authoritative view of what a given field covers.

Intercompany journal entries are the exception worth knowing about: custom fields apply to the `journal_entry` record type and not to `intercompany_journal_entry`, so an entry posted through the intercompany endpoint cannot carry them. If an integration needs to stamp identifiers on multi-entity postings, either carry the identifier in the memo or post one regular journal entry per entity.

Because journal entries accept custom fields, a system that posts entries into DualEntry can carry its own identifiers onto the entry rather than packing them into the memo. That is the usual pattern when an external platform needs to trace a posted entry back to its source transaction or receipt.

Custom fields on master data records behave the same way as on transactions, with one practical difference: master data values are entered once and then read many times, so they are a good place for attributes such as a vendor's internal supplier code or a customer's account manager.

### Restricting a field to specific companies

A field definition can also be scoped to one or more companies. Leave the company list empty and the field is available to every company in the organization; name companies on it and the field is available only on records belonging to those companies. Writing a value to a record whose company is outside that list is rejected with an error naming the companies the field does allow, so an integration that posts across several entities should either leave the field unscoped or scope it to every company it writes to.

Company scoping is set on the field definition, alongside the applies-to list. It is a separate axis from the record type: a field can apply to bills everywhere, to bills in two companies, or to bills and invoices in one company.

## Field types available

DualEntry provides nine custom field types. Choose the narrowest type that fits the data, because the type controls input validation in the app and the value type returned by the API.

The table below lists each type and what it stores:

| Type          | Stores                                                    |
| ------------- | --------------------------------------------------------- |
| Text          | A single line of free text.                               |
| Paragraph     | Multi-line free text.                                     |
| Number        | A numeric value with no currency semantics.               |
| Currency      | A monetary amount.                                        |
| Date          | A calendar date.                                          |
| Boolean       | A true or false checkbox.                                 |
| Single select | One value from a list of options you define.              |
| Multi select  | Any number of values from a list of options you define.   |
| Link          | A URL. The app accepts only `http` and `https` addresses. |

Single select and multi select are the types to reach for when you intend to report on the value later, because a fixed option list keeps the data clean enough to group by. Free text fields accept anything, which makes them convenient for identifiers and unreliable for grouping.

Type validation is not enforced identically everywhere. The app validates a link field as an `http` or `https` URL before it will save, but the API stores what it is given on that type, so an integration can write a value to a link field that the app would have rejected. Validate URLs on your side rather than relying on the field type to do it.

Field names are limited to between 2 and 32 characters. Pick a name that reads well as a column header, since the field name is what appears on the record form, in exports, and in report columns.

## How many custom fields you can create

DualEntry does not impose a maximum number of custom fields per record type or per organization. Ten custom fields on a journal entry is well within normal use, and organizations commonly run more than that across their combined record types.

The practical constraints are usability rather than platform limits. Every field applied to a record type appears on that record's form, so a record type with dozens of fields becomes slower to fill in and easier to fill in wrongly. Apply each field only to the record types that genuinely need it rather than applying it broadly and leaving it empty.

Each record type on a definition carries its own active and required flags, so one field can be optional on bills and required on invoices without a second definition. Marking a field required on a record type blocks saving a record of that type until the field has a value, which is worth confirming against any integration that already creates those records.

Custom fields can be placed under an [approval workflow](./approval-workflows), so changes to the field definitions themselves are reviewable master data changes rather than silent edits. Because a definition can span companies, only organization-wide approval policies apply to it, not policies scoped to a single company. Set that up when the fields carry data other systems depend on.

## Reading and writing custom fields through the API

Custom fields are available on the public API in two places: the field definitions and the values on each record. Definitions are managed through the custom fields endpoints, so an integration can create the fields it needs during setup rather than requiring someone to configure them by hand first.

Record endpoints accept and return custom field values on both create and read. Both list and detail endpoints return custom field data, so you do not need a second call per record to retrieve values once a record has been written.

Because the definitions are writable over the API, an integration that needs to stamp its own identifiers on DualEntry records can provision its fields at install time and then populate them on every record it creates. That keeps the identifiers in structured fields rather than in the memo, where they are harder to read back reliably.

Field definitions are org-wide rather than per-integration, so two integrations that both write to bills share the same definitions. Agree on names before either one provisions its fields, otherwise you end up with near-duplicate fields such as `Source ID` and `Source Id` that no report can sensibly combine. Renaming a field later updates it everywhere the field appears, since records reference the definition rather than storing its name.

For the request and response shape on each record type, see the [API introduction](/developers/guides/introduction) and the [guide to building a custom integration](/developers/guides/building-a-custom-integration).

## Where custom field values can and cannot be used

Once populated, custom field values are readable on the record, returned by the API, and available as report columns and report filters. That covers the common case of pulling a set of records and reconciling them against an external system by a shared identifier.

One limitation is worth planning around: transaction list views in the app cannot be filtered or searched by a custom field value. The journal entry search index covers the record's own fields (record number, code, company name, amount, currency, date, memo, and reference number) along with each line's account, customer, vendor, and memo. No custom field is indexed, and the list endpoint has no custom field parameter. If you need to locate a record by an external identifier, run a report filtered on the custom field or query the custom field values through the API rather than expecting the list search box to find it.

Custom field values are metadata. They do not affect the general ledger, so a value recorded on a posted entry never changes an account balance and can be corrected without a reversing entry.

This matters most when an external system stores a DualEntry identifier on its side and expects to search DualEntry by its own ID later. Keep the DualEntry record ID from the API create response on your side of the integration, so the lookup runs by record ID rather than by custom field value.

## Related reading

* [Approval workflows](./approval-workflows) for putting custom field changes under review.
* [Journal entries](../core-financials/general-ledger/journal-entries) for the record type most often extended with custom fields.
* [Building a custom integration](/developers/guides/building-a-custom-integration) for integration design guidance.
