NetSuite stores custom-field definitions separately from the values users enter on transactions, entities and custom records. When you need a data dictionary, field inventory or integration map, you query metadata—not operational instance tables.
This article is a map of the landscape. For a hands-on SuiteQL walkthrough on custom-record fields, use How to Query NetSuite Custom Record Fields With SuiteQL.
Definitions versus instances
| Layer | Answers | Typical SuiteQL target |
|---|---|---|
| Definition (metadata) | What fields exist, labels, types, owning record, list targets | Analytical metadata records from the Records Catalog |
| Instance (data) | What value is stored on a particular record | customer, transaction, customrecord_..., and their cust... columns |
Example:
- Metadata: “
custrecord_example_statusis a SELECT field oncustomrecord_example.” - Instance: “Record 123 has status internal ID 4.”
Mixing these layers produces either empty results or the wrong grain of answer.
Custom field families are not one table
NetSuite groups custom fields by the kind of record they attach to. Common families include:
- Custom-record fields (
custrecord_...) - Transaction body fields (
custbody_...) - Transaction column (line) fields (
custcol_...) - Entity fields (
custentity_...) - Item fields
- CRM fields
- Other-record fields
Do not expect a single SuiteQL record to describe every family. Search the Records Catalog for each family you need. Names such as CustomRecordCustomField are useful search terms when present, but they are not universally available across accounts, features, roles or analytics channels.
How to discover the metadata record for a family
- Open Setup → Records Catalog.
- Select the SuiteScript and REST Query API channel.
- Search by family name, a known field label, or the full
cust...script ID. - Note the analytical record script ID, fields and joins.
- Re-check under the role that will run the query in production.
The catalog is account-, feature-, role- and channel-specific. Oracle documents it as the reference for SuiteQL and constructed N/query availability in the current context. See How to Find SuiteQL Table and Field Names.
Custom-record field metadata in practice
When available, a record such as CustomRecordCustomField exposes rows for custom-record field definitions. A progressive query starts with identity columns confirmed in your catalog (IDs below are illustrative):
SELECT
field_definition.id,
field_definition.scriptid,
field_definition.label
FROM
CustomRecordCustomField field_definition
ORDER BY
field_definition.scriptid
Owning type, field type and select-target columns are added only after confirmation:
- CustomRecordCustomField SuiteQL column reference
- How to Join CustomRecordCustomField to CustomRecordType
- How to Find a Custom Field’s List or Record Type With SuiteQL
If CustomRecordCustomField is missing, diagnose availability rather than hard-coding a forum query: Why CustomRecordCustomField Is Missing From SuiteQL.
Type metadata versus field metadata
Field definitions often point at a custom-record type or other parent definition. Type-level metadata (sometimes searchable as CustomRecordType) describes the custom record itself: script ID, name and related attributes when exposed.
Join field rows to type rows only through catalog-documented fields or joins. The join guide above covers patterns without inventing universal join names.
Where instance columns appear
After a field exists, SuiteQL may also expose it as a column on the operational record:
SELECT
custom_record.id,
custom_record.name,
custom_record.custrecord_example_status
FROM
customrecord_example custom_record
WHERE
custom_record.isinactive = 'F'
That query reads values. It does not replace a metadata inventory. Both are valid; they answer different questions.
SuiteQL metadata versus SuiteCloud XML
Another definition store is SDF / SuiteCloud object XML: <customrecordtype> with nested <customrecordcustomfield> elements. That format is for project objects and deployment, not for analytical SuiteQL.
| Concern | Prefer |
|---|---|
| Runtime inventory in an account | SuiteQL + Records Catalog |
| Project source control and deploy | SuiteCloud object import / XML |
| Field values on live records | Instance SuiteQL or SuiteScript |
Comparison detail: SuiteQL Metadata vs SuiteCloud XML for Custom Records. Import workflow: SuiteCloud: Import a Custom Record and Its Custom Fields.
Building a cross-family inventory
For a full custom-field data dictionary:
- List the field families in scope.
- Confirm a metadata record for each family in the catalog.
- Use separate queries per family—do not force a single universal SQL statement.
- Normalise results in SuiteScript (common columns: script ID, label, field type, owning record, select target).
- Page large result sets.
A complete export pattern with pagination and CSV escaping is in Export a NetSuite Custom-Field Data Dictionary With SuiteScript.
Practical rules of thumb
- Search by script ID when you know the field; search by record type when you know the family.
- Copy analytical IDs from the catalog; never invent joins from UI labels.
- Keep definition queries separate from instance queries.
- Re-verify metadata availability when roles, features or channels change.
- Treat blog and forum SQL as templates until every identifier matches your catalog.
The mental model is simple: custom field metadata tables describe the schema NetSuite administrators configured; instance tables describe the data users entered against that schema.