How to Query NetSuite Custom Record Fields With SuiteQL
Use the NetSuite Records Catalog to find CustomRecordCustomField metadata, verify available fields and build a SuiteQL query for custom-record field IDs and labels.
Sometimes the data you need is not stored in a custom record instance. You need information about the custom record’s definition: its fields, script IDs, labels and relationships.
That is why developers go looking for a SuiteQL record such as CustomRecordCustomField.
The awkward part is that NetSuite’s analytics schema is dynamic. The records and fields available to SuiteQL depend on the account, enabled features and the role executing the query. A query copied from another account can therefore fail even when its SQL is valid.
The reliable approach is to use the account’s Records Catalog first and write the query from the schema it exposes.
Start in the Records Catalog
Open Setup → Records Catalog and select the SuiteScript and REST Query API channel.
Oracle describes the Records Catalog as the account-specific reference for record types, fields and joins available to SuiteQL and constructed N/query queries. It reflects the current role’s permissions and the account’s enabled features.
Search for these terms:
CustomRecordCustomFieldcustom record field- The script ID of a known field, such as
custrecord_example_status
If the record is available, record its exact script ID, field IDs and joins. Do not assume that the labels shown in the NetSuite customisation UI are valid SuiteQL identifiers.
The catalog’s Global Field Search is particularly useful when you know a field label or script ID but not the record that exposes it.
Build the query progressively
Begin with only the fields confirmed in your Records Catalog:
SELECT
field_definition.id,
field_definition.scriptid,
field_definition.label
FROM
CustomRecordCustomField field_definition
ORDER BY
field_definition.scriptid
The record and column IDs above illustrate the intended shape. Use the exact IDs displayed in your account. If label is unavailable but another name field is exposed, select that field instead.
Once the basic query works, add the field that identifies the owning custom-record type:
SELECT
field_definition.id,
field_definition.scriptid,
field_definition.label,
field_definition.recordtype
FROM
CustomRecordCustomField field_definition
WHERE
field_definition.recordtype = ?
ORDER BY
field_definition.scriptid
Pass an internal ID as a bind parameter rather than interpolating it into the SQL:
const results = query.runSuiteQL({
query: suiteql,
params: [customRecordTypeId],
}).asMappedResults();
If the catalog exposes a join from the field definition to the custom-record type, use that documented relationship to return the type’s script ID or name. Join IDs are account-schema contracts; guessing one from the UI label is unreliable.
Metadata is different from record data
These two questions require different queries:
- Which fields are defined on this custom-record type? Query the metadata record exposed by the Records Catalog.
- What values are stored in those fields? Query the custom record itself using its
customrecord_...table andcustrecord_...columns.
For example, after discovering custrecord_example_status, a data query might look like this:
SELECT
custom_record.id,
custom_record.name,
custom_record.custrecord_example_status
FROM
customrecord_example custom_record
WHERE
custom_record.isinactive = 'F'
The metadata query discovers the field definition. The data query reads the values stored on individual custom-record instances.
Why a valid-looking query may fail
The record is absent from the catalog
The current role may not have access, the record may not be available through the selected analytics channel, or the feature that provides it may be disabled.
A UI label was used as a field ID
SuiteQL uses analytical field IDs. Confirm them in the Records Catalog instead of converting a display label into a guessed identifier.
A field is visible but unavailable
Turn on Show Unavailable Items in the Records Catalog. It can reveal a permission or feature restriction that would otherwise look like a SQL error.
The query returns metadata but not custom-record values
CustomRecordCustomField describes field definitions. Query the relevant customrecord_... record type to retrieve stored values.
The results differ between roles
The Records Catalog and SuiteQL results are role-aware. Test using the same role that will execute the production script or integration.
Other custom field families
NetSuite distinguishes custom-record fields from other custom field types, including:
- Transaction body fields
- Transaction column fields
- Entity fields
- Item fields
- CRM fields
- Other-record fields
Do not expect one metadata record to describe every family. Search the Records Catalog for the specific field family and confirm its availability before composing a combined metadata report.
A practical discovery checklist
- Open Setup → Records Catalog with the execution role.
- Select the SuiteScript and REST Query API channel.
- Search by record name, field label and script ID.
- Copy the analytical record and field IDs exactly.
- Run a minimal three-column query.
- Add the owning-record relationship only after confirming its field or join.
- Use bind parameters for filters.
- Test under the production role.
The important lesson is not a single universal query. It is that the Records Catalog is the source of truth for the SuiteQL schema actually available in your NetSuite account.