Skip to content
SeamSetTalk to us

All guides

NetSuite N/llm in 2026.2: models, AI Units, and SuiteScript examples

By Arnaud de Turckheim

Last verified against NetSuite 2026.2

In short

  • The N/llm module is NetSuite’s SuiteScript 2.1 generative AI API: server scripts send prompts to large language models (LLMs) that NetSuite reaches through Oracle Cloud Infrastructure (OCI) Generative AI, and get back text, JSON, embeddings or tool calls.
  • Since the August 2026 minor release, every call consumes NetSuite AI Units from the account’s shared pool. Bring-your-own OCI credentials are gone: ociConfig is ignored without an error.
  • Models: COHERE_COMMAND (Cohere Command A, default), COHERE_COMMAND_VISION (images), GPT_OSS (OpenAI GPT-OSS 120b). Embeddings: COHERE_EMBED (Cohere Embed v4.0).
  • Limits: five concurrent generate calls, 100 governance units per generate call, 30-second default timeout, server scripts only.
  • Have 2025 code? Remove ociConfig, recalibrate usage checks, retest model values, regenerate embeddings (checklist below).

Who this is for

Developers whose 2025 N/llm script now behaves differently, or who want the 2026.2 reference rather than a 2025 tutorial. As of NetSuite 2026.2 (September 2026).

What you need

  • The Server SuiteScript feature: N/llm “is available in NetSuite by default” once it is enabled.
  • A server script: Suitelet, user event, scheduled, map/reduce, RESTlet or workflow action. Not client scripts, and not Custom Tool scripts.
  • AI Units in the account’s pool (cost per AI feature).
  • For Prompt Studio: the Administrator role, or the Setup Prompts (ADMI_PROMPTS) permission.

What changed in N/llm in 2026: AI Units, ociConfig, getRemainingFreeUsage

Change Release What your 2025 code sees
All AI usage runs on NetSuite AI Units, no “separate usage pools” August 2026 minor release Every generate, evaluate or embed call draws on the pool
ociConfig “no longer supported” (N/llm, N/documentCapture, N/task) August 2026 No error; every value is ignored
getRemainingFreeUsage(), getRemainingFreeEmbedUsage() deprecated August 2026 They “remain available for compatibility” and return AI Units remaining
OCI settings, usage tables, SuiteScript and Prompt Studio subtabs removed from AI Preferences August 2026 Prompt Studio itself stays at Setup > Company > AI > Prompt Studio
Cohere Command A Vision August 2026 COHERE_COMMAND_VISION and options.image
N/llm and Prompt Studio “in all regions where NetSuite is supported” August 2026 No region limits (the module page still says “certain regions”)
reasoningEffort and responseFormat for GPT-OSS September 2026 minor release New options on GPT_OSS

Migrating a 2025 N/llm script: checklist

  1. Search your SuiteCloud Development Framework (SDF) project and File Cabinet for ociConfig, getRemainingFree, ModelFamily, EmbedModelFamily, and <modelfamily> in prompt XML (Oracle’s own example still shows the older COHERE_COMMAND_R).
  2. Delete ociConfig. All of it is ignored, including endpointId, which pointed calls at your own OCI dedicated AI cluster. Once no script uses them, delete the NetSuite API secrets that held the OCI fingerprint and private key, and revoke the OCI key.
  3. Recalibrate usage guards. The 2025 free pool counted requests; the same methods now return the account’s AI Units (5 to 25 per request in Oracle’s example). Use llm.getRemainingUsage() with a reserve in AI Units.
  4. Set a current model. Oracle’s enums are plain objects, so a removed key is undefined, and Oracle does not say whether that throws INVALID_MODEL_FAMILY_VALUE or falls back to Command A. Log JSON.stringify(llm.ModelFamily) in the SuiteScript Debugger, set a value explicitly, retest.
  5. Regenerate stored embeddings with Embed v4.0, as Oracle advises (example 6).
  6. Recheck data location if you chose an OCI region for compliance: N/llm data “may be processed globally”.
  7. Test in a sandbox. It has its own AI Unit pool.

Before and after (the ociConfig fields are from Oracle’s generateText page as archived in February 2026):

- const left = llm.getRemainingFreeUsage();  // 2025: free requests left
- if (left < 10) return;
+ const left = llm.getRemainingUsage();      // 2026.2: AI Units left in the account pool
+ if (left < RESERVE_UNITS) return;          // a reserve you choose, in AI Units
  const response = llm.generateText({
      prompt: prompt,
+     modelFamily: llm.ModelFamily.COHERE_COMMAND,
-     ociConfig: {
-         userId: '...', tenancyId: '...', compartmentId: '...',
-         fingerprint: 'custsecret_oci_fingerprint',
-         privateKey: 'custsecret_oci_private_key'
-     }
  });

Models and parameters

RAG (retrieval-augmented generation) means passing options.documents and getting citations back.

llm.ModelFamily Model ID Documents (RAG) Image Tools Reasoning effort
COHERE_COMMAND, COHERE_COMMAND_LATEST cohere.command-a-03-2025 (default) Yes No Yes No
COHERE_COMMAND_VISION, COHERE_COMMAND_VISION_LATEST cohere.command-a-vision No Yes No No
GPT_OSS, GPT_OSS_LATEST openai.gpt-oss-120b No No Yes Yes

All three accept a preamble. Each _LATEST value maps to its base value’s model ID today; Oracle does not say whether that will change, so log response.model.

Pick a model by testing: change only the model family, with parameters valid for both models (table below). A Crowe consultant does this in Prompt Studio (Crowe video, at 7:21) and in a Suitelet calling generateText (at 9:41). Both replies can be correct: he compares tone, wording, structure and instruction following.

Parameter Cohere Command A and Command A Vision GPT-OSS
maxTokens 1 to 4,000 (default 2,000) 1 to 16,000 (default 2,000)
temperature 0 to 1 (default 0.2) 0 to 2 (default 0.2)
topK 0 to 500 (default 500) 0 to 100,000 (default 500)
topP 0 to 1 (default 0.7) 0 to 1 (default 0.7)
frequencyPenalty, presencePenalty 0 to 1 (default 0) -2 to 2 (default 0)
Input limit 256,000 tokens 128,000 tokens

Embeddings: llm.EmbedModelFamily.COHERE_EMBED (or COHERE_EMBED_LATEST) is cohere.embed-v4.0: 1,536 dimensions by default (dimensions 1 to 1,536), up to 96 inputs per call, and truncate (llm.Truncate.START, END, NONE) for inputs over 512 tokens.

N/llm methods and governance units

Method (alias) Returns Governance units
llm.generateText(options) (llm.chat) llm.Response 100
llm.generateTextStreamed(options) (llm.chatStreamed) llm.StreamedResponse 100
llm.evaluatePrompt(options) (llm.executePrompt) llm.Response 100
llm.evaluatePromptStreamed(options) (llm.executePromptStreamed) llm.StreamedResponse 100
llm.embed(options) llm.EmbedResponse 50
llm.createChatMessage, createDocument, createTool, createToolParameter, createToolResult Helper objects None
llm.getRemainingUsage() AI Units remaining None

Each calling method has a .promise version. generateText also takes chatHistory, documents, image, preamble, responseFormat, safetyMode (Cohere only, STRICT by default), timeout (default 30,000 ms), tools and toolResults. Responses carry text, model, citations, toolCalls and usage (token counts).

Examples

These come from Oracle’s documentation and samples; each names its source and any change. Run them in a sandbox before production. require samples are for the SuiteScript Debugger; deployed scripts use define. For a coding agent that writes scripts like these, see AI-assisted SuiteScript development.

1. Generate text

Verbatim from Oracle’s “Send a Prompt to the LLM and Receive a Response”:

/**
*@NApiVersion 2.1
*/
// This example shows how to query the default LLM
require(['N/llm'],
    function(llm) {
        const response = llm.generateText({
            // modelFamily is optional. When omitted, the Cohere Command A model is used.
            prompt: "Hello World!",
            modelParameters: {
                maxTokens: 1000,
                temperature: 0.2,
                topK: 3,
                topP: 0.7,
                frequencyPenalty: 0.4,
                presencePenalty: 0
            }
        });
        const responseText = response.text;
        const remainingUsage = llm.getRemainingUsage(); // View remaining AI Units
    });

On Cohere Command, only one penalty may be above zero, or the call throws MUTUALLY_EXCLUSIVE_ARGUMENTS.

2. Structured JSON output

From the llm.generateText(options) page:

var response = llm.generateText({
    prompt: "My name is Peter Parker, and I'm 25 years old. I live in New York, and I'm definitely not Spiderman.",
    responseFormat: {
            "type": "object",
            "required": ["name", "age"],
            "properties": {
                "name": { "type": "string" },
                "age": { "type": "integer" }
            }
    }
});
var structuredOutput = JSON.parse(response.text);

Works on Cohere models and, since September 2026, GPT-OSS. It cannot be combined with documents, tools or toolResults.

3. A deployable user event with a usage guard

Adapted from Oracle’s fix-typos user event (SuiteWorld 2024 samples on GitHub, same field ID). The reserve check and error handling are SeamSet’s additions: illustrative.

/**
 * @NApiVersion 2.1
 * @NScriptType UserEventScript
 */
define(['N/llm', 'N/log'], (llm, log) => {
    const RESERVE_UNITS = 1000; // AI Units to leave for other features: your choice

    const beforeSubmit = (context) => {
        if (context.type !== context.UserEventType.CREATE &&
            context.type !== context.UserEventType.EDIT) return;
        const text = context.newRecord.getValue({ fieldId: 'salesdescription' });
        if (!text) return;
        if (llm.getRemainingUsage() < RESERVE_UNITS) {
            log.audit('N/llm skipped', 'AI Units below reserve');
            return;
        }
        try {
            const response = llm.generateText({
                prompt: 'Fix typos in this text and return only the corrected text: ' + text,
                modelParameters: { maxTokens: 500, temperature: 0 }
            });
            context.newRecord.setValue({ fieldId: 'salesdescription', value: response.text });
            log.audit('N/llm usage', JSON.stringify(response.usage));
        } catch (e) {
            // For example MAXIMUM_PARALLEL_REQUESTS_LIMIT_EXCEEDED or INAPPROPRIATE_CONTENT_DETECTED
            log.error('N/llm failed, record saved unchanged', e.name + ': ' + e.message);
        }
    };
    return { beforeSubmit };
});

Oracle’s version sets the fields in a .then() that beforeSubmit does not wait for; this one calls generateText synchronously. The call costs 100 of the user event’s 1,000 units and adds the model’s response time to every save.

4. GPT-OSS reasoning effort and Command A Vision (illustrative)

/**
 * @NApiVersion 2.1
 */
require(['N/llm', 'N/file'], (llm, file) => {
    const answer = llm.generateText({
        prompt: "List the three likeliest causes of a late vendor payment.",
        modelFamily: llm.ModelFamily.GPT_OSS,
        modelParameters: { reasoningEffort: llm.ReasoningEffort.LOW, maxTokens: 2000 } // LOW, MEDIUM (default), HIGH
    });
    const caption = llm.generateText({
        prompt: 'Describe the chart in this image in two sentences.',
        modelFamily: llm.ModelFamily.COHERE_COMMAND_VISION,
        image: file.load({ id: 1234 }) // internal ID of an image in your File Cabinet
    });
});

reasoningEffort goes in modelParameters (parameter table and September 2026 release note; the enum page’s sample puts it at the top level). Higher effort “can increase token use”, and with it AI Units: Oracle advises the lowest value that works. Long HIGH answers may need a timeout above 30,000 ms.

options.image takes a file.File. Oracle lists no image formats or size limit (its INVALID_IMAGE error mentions PNG).

5. A Prompt Studio prompt with evaluatePrompt

Prompt Studio keeps wording and model out of your code, so they change without a redeploy.

  1. Go to Setup > Company > AI > Prompt Studio.
  2. Create a prompt with Prompt Type Generic (Oracle: “standalone and can be used in SuiteScript code”). NetSuite prefixes the Script ID with custprompt.
  3. Choose the model under Model Settings and write the Template. Generic prompts have no variable picker: type each ${variable} your code will set.
  4. In the Replace Variable with Value column, enter a test value for each variable, check the Prompt to Preview field, then click Generate Preview. Click Show SuiteScript Example for a call listing every variable.

Template syntax and variables from Oracle’s “Create a Prompt and Evaluate It” (ID illustrative):

${mandatoryVariable} <#if optionalVariable?has_content>${optionalVariable}<#else>World</#if>
const response = llm.evaluatePrompt({
    id: 'custprompt_hello', // your prompt's script ID or internal ID
    variables: {
        mandatoryVariable: "Hello",
        optionalVariable: "People"
    }
});

A missing required variable throws TEMPLATE_PROCESSING_EXCEPTION. Each test preview uses AI Units (Oracle estimates 5 to 10), and deleting a Generic prompt breaks the scripts that use it.

Sarah Muha (RSM) notes that her Generic prompt stays unused until a script calls it (NetSuite Next demo). Oracle has announced that Prompt Studio can also adjust how Ask Oracle behaves in NetSuite Next (SuiteWorld 2025 Product Keynote, at 1:15:50), but does not document it as of 2026.2.

6. Embeddings: find similar items

Adapted from Oracle’s “Find Similar Items Using Embeddings” Suitelet, reduced to fixed inputs:

/**
 * @NApiVersion 2.1
 */
require(['N/llm'], (llm) => {
    const cosineSimilarity = (a, b) => { // same math as Oracle's sample
        const dot = a.reduce((sum, v, i) => sum + v * b[i], 0);
        const norm = (v) => Math.sqrt(v.reduce((sum, x) => sum + x * x, 0));
        return dot / (norm(a) * norm(b));
    };
    const embeddingResult = llm.embed({
        embedModelFamily: llm.EmbedModelFamily.COHERE_EMBED,
        inputs: ['Blue cotton T-shirt', 'Navy cotton tee', 'Steel water bottle'] // 96 max
    });
    const item = embeddingResult.embeddings[0];
    const similarityResults = embeddingResult.inputs.map((itemName, j) => ({
        itemName,
        similarity: cosineSimilarity(item, embeddingResult.embeddings[j])
    }));
    log.debug('Similar items', JSON.stringify(similarityResults));
});

N/llm returns vectors only; Oracle documents no vector store. Store each vector with the model and dimensions that produced it, and never compare across them: on vectors of different lengths, this function returns NaN or a meaningless score.

To regenerate old vectors, use map/reduce: one embed call of up to 96 inputs per map invocation costs 50 of its 1,000 units. Oracle’s full Suitelet splits a SuiteQL (NetSuite’s SQL query language) string across lines inside double quotes, a syntax error: use backticks.

7. Tool calling: let the model query NetSuite

Built from the snippets on Oracle’s “Tooling in the N/llm Module” page. The loop cap and guards are SeamSet’s additions.

/**
 * @NApiVersion 2.1
 */
require(['N/llm', 'N/query'], (llm, query) => {
    const TOOL_DEFINITIONS = {
        findUserId: llm.createTool({
            name: "findUserId",
            description: "Looks up user ID based on user name",
            parameters: [
                llm.createToolParameter({
                    name: "userName",
                    description: "Name of the user",
                    type: llm.ToolParameterType.STRING
                })
            ]
        })
    };
    const TOOL_HANDLERS = {
        findUserId: (options) => {
            const res = query.runSuiteQL({
                query: "SELECT id from entity where fullname=?",
                params: [options.userName]
            }).asMappedResults();
            return res.length === 0 ? -1 : res[0]["id"];
        }
    };
    const tools = Object.values(TOOL_DEFINITIONS);
    let llmResult = llm.generateText({ prompt: "What is the ID of John Smith?", tools: tools });
    let rounds = 0; // caps AI Units and governance
    while ((llmResult.toolCalls || []).length > 0 && rounds < 3) {
        const toolResults = llmResult.toolCalls.map((call) => {
            const handler = TOOL_HANDLERS[call.name];
            const result = handler ? handler(call.parameters) : 'Unknown tool';
            return llm.createToolResult({ call, outputs: [{ result }] });
        });
        llmResult = llm.generateText({ tools, toolResults, chatHistory: llmResult.chatHistory });
        rounds++;
    }
    log.debug('Answer', llmResult.text); // can be empty if the cap stopped pending tool calls
});

With toolResults set, any prompt is ignored. Tools work on Command A and GPT-OSS, not Vision. Parameter types: ARRAY, BOOLEAN, FLOAT, INTEGER, OBJECT, STRING. Oracle: “Only provide tool definitions that are safe and appropriate for the current user context.”

Streaming

The streamed methods return a StreamedResponse: iterate with response.iterator().each(...); response.text holds the text so far. Oracle does not document pushing the stream to a browser.

Limits: concurrency, AI Units, governance

Concurrency. Up to five concurrent generate calls (generate and evaluate methods, streamed or not) and five concurrent embed calls. Beyond that: MAXIMUM_PARALLEL_REQUESTS_LIMIT_EXCEEDED. Oracle does not say whether this is per script or per account: keep map/reduce parallelism at five or fewer, and retry.

AI Units. Each General Access user brings “1,000 AI Units per month of term, provisioned upfront” into one pool for the whole term: 10 users on a 36-month term get 360,000 “for use throughout their term” (Oracle’s example). Unused units expire at term end.

A sandbox gets a separate pool equal to production’s. Packs of 10,000 and 25,000 can be added. Near the limit, administrators get email alerts; then Oracle expects you to “purchase more or pause”.

Oracle estimates one N/llm renewal-email request “could consume from 5-25 AI Units”, and says actual use varies. Illustration only (SeamSet’s arithmetic): 1,000 such calls a month use 60,000 to 300,000 AI Units a year; ten users on a 12-month term bring 120,000.

To measure a real call, compare llm.getRemainingUsage() before and after it in a sandbox with nothing else running, over several calls (Oracle does not say how fast the balance updates).

Where to watch. Setup > Company > View Billing Information shows this month’s account use. Oracle’s docs point to “Setup > Company > AI Units usage dashboard” for a breakdown by date, name and feature, without saying whether “name” is a script: log response.usage yourself.

Governance. The generate and evaluate methods cost 100 units each, embed 50. From Oracle’s usage limit and map/reduce governance pages:

Script type Usage units Generate calls at most, if nothing else runs
Suitelet, user event 1,000 per execution 10
Workflow action 1,000 per workflow state, shared by all actions in it 10
RESTlet 5,000 50
Scheduled 10,000 100
Map/reduce Per invocation: getInputData 10,000, map 1,000, reduce 5,000, summarize 10,000 100, 10, 50, 100
SuiteScript Debugger 1,000 10

Exceeding a limit throws SSS_USAGE_LIMIT_EXCEEDED. Map/reduce also caps map invocations at 5 minutes, reduce at 15.

LLM Prompt workflow action (Oracle sample)

Oracle publishes a SuiteFlow action that calls N/llm as a GitHub sample (oracle-samples/netsuite-suitecloud-samples, folder suitecloud-ai-solutions-catalog/llm-prompt-workflow-action). A developer deploys it once; administrators then use it without code.

It holds the workflow action script wf_sendLlmPrompt.js (script record customscript_llm_prompt_workflowaction, “LLM Prompt”), the parameter custscript_llm_prompttext (“Prompt Text”), and return type TEXT on the script record, so SuiteFlow’s Store Result In can save the answer. The deployment ships as Testing, all roles.

Deploy it:

  1. In the target account (sandbox first), enable the SuiteCloud Development Framework feature; the manifest also requires Server SuiteScript (SERVERSIDESCRIPTING) and SuiteFlow (WORKFLOW). Use a role allowed to deploy SDF projects.
  2. Install the SuiteCloud CLI (command-line interface): npm install -g @oracle/suitecloud-cli (Node.js and JDK versions in its README).
  3. Clone the repository, open the sample folder and run npm install: the project runs its Jest unit tests before every deploy.
  4. Run suitecloud account:setup to link the project to the account.
  5. Run suitecloud project:deploy.
  6. Before others rely on it, set the deployment status to Released and narrow its audience if needed. Oracle’s docs conflict on whether Testing runs for the owner only.

Use it (condensed from the README):

  1. Go to Customization > Workflow > Workflows > New, pick the record type and an event-based trigger (for example After Record Submit).
  2. In a state, add a new action: LLM Prompt (Custom).
  3. Set the action trigger (for example Trigger On: Entry) and Store Result In (for example Memo).
  4. Enter the Prompt Text (for example “Summarize this record in one sentence”). Under 5 characters, the script throws INVALID_PROMPT.
  5. Save a matching record and check the field.

Before production:

  • The script appends the whole record (JSON.stringify(context.newRecord)) to every prompt. Send only the fields you need: fewer AI Units, less data exposed.
  • It logs the deprecated llm.getRemainingFreeUsage.promise(), which still works. If you switch to llm.getRemainingUsage.promise(), update the mock in __tests__/wf_sendLlmPrompt.test.js too, or the pre-deploy tests fail and block the deploy.

N/llm, Text Enhance, custom MCP tool, Ask Oracle or an external assistant?

Option Who drives it Model AI Units Pick it when
N/llm Your server script Command A, Vision or GPT-OSS Yes Your code calls the model: automations or your own Suitelet UI
Text Enhance action A user, from a text field’s Text Enhance button NetSuite’s Yes Users rework a field’s text on demand, with no code (Text Enhance)
Custom MCP tool An AI client, through the NetSuite AI Connector Service (Oracle’s MCP server) The client’s No Users of an AI client need one rule-bound operation (build one)
Ask Oracle A user inside NetSuite NetSuite’s Yes Users want answers in NetSuite, once your account has it
Claude, ChatGPT or Claude Code plus AI Connector A person in the client The client’s No Ad hoc questions (set it up)

The paths do not mix: “The N/http, N/https, N/llm, and N/sftp modules are not supported in custom tool scripts.” Ask Oracle is “included with your NetSuite license” but rolls out in phases, and no role has access by default.

Text Enhance action or script? A Text Enhance action rewrites a field on click; the user reviews it. An N/llm user event can fill another field on save: Example 3, with setValue on a new field. A Protelo webinar demos the first (at 4:25) and suggests the second (at 25:35).

Suggested uses. An Oracle NetSuite solution consultant suggests product-review summaries on SuiteCommerce pages, analysis of how products are received, customer and project summaries, and text extracted from documents into fields; he also built an app that scores a pipeline for an executive dashboard (Tavano Team webinar).

Check native features first. A Crowe demo scores late-payment risk with N/llm (Crowe NetSuite Solutions, late-payment scoring, at 0:50), but Payment Date Prediction (2026.1, off by default) now predicts, with machine learning, when an invoice will be paid and how many days it may be overdue (requirements).

Data considerations (what Oracle states)

  • “The data is not used by third parties for model training.”
  • Your data “may be processed globally according to the Oracle Services Privacy Policy”.
  • Embeddings are as sensitive as the source data and fall under the same rules.
  • Oracle’s AI features, N/llm included, are not assessed for the US Health Insurance Portability and Accountability Act (HIPAA): send no electronic protected health information.
  • Validate AI output: Oracle disclaims liability for its use. Tool handlers need “proper validation to prevent unintended operations or unauthorized access”.

Common problems

Symptom Cause Fix
A free-usage guard always passes, or blocks everything It now reads the account’s AI Units, not requests left Recalibrate in AI Units
INVALID_MODEL_FAMILY_VALUE, or different output since August 2026 Old or mistyped model value Log llm.ModelFamily; set a current value
Similarity scores are NaN or meaningless Old vectors compared with 1,536-dimension Embed v4.0 vectors Regenerate all vectors with one model and dimensions value
SSS_USAGE_LIMIT_EXCEEDED Too many generate calls (100 units each) for the script type Move bulk work to map/reduce
MAXIMUM_PARALLEL_REQUESTS_LIMIT_EXCEEDED More than five concurrent generate or embed calls Lower concurrency, retry
Workflow sample deploy stops on failed tests Deprecated call swapped without updating the Jest mock Update __tests__/wf_sendLlmPrompt.test.js
Syntax error after pasting Oracle’s tool or embeddings Suitelet Double-quoted strings split across lines Join lines or use backticks
MUTUALLY_EXCLUSIVE_ARGUMENTS responseFormat with documents or tools, or both penalties above zero on Cohere Command Drop one
REASONING_EFFORT_PARAMETER_NOT_AVAILABLE, MODEL_1_DOES_NOT_ACCEPT_DOCUMENTS, COHERE_VISION_DOES_NOT_SUPPORT_TOOLING Option not supported by that model Check the model table
INAPPROPRIATE_CONTENT_DETECTED Safety filtering (STRICT default on Cohere), partly applied even with safety off Try llm.SafetyMode.CONTEXTUAL or rephrase

Doc traps in Oracle’s pages:

  • The module page says llm.ModelFamily sets options.model; the parameter is options.modelFamily.
  • Error tables mention llm.SafetyMode.OFF, absent from the enum.
  • INVALID_ID_PREFIX is documented for IDs not starting with custprompt, yet the method page’s syntax passes -1 and Oracle’s samples pass stdprompt_gen_purch_desc_invt_item and a numeric ID. Pass your custprompt script ID or internal ID.
  • The module page types ToolCall.parameters as an array; Oracle’s handlers read it as an object (options.userName).

FAQ

Does ociConfig still work?

No. Since the August 2026 minor release, NetSuite accepts ociConfig without an error but ignores every value, including endpointId for a dedicated AI cluster. Remove it and retire the secrets and OCI key it used.

Does N/llm cost money, and what happens when AI Units run out?

N/llm consumes NetSuite AI Units, included with eligible licenses and pooled for the term. Near the limit, administrators get email alerts, then Oracle expects you to buy more or pause. Oracle does not document what an N/llm call does once the pool is empty.

Which N/llm model should I use?

Command A (COHERE_COMMAND, the default) for documents with citations and for tools. Command A Vision for images. GPT-OSS for reasoning effort, answers up to 16,000 tokens, and tools. Oracle publishes no per-model AI Unit rate: measure in a sandbox.

Do I need to regenerate my embeddings?

Yes, if you stored vectors from an embed model older than Cohere Embed v4.0, which returns more dimensions (1,536) than earlier models. Oracle says you “should regenerate those embeddings”. Batch up to 96 inputs per embed call in map/reduce.

Can I call Claude or my own model from SuiteScript?

Not through N/llm: Oracle rules out bringing your own model or provider. A server script can call a third-party API through N/https, under that provider’s terms. To have Claude work on NetSuite data, use the AI Connector, which consumes no AI Units.

Can I rely on Command A for counts and totals?

A Reddit user reported wrong counts from Command A compared with ChatGPT (December 2025). Do not ask a model to count over raw text. Compute numbers with SuiteQL in a tool handler, as Oracle’s tool sample does, and let the model phrase the result.

How do I switch N/llm off?

Oracle says there is no single account-level switch for all AI. N/llm follows the Server SuiteScript feature, and turning that off stops every server script. In practice, control who deploys scripts and review those that load N/llm (governing AI access).

Where do I see how many AI Units my scripts used?

Administrators see account totals on View Billing Information and the AI Units usage dashboard, which may not identify scripts. In code, log response.usage per call and compare llm.getRemainingUsage() before and after.

Sources

Oracle Help Center

Oracle GitHub

Oracle NetSuite video

Third party

SeamSet builds this kind of automation from a plain-language request and ships it sandbox first: tested, documented, reviewed and approved by your NetSuite admin, with audit and rollback.