NetSuite Script ID Prefixes: custbody, custcol, customrecord and More
NetSuite puts a fixed prefix on the script ID of every custom field and custom object, and that prefix tells you where the field lives and how to query it. This table lists each prefix, the menu path where the object is created, and the way to reference it in SuiteScript, SuiteQL and REST.
| Prefix | Object | Where created | Example ID | How to reference | Notes |
|---|---|---|---|---|---|
custbody | Transaction body field | Customization > Lists, Records and Fields > Transaction Body Fields | custbody_qc_inspection | rec.getValue({fieldId: 'custbody_qc_inspection'}); SuiteQL transaction.custbody_qc_inspection; REST body field | Applies to the transaction types ticked on the field. |
custcol | Transaction column (line) field | Customization > Lists, Records and Fields > Transaction Line Fields | custcol_heat_number | rec.getSublistValue({sublistId: 'item', fieldId: 'custcol_heat_number', line: 0}); SuiteQL transactionline.custcol_heat_number | Lives on transactionline in SuiteQL, not transaction. |
custentity | Entity field (customer, vendor, employee, contact, partner) | Customization > Lists, Records and Fields > Entity Fields | custentity_credit_tier | SuiteQL customer.custentity_credit_tier or vendor.custentity_credit_tier | One field can apply to several entity types. |
custitem | Item field | Customization > Lists, Records and Fields > Item Fields | custitem_material_grade | SuiteQL item.custitem_material_grade | Applies to the item types ticked on the field. |
custevent | CRM field (case, task, event, call) | Customization > Lists, Records and Fields > CRM Fields | custevent_root_cause | SuiteQL supportcase.custevent_root_cause | Used on activities and support cases. |
custitemnumber | Item number field (lot and serial numbers) | Customization > Lists, Records and Fields > Item Number Fields | custitemnumber_cert_no | Inventory number record field | Stored per lot or serial number, not per item. |
custrecord | Custom record field, and Other Record field on standard records | On the custom record type, or Customization > Lists, Records and Fields > Other Record Fields | custrecord_qc_result | SuiteQL customrecord_qc_inspection.custrecord_qc_result | Same prefix for both uses; name it after its record to stay readable. |
custpage | Field, sublist or tab added by script at runtime | serverWidget in a Suitelet or beforeLoad user event | custpage_preview | form.addField({id: 'custpage_preview', ...}) | Not stored. Values are lost unless the script saves them to a real field. |
custscript | Script parameter | Script record > Parameters subtab | custscript_ap_approver_role | runtime.getCurrentScript().getParameter({name: 'custscript_ap_approver_role'}) | Defined on the script, valued on the deployment or as a preference. |
customrecord | Custom record type | Customization > Lists, Records and Fields > Record Types | customrecord_qc_inspection | record.load({type: 'customrecord_qc_inspection', id}); SuiteQL FROM customrecord_qc_inspection; REST record/v1/customrecord_qc_inspection | SuiteQL table name is the script ID in lower case. |
customlist | Custom list | Customization > Lists, Records and Fields > Lists | customlist_ship_method | SuiteQL FROM customlist_ship_method (id, name, scriptid, isinactive) | Fields of type List/Record store the value's internal ID. |
customscript | Script record | Customization > Scripting > Scripts | customscript_so_credit_hold_ue | task.create({scriptId: 'customscript_...'}); url.resolveScript | Name it with type suffix (_ue, _cs, _sl, _rl, _mr, _ss). |
customdeploy | Script deployment | Script record > Deploy Script | customdeploy_so_credit_hold_ue | task.create({deploymentId: 'customdeploy_...'}); url.resolveScript | Auto IDs customdeploy1, 2... are hard to manage across accounts. |
customsearch | Saved search | Lists > Search > Saved Searches | customsearch_open_wo_shortage | search.load({id: 'customsearch_open_wo_shortage'}) | Set the ID on the saved search before others depend on it. |
customworkflow | Workflow | Customization > Workflow > Workflows | customworkflow_po_approval | workflow.initiate({recordType, recordId, workflowId: 'customworkflow_po_approval'}) | States and actions inside it carry their own IDs. |
workflowstate / workflowaction | Workflow state and workflow action | Inside the workflow designer | workflowstate_pending_approval | SDF workflow XML; workflow.trigger actionId | Visible mostly when working with SDF or triggering buttons from script. |
customtransaction | Custom transaction type | Customization > Lists, Records and Fields > Transaction Types | customtransaction_scrap_journal | record.create({type: 'customtransaction_scrap_journal'}); SuiteQL transaction.type | Behaves like a transaction, posting or non-posting by setup. |
customrole | Custom role | Setup > Users/Roles > Manage Roles | customrole_integration_ro | SDF role object; runtime.getCurrentUser().roleId | roleId returns the script ID, role returns the internal ID. |
custtab | Custom subtab | Customization > Forms > Subtabs | custtab_quality | Field Display subtab setting on custom fields | Group custom fields on one subtab per process. |
custform | Custom entry or transaction form | Customization > Forms > Entry Forms / Transaction Forms | custform_qc_sales_order | customform field value (internal ID) on the record | Records store the form's internal ID in customform. |
custtmpl | Advanced PDF/HTML template | Customization > Forms > Advanced PDF/HTML Templates | custtmpl_coc_packing_slip | renderer.setTemplateByScriptId({scriptId: 'CUSTTMPL_COC_PACKING_SLIP'}) | Used for certificates of conformance, packing slips, invoices. |
custemailtmpl | Email template | Documents > Templates > Email Templates | custemailtmpl_po_chase | render.mergeEmail with templateId (internal ID) | Scripts usually need the internal ID. |
cseg | Custom segment | Customization > Lists, Records and Fields > Custom Segments | cseg_program | Body and line field cseg_program; SuiteQL transactionline.cseg_program | Use for GL reporting dimensions such as program or contract. |
NetSuite adds the prefix automatically; you type only the suffix, and an underscore after the prefix is the usual convention. Script IDs are stored in lower case. For multi-select fields and length limits, check the SDF custom object reference in NetSuite help for your release.
Get a customization naming review
Send us an export of your custom fields and records and we will flag auto-numbered IDs, misplaced fields and naming that will cause trouble in SuiteQL and SDF.
Optional. The tool and every export work without this. No spam.
How to use it
Search for the prefix you see in a script or saved search formula, for example custcol, to learn which record holds it. The How to reference column gives the pattern for getValue, the SuiteQL table and column, or the REST field. This matters most in SuiteQL: a custbody field is a column on transaction, while a custcol field is a column on transactionline, and a custom record or custom list is its own table named after its script ID. When you design new fields, pick a suffix that names the process and the record, for example custbody_qc_inspection rather than custbody1, because these IDs end up in scripts, integrations and reports for years.
Where to find record type IDs
Custom record types are listed at Customization > Lists, Records and Fields > Record Types, with both the script ID (customrecord_...) and the internal ID. Scripts and SuiteQL use the script ID. Some older APIs and URL parameters use the numeric internal ID, for example rectype on custom record URLs. Standard record types use names such as salesorder in SuiteQL and record.Type.SALES_ORDER in SuiteScript. The Records Catalog (Setup > Records Catalog) shows the SuiteQL table and every column for standard and custom records in your account, including joins, which makes it the fastest way to confirm a custom field's column name.
Worked example
A quality team stores inspections in customrecord_qc_inspection with fields custrecord_qc_result (List/Record pointing to customlist_qc_result) and custrecord_qc_item. Sales orders carry custbody_qc_inspection linking to it. In SuiteQL: SELECT r.id, BUILTIN.DF(r.custrecord_qc_result) AS result FROM customrecord_qc_inspection r. To find orders with inspections: SELECT t.tranid FROM transaction t WHERE t.custbody_qc_inspection IS NOT NULL. In a 2.1 user event on the sales order: context.newRecord.getValue({fieldId: 'custbody_qc_inspection'}) returns the inspection's internal ID, and getText returns its name. The prefixes alone tell you which table to look in at each step.
Common mistakes
Leaving the ID blank gives you custbody1, custbody2 and so on, which nobody can read and which collide across accounts when SDF projects are merged. Changing a script ID later breaks every script, saved search formula and integration mapping that uses it. Querying a custcol field on the transaction table returns an unknown identifier error in SuiteQL because it belongs to transactionline. custpage fields look like fields but are not stored, so values typed into them are lost unless your script copies them to a real field on submit. Finally, the same custrecord prefix is used for fields on custom records and for Other Record fields on standard records, so name them clearly.
Frequently Asked Questions
What is the difference between custbody and custcol?
custbody fields sit on the transaction header, one value per transaction, and appear on the transaction table in SuiteQL. custcol fields sit on each line, one value per line, and appear on transactionline. In SuiteScript you read custbody with getValue and custcol with getSublistValue on the item, expense or other sublist.
How do I query a custom list in SuiteQL?
Use the list's script ID as the table name: SELECT id, name, isinactive FROM customlist_ship_method WHERE isinactive = 'F'. Fields that point to the list store the internal ID, so join on id or wrap the field in BUILTIN.DF to get the label without a join.
Can I rename a field's script ID after it is created?
NetSuite allows changing some script IDs from the record's action menu, but every reference in scripts, saved search formulas, workflows, CSV import maps and integrations must change too, and SDF projects will no longer match. Treat script IDs as permanent and choose them carefully at creation.
Why do some fields start with custpage?
custpage is the required prefix for fields, sublists and tabs added at runtime by a Suitelet or a beforeLoad user event through serverWidget. They are display-only and not stored on the record. Use them for previews, helpers and Suitelet forms, and save any value you need to a real custom field.
If you want people to ask questions about your custom records and fields in plain English and get answers from NetSuite on your own servers, with the query shown, we can set that up.
Related Tools
NetSuite Custom Field Specification Worksheet
Plan custom fields in a table, with IDs, types, applies-to records and sources, and export to Excel for review before building.
NetSuiteNetSuite Custom Record Design Spec Template
A design spec for a new NetSuite custom record type: purpose, fields, relationships, access and reporting, ready to approve before anyone builds it.
NetSuiteNetSuite SuiteQL Custom List and Custom Record Query Generator
Enter a custom list or custom record script ID and its fields to get SuiteQL for its values, its records, a join from transactions, and a ready REST call.
NetSuiteNetSuite Script Deployment Fields and Status Reference
What each field on a Script Deployment record does, which script types have it, and the setting to use for testing and for production.
More NetSuite tools
See all- NetSuite Saved Search Formula Generator
- NetSuite CSV Import Template Guide
- NetSuite Role Permission Matrix Worksheet
- NetSuite Inventory Costing Method Reference
- NetSuite Month End Close Checklist
- NetSuite License Cost Estimator
- NetSuite User Access Request Form Template
- NetSuite SuiteScript Deployment Handover Template
- NetSuite Sandbox and Release Change Log Worksheet
Keep exploring
Free tools
- NetSuite Script Deployment Fields and Status ReferenceWhat each field on a Script Deployment record does, which script types have it, and the setting to use for testing and for production.
- NetSuite SuiteQL Custom List and Custom Record Query GeneratorEnter a custom list or custom record script ID and its fields to get SuiteQL for its values, its records, a join from transactions, and a ready REST call.
- NetSuite SuiteScript Governance Units by Script TypeA lookup of governance unit limits for each SuiteScript script type and the design guidance that follows from them.
ERP fixes and how-tos
- How to Create a Custom Record Type in NetSuiteCreate a NetSuite custom record type: Customization > Lists, Records, & Fields > Record Types, script IDs, permissions, sublists and saved searches.
- How to Customize NetSuite Advanced PDF/HTML TemplatesHow to edit NetSuite Advanced PDF/HTML templates with FreeMarker: add fields, loop sublists, apply conditional logic, and fix common rendering errors.
- How to write and run SuiteQL queries in NetSuiteRun SuiteQL from Analytics > SuiteQL Query Tool or via N/query in SuiteScript. Syntax basics, joins, pagination and real examples for NetSuite reporting.
AI on your ERP
- AI for NetSuite, Beyond the Built-In Text ToolsNetSuite's built-in AI covers text generation, not grounded answers on your own data. See how a private LLM over SuiteQL adds real Q&A and controls.
- AI agents for NetSuite manufacturing operationsAI agents for NetSuite manufacturing: WIP tracking, routing exceptions, and work order status grounded in SuiteQL, with human approval on anything that writes back.
Integrations
- How to integrate Microsoft Teams with Oracle NetSuiteConnect Oracle NetSuite to Microsoft Teams: approval cards, alerts, bots and Entra ID sign-in using SuiteScript, RESTlets and Power Automate or Bot Framework.
- How to add AI agents to Oracle NetSuiteHow to add AI agents to Oracle NetSuite: SuiteQL and REST tool layer, RESTlet writes, role-scoped tokens, human approval, and where a private model fits.