Chapter 10.1

Integration Strategy

Plan your integration architecture: point-to-point vs. middleware, iPaaS options, patterns, and error handling strategies.

Integration Architecture Overview

Every NetSuite implementation involves integrationsβ€”whether connecting to e-commerce platforms, CRM systems, banks, or third-party applications. A well-planned integration strategy prevents data silos, reduces manual work, and ensures system reliability.

Point-to-Point Architecture

Pros: Simple, direct, lower initial cost. Cons: Spaghetti architecture, hard to maintain at scale.

Hub and Spoke Architecture (iPaaS/Middleware)

Pros: Centralized monitoring, reusable connectors, scalable. Cons: Higher cost, additional system to manage.

Integration Method Comparison

Method Use Case Volume Complexity
CSV Import Batch data loads, migrations Low-Medium Low
SuiteTalk SOAP Legacy systems, complex operations Medium-High High
SuiteTalk REST Modern integrations, mobile apps Medium-High Medium
RESTlets Custom endpoints, complex logic Any Medium-High
iPaaS (Celigo, etc.) Multiple systems, complex flows Any Medium
SuiteAnalytics Connect BI tools, reporting extracts Read-only Low-Medium

Integration Patterns

Real-Time vs. Batch

Pattern When to Use Examples
Real-Time (Synchronous) Immediate response required Price checks, inventory availability
Near Real-Time (Async) Quick updates, no immediate response Order creation, customer updates
Batch (Scheduled) High volume, non-time-sensitive Daily inventory sync, GL exports
Event-Driven Triggered by specific actions Order shipped β†’ update e-commerce

Authentication Methods

Method Description Recommendation
Token-Based Authentication (TBA) Consumer/Token key pairs Preferred for server-to-server
OAuth 2.0 Standard OAuth flow Preferred for user-facing apps
User Credentials Email/Password Deprecatedβ€”avoid

Error Handling Strategy

ERROR HANDLING FRAMEWORK ═══════════════════════════════════════════════════════════════ ERROR CATEGORIES ─────────────────────────────────────────────────────────────── 1. TRANSIENT ERRORS (retry) - Network timeouts - Rate limit exceeded - Temporary service unavailability β†’ Strategy: Exponential backoff retry 2. DATA ERRORS (fix and retry) - Validation failures - Missing required fields - Invalid references β†’ Strategy: Log, alert, queue for review 3. SYSTEM ERRORS (escalate) - Authentication failures - Permission denied - API changes β†’ Strategy: Alert immediately, stop processing RETRY PATTERN ─────────────────────────────────────────────────────────────── Attempt 1: Immediate Attempt 2: Wait 1 second Attempt 3: Wait 5 seconds Attempt 4: Wait 30 seconds Attempt 5: Wait 2 minutes β†’ After 5 failures: Move to dead letter queue MONITORING REQUIREMENTS ─────────────────────────────────────────────────────────────── β€’ Success/failure counts by integration β€’ Average processing time β€’ Queue depth (pending records) β€’ Error rate trending β€’ Alerts for threshold breaches

iPaaS Comparison

Platform NetSuite Focus Strengths
Celigo High (NetSuite partner) Pre-built connectors, integrator.io
Dell Boomi Medium Enterprise scale, broad connector library
Workato Medium User-friendly, strong automation
MuleSoft Medium Enterprise APIs, Salesforce integration
Tray.io Low-Medium Flexible workflows, developer-friendly
🎯 Consultant Insight

Start simple. Point-to-point integrations are fine for 2-3 connections. Only move to iPaaS when you have 4+ integrations or need advanced features like data transformation, error handling, and monitoring. The iPaaS monthly cost often exceeds the development savings unless you truly need the capability.

Integration Planning Checklist

Chapter 10.2

SuiteTalk SOAP

SOAP web services for NetSuite integration: authentication, operations, and best practices.

SuiteTalk SOAP Overview

SuiteTalk SOAP is NetSuite's original web services API. While the REST API is now preferred for new integrations, SOAP remains important for legacy systems and complex operations not yet available in REST.

Feature SOAP REST
Protocol XML-based SOAP JSON over HTTP
Maturity 20+ years, fully featured Newer, growing coverage
Learning Curve Steeper (WSDL, namespaces) Lower (standard REST)
Custom Records Full support Full support
Saved Searches Full support Via SuiteQL
Asynchronous Yes (native) Limited

WSDL and Endpoints

SUITETALK SOAP ENDPOINTS ═══════════════════════════════════════════════════════════════ WSDL URL: https://<ACCOUNT_ID>.suitetalk.api.netsuite.com/wsdl/v2024_2_0/netsuite.wsdl ENDPOINT URL: https://<ACCOUNT_ID>.suitetalk.api.netsuite.com/services/NetSuitePort_2024_2 ACCOUNT ID FORMAT: ─────────────────────────────────────────────────────────────── Production: TSTDRV1234567 Sandbox: TSTDRV1234567_SB1 Development: TSTDRV1234567_DEV FINDING YOUR ACCOUNT ID: Setup β†’ Company β†’ Company Information β†’ Account ID

Authentication Setup

Token-Based Authentication (TBA)

TBA SETUP PROCESS ═══════════════════════════════════════════════════════════════ 1. CREATE INTEGRATION RECORD Setup β†’ Integration β†’ Manage Integrations β†’ New β”œβ”€β”€ Name: "My Integration" β”œβ”€β”€ State: Enabled β”œβ”€β”€ Token-Based Authentication: Checked └── β†’ Save β†’ Note Consumer Key & Secret 2. CREATE ACCESS TOKEN Setup β†’ Users/Roles β†’ Access Tokens β†’ New β”œβ”€β”€ Application: "My Integration" β”œβ”€β”€ User: Integration user β”œβ”€β”€ Role: Integration role └── β†’ Save β†’ Note Token ID & Secret SOAP HEADER WITH TBA: ─────────────────────────────────────────────────────────────── <tokenPassport> <account>TSTDRV1234567</account> <consumerKey>consumer_key_here</consumerKey> <token>token_id_here</token> <nonce>random_string</nonce> <timestamp>unix_timestamp</timestamp> <signature algorithm="HMAC-SHA256">signature</signature> </tokenPassport>

Common Operations

Operation Description Use Case
get Retrieve single record by ID Fetch customer details
getList Retrieve multiple records by IDs Batch fetch orders
add Create new record Create sales order
update Modify existing record Update customer address
upsert Add or update based on external ID Sync from external system
delete Remove record Delete draft order
search Query records with criteria Find open invoices
asyncAddList Bulk add asynchronously Import 10,000 records

Search Operations

SOAP SEARCH EXAMPLE ═══════════════════════════════════════════════════════════════ <search> <searchRecord xsi:type="TransactionSearchBasic"> <type operator="anyOf"> <searchValue>_salesOrder</searchValue> </type> <status operator="anyOf"> <searchValue>_salesOrderPendingFulfillment</searchValue> </status> <tranDate operator="within"> <searchValue>2025-01-01T00:00:00</searchValue> <searchValue2>2025-12-31T23:59:59</searchValue2> </tranDate> </searchRecord> </search> SEARCH TYPES: ─────────────────────────────────────────────────────────────── Basic: Simple criteria on main record Joined: Include related record criteria Advanced: Use saved search definition
⚠️ SOAP Concurrency Limits
  • Concurrent requests: Based on SuiteCloud license tier
  • Records per request: 200 for add/update, 1000 for search results
  • Request timeout: 15 minutes
  • Rate limiting: Requests may be throttled under load
πŸ’‘ SOAP Integration Best Practices
  • Use external IDs: Enable upsert operations and avoid duplicate lookups
  • Batch operations: Use addList/updateList instead of individual calls
  • Async for large volumes: Use asyncAddList for bulk operations
  • Handle pagination: Search results may require multiple pages
  • Cache WSDL locally: Avoid re-downloading on every request
  • Implement retry logic: Handle transient failures gracefully
🎯 Consultant Insight

SOAP is verbose but powerful. For new integrations, prefer REST unless you need features only available in SOAP (like certain async operations or complex saved search execution). When working with legacy SOAP integrations, prioritize moving to TBA authentication if still using user credentialsβ€”it's more secure and doesn't count against concurrent user limits.

Chapter 10.3

SuiteTalk REST

Modern REST API for NetSuite: record operations, SuiteQL, OAuth 2.0, and integration patterns.

REST API Overview

SuiteTalk REST provides a modern, JSON-based API for NetSuite integration. It follows REST conventions and is easier to use than SOAP for most common operations.

API Endpoints

REST API BASE URLS ═══════════════════════════════════════════════════════════════ RECORD API: https://<ACCOUNT_ID>.suitetalk.api.netsuite.com/services/rest/record/v1 QUERY API (SuiteQL): https://<ACCOUNT_ID>.suitetalk.api.netsuite.com/services/rest/query/v1 METADATA: https://<ACCOUNT_ID>.suitetalk.api.netsuite.com/services/rest/record/v1/metadata-catalog EXAMPLES: ─────────────────────────────────────────────────────────────── GET customer: GET /customer/123 Create customer: POST /customer Update customer: PATCH /customer/123 Delete customer: DELETE /customer/123 List customers: GET /customer

Authentication

OAuth 2.0 Setup

OAUTH 2.0 FLOW ═══════════════════════════════════════════════════════════════ 1. AUTHORIZATION REQUEST ─────────────────────────────────────────────────────────────── GET https://<ACCOUNT_ID>.app.netsuite.com/app/login/oauth2/authorize.nl ?response_type=code &client_id=<CLIENT_ID> &redirect_uri=<REDIRECT_URI> &scope=rest_webservices &state=<STATE> 2. TOKEN EXCHANGE ─────────────────────────────────────────────────────────────── POST https://<ACCOUNT_ID>.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token Content-Type: application/x-www-form-urlencoded grant_type=authorization_code &code=<AUTH_CODE> &redirect_uri=<REDIRECT_URI> &client_id=<CLIENT_ID> &client_secret=<CLIENT_SECRET> 3. API REQUEST WITH TOKEN ─────────────────────────────────────────────────────────────── GET /services/rest/record/v1/customer/123 Authorization: Bearer <ACCESS_TOKEN>

Token-Based Authentication

TBA HEADER FORMAT ═══════════════════════════════════════════════════════════════ Authorization: OAuth realm="ACCOUNT_ID", oauth_consumer_key="consumer_key", oauth_token="token_id", oauth_signature_method="HMAC-SHA256", oauth_timestamp="unix_timestamp", oauth_nonce="random_string", oauth_version="1.0", oauth_signature="base64_encoded_signature"

Record Operations

REST RECORD OPERATIONS ═══════════════════════════════════════════════════════════════ CREATE CUSTOMER (POST) ─────────────────────────────────────────────────────────────── POST /services/rest/record/v1/customer Content-Type: application/json { "companyName": "Acme Corporation", "email": "contact@acme.com", "subsidiary": {"id": "1"} , "custentity_external_id": "ACME-001" } Response: 201 Created { "id": "12345", "links": [...] } UPDATE CUSTOMER (PATCH) ─────────────────────────────────────────────────────────────── PATCH /services/rest/record/v1/customer/12345 Content-Type: application/json { "phone": "555-1234", "custentity_credit_limit": 50000 } Response: 204 No Content GET WITH SUBLISTS ─────────────────────────────────────────────────────────────── GET /services/rest/record/v1/salesOrder/67890?expandSubResources=true Returns order with line items, addresses, etc.

SuiteQL Queries

SUITEQL VIA REST API ═══════════════════════════════════════════════════════════════ POST /services/rest/query/v1/suiteql Content-Type: application/json Prefer: transient { "q": "SELECT id, companyname, email FROM customer WHERE isinactive = 'F' AND datecreated > '2025-01-01' ORDER BY companyname" } RESPONSE: { "links": [...], "count": 150, "hasMore": true, "offset": 0, "totalResults": 1523, "items": [ {"id": "123", "companyname": "Acme Corp", "email": "..."}, {"id": "124", "companyname": "Beta Inc", "email": "..."}, ... ] } PAGINATION: ─────────────────────────────────────────────────────────────── Add to query: FETCH NEXT 1000 ROWS ONLY Add header: Prefer: respond-async Next page: Follow "next" link in response

Sublist Operations

WORKING WITH SUBLISTS ═══════════════════════════════════════════════════════════════ ADD LINE TO SALES ORDER ─────────────────────────────────────────────────────────────── POST /services/rest/record/v1/salesOrder/67890/item Content-Type: application/json { "item": {"id": "100"}, "quantity": 5, "rate": 99.99 } UPDATE LINE ─────────────────────────────────────────────────────────────── PATCH /services/rest/record/v1/salesOrder/67890/item/1 Content-Type: application/json { "quantity": 10 } DELETE LINE ─────────────────────────────────────────────────────────────── DELETE /services/rest/record/v1/salesOrder/67890/item/1 GET ALL LINES ─────────────────────────────────────────────────────────────── GET /services/rest/record/v1/salesOrder/67890/item

Error Handling

REST API ERROR RESPONSES ═══════════════════════════════════════════════════════════════ 400 BAD REQUEST ─────────────────────────────────────────────────────────────── { "type": "https://www.netsuite.com/problems/validation", "title": "Invalid field value", "status": 400, "o:errorDetails": [ { "detail": "Invalid reference key '999' for field 'subsidiary'", "o:errorCode": "INVALID_KEY_OR_REF" } ] } 429 TOO MANY REQUESTS ─────────────────────────────────────────────────────────────── { "type": "https://www.netsuite.com/problems/rate-limiting", "title": "Rate limit exceeded", "status": 429, "o:errorDetails": [ { "detail": "Request rate limit exceeded. Retry after 60 seconds." } ] }
πŸ’‘ REST API Best Practices
  • Use SuiteQL for queries: More flexible than record filtering
  • Expand sublists selectively: Only request what you need
  • Handle pagination: Use offset/limit for large result sets
  • Check for async: Large operations may return 202 Accepted
  • Use external IDs: Enable idempotent operations
🎯 Consultant Insight

REST is the future of NetSuite integrations. Start new projects with REST unless you specifically need SOAP features. The REST API's JSON format is easier to debug, and OAuth 2.0 is standard across modern applications. SuiteQL via REST gives you SQL-like flexibility that's often easier than building complex search criteria.

Chapter 10.4

RESTlets

Build custom REST endpoints in NetSuite for complex integration logic and specialized operations.

RESTlet Overview

RESTlets are custom SuiteScript endpoints that respond to HTTP requests. They enable you to build custom APIs within NetSuite, perfect for complex business logic that standard APIs don't cover.

Use RESTlets When Use Standard API When
Complex business logic required Simple CRUD operations
Multiple records in single transaction Single record operations
Custom data transformation Standard field mapping
Aggregate data from multiple sources Single record type queries
Custom authentication/validation Standard authentication

RESTlet Structure

RESTLET SCRIPT TEMPLATE (SuiteScript 2.1) ═══════════════════════════════════════════════════════════════ /** * @NApiVersion 2.1 * @NScriptType Restlet */ define(['N/record', 'N/search', 'N/log'], (record, search, log) => { /** * GET request handler * @param {Object} requestParams - URL parameters * @returns {Object} Response data */ const get = (requestParams) => { try { const customerId = requestParams.customerId; if (!customerId) { return { error: 'customerId is required' }; } // Load customer record const customer = record.load({ type: record.Type.CUSTOMER, id: customerId }); return { id: customer.id, name: customer.getValue('companyname'), email: customer.getValue('email'), balance: customer.getValue('balance') }; } catch (e) { log.error('GET Error', e.message); return { error: e.message }; } }; /** * POST request handler * @param {Object} requestBody - Request body (JSON parsed) * @returns {Object} Response data */ const post = (requestBody) => { try { const { customerName, email, subsidiary } = requestBody; // Validation if (!customerName) { return { error: 'customerName is required' }; } // Create customer const customer = record.create({ type: record.Type.CUSTOMER }); customer.setValue('companyname', customerName); customer.setValue('email', email); customer.setValue('subsidiary', subsidiary || 1); const customerId = customer.save(); return { success: true, customerId: customerId }; } catch (e) { log.error('POST Error', e.message); return { error: e.message }; } }; return { get, post }; });

Deployment

RESTLET DEPLOYMENT ═══════════════════════════════════════════════════════════════ 1. CREATE SCRIPT RECORD Customization β†’ Scripting β†’ Scripts β†’ New β”œβ”€β”€ Type: RESTlet β”œβ”€β”€ Script File: restlet_customer_api.js └── Functions: get, post, put, delete 2. CREATE SCRIPT DEPLOYMENT β”œβ”€β”€ Status: Released β”œβ”€β”€ Log Level: Debug (for testing) β”œβ”€β”€ Execute As Role: Integration role β”œβ”€β”€ Audience: Roles that should access └── URL: Generated automatically RESTLET URL FORMAT: ─────────────────────────────────────────────────────────────── https://<ACCOUNT_ID>.restlets.api.netsuite.com/app/site/hosting/restlet.nl ?script=<SCRIPT_ID> &deploy=<DEPLOY_ID> &customerId=123 Or use external URL (if configured)

Authentication

RESTLET AUTHENTICATION ═══════════════════════════════════════════════════════════════ OPTION 1: TOKEN-BASED AUTHENTICATION (TBA) ─────────────────────────────────────────────────────────────── Same OAuth 1.0 header as SuiteTalk REST: Authorization: OAuth realm="ACCOUNT_ID", oauth_consumer_key="...", oauth_token="...", oauth_signature_method="HMAC-SHA256", oauth_timestamp="...", oauth_nonce="...", oauth_version="1.0", oauth_signature="..." OPTION 2: NLAUTH (Not Recommended) ─────────────────────────────────────────────────────────────── Authorization: NLAuth nlauth_account=ACCOUNT_ID, nlauth_email=user@domain.com, nlauth_signature=password, nlauth_role=3 Note: NLAuth uses user credentialsβ€”prefer TBA for security

Advanced Patterns

RESTLET DESIGN PATTERNS ═══════════════════════════════════════════════════════════════ PATTERN 1: COMPOSITE OPERATIONS ─────────────────────────────────────────────────────────────── // Single API call creates order with items and customer const post = (requestBody) => { const { customer, orderLines, shipAddress } = requestBody; // Create or find customer let customerId = findCustomerByEmail(customer.email); if (!customerId) { customerId = createCustomer(customer); } // Create sales order const order = record.create({ type: 'salesorder' }); order.setValue('entity', customerId); // Add lines orderLines.forEach((line, index) => { order.setSublistValue({ sublistId: 'item', fieldId: 'item', line: index, value: line.itemId }); order.setSublistValue({ sublistId: 'item', fieldId: 'quantity', line: index, value: line.quantity }); }); const orderId = order.save(); return { success: true, orderId }; }; PATTERN 2: WEBHOOK RECEIVER ─────────────────────────────────────────────────────────────── // Receive webhooks from external systems const post = (requestBody) => { log.audit('Webhook Received', JSON.stringify(requestBody)); // Validate webhook signature if (!validateSignature(requestBody)) { return { error: 'Invalid signature', status: 401 }; } // Queue for processing (avoid timeout) const queueRecord = record.create({ type: 'customrecord_webhook_queue' }); queueRecord.setValue('custrecord_payload', JSON.stringify(requestBody)); queueRecord.save(); return { success: true, message: 'Queued for processing' }; };
⚠️ RESTlet Governance
  • Governance units: RESTlets have standard SuiteScript limits (10,000 units)
  • Timeout: 5 minutes for synchronous requests
  • Concurrency: Based on account's SuiteCloud license
  • Response size: 10MB maximum

For long-running operations, queue work and use scheduled scripts to process.

🎯 Consultant Insight

RESTlets are your escape hatch when standard APIs don't fit. Common use cases: e-commerce order import with custom logic, inventory availability checks across locations, composite operations that would require multiple API calls. Always add logging and error handlingβ€”debugging RESTlets in production without good logs is painful.

Chapter 10.5

CSV Import

Batch data loading via CSV: templates, field mapping, scheduling, and best practices.

CSV Import Overview

CSV Import is NetSuite's built-in tool for batch data loading. It's often the simplest integration method for periodic data transfers that don't require real-time processing.

Setup β†’ Import/Export β†’ Import CSV Records

Import Types

Import Type Description Common Use
Add Create new records only Initial data load
Update Modify existing records Mass updates
Add/Update Upsert based on key field Ongoing sync

CSV Formatting Rules

CSV FORMATTING REQUIREMENTS ═══════════════════════════════════════════════════════════════ FILE FORMAT ─────────────────────────────────────────────────────────────── β€’ Encoding: UTF-8 (preferred) or Windows-1252 β€’ Delimiter: Comma (,) β€’ Text qualifier: Double quotes (") β€’ Line ending: CRLF or LF β€’ First row: Column headers (required) FIELD FORMATS ─────────────────────────────────────────────────────────────── Dates: MM/DD/YYYY or YYYY-MM-DD Booleans: T/F, True/False, Yes/No, 1/0 Numbers: No thousands separator, period decimal Currency: No currency symbol, no thousands separator Multi-select: Values separated by pipe (|) References: Internal ID or External ID EXAMPLE CSV ─────────────────────────────────────────────────────────────── External ID,Company Name,Email,Subsidiary,Is Inactive CUST-001,Acme Corporation,sales@acme.com,1,F CUST-002,Beta Industries,info@beta.com,1,F CUST-003,"Gamma, LLC",contact@gamma.com,2,F Note: "Gamma, LLC" quoted because contains comma

Field Mapping

FIELD MAPPING STRATEGIES ═══════════════════════════════════════════════════════════════ REFERENCE FIELDS ─────────────────────────────────────────────────────────────── For fields like Customer, Item, Class, etc.: Option 1: Internal ID Column: Customer Value: 12345 Option 2: Name/Display Value Column: Customer Value: Acme Corporation Option 3: External ID (recommended) Column: Customer : External ID Value: CUST-001 SUBLIST IMPORT (Two-File Method) ─────────────────────────────────────────────────────────────── File 1: Header (Sales Order) External ID,Customer,Order Date,Subsidiary SO-001,CUST-001,12/01/2025,1 SO-002,CUST-002,12/02/2025,1 File 2: Lines (Sales Order Items) External ID,Item,Quantity,Rate SO-001,ITEM-001,10,99.99 SO-001,ITEM-002,5,149.99 SO-002,ITEM-001,20,99.99 Import header first, then lines (linked by External ID)

Saved Import Maps

Save field mappings for repeated imports:

Setup β†’ Import/Export β†’ Saved CSV Imports
Setting Description
Import Map Name Descriptive name for this mapping
Record Type Customer, Item, Sales Order, etc.
Field Mappings CSV column β†’ NetSuite field
Import Options Add, Update, or Add/Update
Data Handling On error: skip record or abort

Scheduled Imports

AUTOMATED CSV IMPORT ═══════════════════════════════════════════════════════════════ OPTION 1: SCHEDULED IMPORT (Built-in) ─────────────────────────────────────────────────────────────── 1. Save import map 2. Go to: Setup β†’ Import/Export β†’ Scheduled CSV Imports 3. Configure: - Saved import to use - File source: File Cabinet folder - Schedule: Daily, Weekly, etc. - Email notification on completion OPTION 2: SUITESCRIPT + N/TASK MODULE ─────────────────────────────────────────────────────────────── const task = require('N/task'); const importTask = task.create({ taskType: task.TaskType.CSV_IMPORT, mappingId: 'custimport_customer_sync', importFile: 'SuiteScripts/imports/customers.csv' }); const taskId = importTask.submit(); OPTION 3: EXTERNAL AUTOMATION ─────────────────────────────────────────────────────────────── 1. External system uploads CSV to File Cabinet via REST/SOAP 2. Scheduled script triggers import 3. Results logged/emailed
⚠️ Common Import Errors
  • Invalid reference: Referenced record doesn't existβ€”check ID or name
  • Required field missing: Mandatory field not mapped or empty
  • Duplicate key: External ID already exists (for Add imports)
  • Invalid date format: Use MM/DD/YYYY or configure format
  • Permission denied: Import user lacks record access
πŸ’‘ CSV Import Best Practices
  • Always preview: Review first 10 rows before full import
  • Use external IDs: Enable reliable updates without internal IDs
  • Test in sandbox: Validate import maps before production
  • Limit batch size: 25,000 records max per import recommended
  • Log imports: Keep import files and results for audit
🎯 Consultant Insight

CSV Import is underrated. For daily/weekly batch updates from systems that can export CSV (most can), it's often simpler than building API integrations. Use scheduled imports with File Cabinet as the drop zoneβ€”external systems FTP files there, NetSuite picks them up automatically. Just ensure good monitoring so you catch failures.

Chapter 10.6

NetSuite AI Connector (MCP)

AI integration capabilities using the Model Context Protocol (MCP) standard.

ℹ️ MCP Standard Tools

NetSuite supports the Model Context Protocol (MCP), enabling AI systems to interact with NetSuite data and operations through standardized interfaces.

MCP Overview

The Model Context Protocol (MCP) is an open standard for connecting AI systems to external data sources and tools. NetSuite's AI Connector implements MCP, allowing AI assistants and agents to query data, create records, and execute business processes.

Available MCP Tools

Tool Category Capabilities Example Use
Query Tools Run saved searches, SuiteQL queries "Show me overdue invoices"
Record Tools Create, read, update records "Create a customer for Acme Corp"
Workflow Tools Trigger workflows, check status "Approve pending purchase orders"
Report Tools Generate financial reports "Generate income statement for Q4"
Analytics Tools Access dashboard KPIs "What's our current DSO?"

Prerequisites

  • NetSuite account: Administrator-level access to configure features, integrations, and roles
  • Paid AI accounts: ChatGPT Plus/Enterprise or Claude Pro/Enterprise
  • Integration record: Must be created and configured in NetSuite
  • Enabled features in NetSuite: Server SuiteScript, OAuth 2.0, REST Web Services

NetSuite Configuration

STEP 1: ENABLE FEATURES ═══════════════════════════════════════════════════════════════ Path: Setup β†’ Company β†’ Enable Features β†’ SuiteCloud subtab Enable the following features: βœ“ Server SuiteScript βœ“ OAuth 2.0 βœ“ REST Web Services STEP 2: INSTALL SUITEAPP ═══════════════════════════════════════════════════════════════ Location: SuiteApp section (or Customization β†’ SuiteBundler β†’ Search & Install) Action: Search for "MCP" and install "MCP Standard Tools SuiteApp" STEP 3: CONFIGURE ROLE ═══════════════════════════════════════════════════════════════ Path: Setup β†’ Users/Roles β†’ Manage Roles Approach: Clone an existing role (e.g., AP Clerk) or create a new least-privilege role Required Permissions: β”œβ”€β”€ MCP server connection: Full └── Login using OAuth 2.0 access token: Full ⚠️ IMPORTANT: Administrator role CANNOT be used for AI connections

Integration Record Setup

CREATE INTEGRATION RECORD ═══════════════════════════════════════════════════════════════ Path: Setup β†’ Integrations β†’ Manage Integrations β†’ New Fields to Configure: β”œβ”€β”€ Name: "AI Connector – ChatGPT" (or "AI Connector – Claude") β”œβ”€β”€ State: Enabled β”œβ”€β”€ Authentication: OAuth 2.0 └── Redirect URI: Callback URL from AI client Result: NetSuite generates Client ID and Client Secret (Store these securely - Client Secret shown only once!)

OAuth 2.0 Authorization Flow

Step Action Details
1. Authorization Request AI client redirects user User logs into NetSuite and grants consent
2. Authorization Code NetSuite returns code Code sent to Redirect URI
3. Token Exchange AI client requests tokens Sends code, Client ID, Client Secret to token endpoint
4. Tokens Issued NetSuite returns tokens Access Token (API calls), Refresh Token (renewal)
OAUTH 2.0 ENDPOINTS ═══════════════════════════════════════════════════════════════ Replace <ACCOUNT_ID> with your NetSuite account ID Authorization: https://<ACCOUNT_ID>.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/authorize Token: https://<ACCOUNT_ID>.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token Revoke (to invalidate tokens): https://<ACCOUNT_ID>.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/revoke

Connecting ChatGPT to NetSuite

CHATGPT CONNECTOR SETUP ═══════════════════════════════════════════════════════════════ 1. OPEN SETTINGS Path: Settings β†’ Apps and Connectors 2. ENABLE DEVELOPER MODE Navigate to Advanced Settings and enable Developer Mode if required 3. CREATE CONNECTOR Action: Create Connector Name: "NetSuite Connector" 4. ENTER DETAILS Account ID: Found at Setup β†’ Company β†’ Company Information MCP Server URL: Use format from NetSuite AI Connector docs, inserting your Account ID 5. AUTHENTICATE Method: OAuth 2.0 Role: Select your custom MCP role (NOT Administrator) 6. TEST CONNECTION Example prompt: "Show me the most recently created vendor" Validate results directly in NetSuite

Connecting Claude to NetSuite

CLAUDE CONNECTOR SETUP ═══════════════════════════════════════════════════════════════ 1. OPEN SETTINGS Path: Settings β†’ Connectors 2. CHOOSE CONNECTOR TYPE Option A: Web β†’ NetSuite AI Connector (pre-built) Option B: Custom connector (recommended for more control) 3. ENTER DETAILS MCP Server URL: Same format as ChatGPT, with your Account ID 4. AUTHENTICATE Method: OAuth 2.0 Role: Select your custom MCP role (NOT Administrator) 5. TEST CONNECTION Try: "What customers were created this week?" Verify results match NetSuite data

Use Cases

πŸ’» Software/SaaS
AI-Powered Business Operations
  • Customer Service: "Look up order SO-12345 status"
  • Sales Support: "What's the pricing history for this customer?"
  • Finance: "Generate AR aging report and email CFO"
  • Operations: "What items are below reorder point?"
  • Executive: "Compare this month's revenue to last year"

Testing & Troubleshooting

Issue Cause Solution
Role not visible during auth Missing permissions or assignment Verify MCP permission, role assignment, then re-login
Permission errors on create/update Role has view-only access Grant Create/Edit permissions for target record types
Missing data in results Subsidiary restrictions Verify role has access to all required subsidiaries
Token expired errors Access token lifecycle Implement refresh token logic; re-authenticate if needed
Administrator role rejected Security restriction Create dedicated least-privilege role for AI connections
πŸ’‘ Data Privacy Controls

Review AI application settings to opt out of training data usage if required by your organization's data policies. Both ChatGPT and Claude offer enterprise plans with data privacy guarantees.

⚠️ AI Integration Security Best Practices
  • Least-privilege roles: Create dedicated roles with minimum necessary permissions
  • Role-based access: AI executes with assigned role permissions only
  • Subsidiary scope: Restrict data visibility to assigned subsidiaries
  • Audit logging: All AI operations logged for compliance review
  • Operation approval: Configure which operations need human approval
  • Rate limiting: Prevent excessive AI-initiated operations
  • Data filtering: Restrict sensitive fields from AI access
  • Token security: Store Client Secret securely; implement token refresh
🎯 Consultant Insight

The MCP integration is transformative for organizations using AI assistants. Start with read-only access (queries and reports) to build trust, then gradually enable write operations with appropriate approval workflows. The biggest value is in repetitive lookup tasksβ€”"What's the status of X?" questions that currently require manual NetSuite navigation. Note that open-source tools like OpenSuiteMCP should be thoroughly vetted before production use.

Chapter 10.7

Common Integrations

Integration patterns for Salesforce, Shopify, Amazon, banking, and payment processors.

E-Commerce Integrations

Shopify Integration

Data Flow Direction Field Mapping
Products NetSuite β†’ Shopify Item ID β†’ SKU, Display Name β†’ Title, Base Price β†’ Price
Inventory NetSuite β†’ Shopify Quantity Available β†’ Inventory Level (real-time or every 15 min)
Orders Shopify β†’ NetSuite Order # β†’ External ID, Customer Email β†’ Customer
Fulfillment NetSuite β†’ Shopify Tracking Number, Carrier, Ship Date

Amazon Integration

Data Type Direction Frequency
Product Listings NetSuite β†’ Amazon On change
Inventory NetSuite β†’ Amazon Every 15 min
Pricing NetSuite β†’ Amazon On change
Orders Amazon β†’ NetSuite Every 5 min
Fulfillment NetSuite β†’ Amazon On ship
Returns Amazon β†’ NetSuite Daily

CRM Integrations

Salesforce Integration

Data Flow Direction Details
Accounts/Customers Bidirectional SF Account ↔ NS Customer (Master/Slave or bidirectional)
Opportunities β†’ Orders Salesforce β†’ NetSuite Closed Won opportunities create Sales Orders
Invoices/Payments NetSuite β†’ Salesforce Financial data for sales visibility

Banking Integrations

Integration Type Direction Format/Details
Bank Feeds Bank β†’ NetSuite OFX/QFX/CSV/BAI2, Daily import
Positive Pay NetSuite β†’ Bank Check #, Amount, Payee, Date
ACH/EFT Payments NetSuite β†’ Bank NACHA File for vendor payments
Lockbox Bank β†’ NetSuite Payment file for invoice matching

Payment Processor Integrations

Processor Integration Method Features
Stripe SuiteApp or RESTlet Cards, ACH, subscriptions
PayPal Native integration PayPal payments, e-commerce
Authorize.net SuitePayments Credit card processing
Square iPaaS or custom POS, online payments
Bill.com SuiteApp AP automation, vendor payments

Industry-Specific Integrations

🏭 Manufacturing
Manufacturing
  • EDI: SPS Commerce, TrueCommerce for customer/vendor EDI
  • PLM: Product Lifecycle Management systems
  • MES: Manufacturing Execution Systems for shop floor
  • Quality: QMS systems for quality tracking
πŸ›’ Retail
Retail
  • POS: Square, Lightspeed, Shopify POS
  • Marketplaces: Amazon, eBay, Walmart, Etsy
  • Shipping: ShipStation, ShipBob, EasyPost
  • Returns: Loop, Returnly, Happy Returns
πŸ’» Software/SaaS
Software/SaaS
  • Billing: Stripe Billing, Chargebee, Zuora
  • CRM: Salesforce, HubSpot
  • Support: Zendesk, Intercom, Freshdesk
  • Usage: Product analytics for usage-based billing
🎯 Consultant Insight

Before building custom integrations, check the SuiteApp marketplace. Common integrations like Shopify, Salesforce, and major shipping carriers have established connectors that are faster to implement than custom builds. Custom development makes sense when you have unique requirements or need tight control over the integration logic.

Chapter 10.8

E-Invoicing

Electronic invoicing standards, compliance requirements, and NetSuite configuration.

ℹ️ North America E-Invoicing

NetSuite supports e-invoicing for North American markets, in addition to European and Latin American coverage.

E-Invoicing Overview

E-invoicing (electronic invoicing) is the exchange of invoice documents between trading partners in structured electronic format. Many countries now mandate e-invoicing for B2B and B2G transactions.

Global E-Invoicing Standards

Region Standard Status
European Union Peppol, FatturaPA (Italy) Mandatory (varies by country)
Mexico CFDI 4.0 Mandatory
Brazil NF-e, NFS-e Mandatory
India GST E-Invoice Mandatory above threshold
Saudi Arabia ZATCA E-Invoicing Mandatory
North America Various (emerging) Voluntary/Growing

NetSuite Configuration

Enable E-Invoicing

Setup β†’ Company β†’ Enable Features β†’ Transactions
  • Enable Electronic Invoicing
  • Configure country-specific settings

E-Invoice Provider Setup

E-INVOICE PROVIDER CONFIGURATION ═══════════════════════════════════════════════════════════════ Setup β†’ Company β†’ Electronic Invoicing β†’ Provider Setup PROVIDER OPTIONS: ─────────────────────────────────────────────────────────────── β€’ NetSuite E-Invoicing (native) β€’ Avalara (for supported countries) β€’ Third-party providers (via integration) CONFIGURATION: ─────────────────────────────────────────────────────────────── 1. Select provider 2. Enter API credentials 3. Map NetSuite fields to e-invoice format 4. Configure document types (invoice, credit memo, etc.) 5. Set up customer/vendor identifiers (VAT, tax ID) 6. Test with sample transactions

Country-Specific Requirements

πŸ’» Software/SaaS
European Union (Peppol)
PEPPOL REQUIREMENTS ─────────────────────────────────────────────────────────────── Required Fields: β€’ Seller: Name, Address, VAT ID, Peppol ID β€’ Buyer: Name, Address, VAT ID, Peppol ID β€’ Invoice: Number, Date, Due Date, Currency β€’ Lines: Description, Quantity, Unit, Price, VAT β€’ Totals: Net, VAT, Gross Peppol ID Format: Country Code : Identifier Example: DE:991234567890
πŸ“¦ Wholesale/Distribution
Mexico (CFDI 4.0)
CFDI 4.0 REQUIREMENTS ─────────────────────────────────────────────────────────────── β€’ RFC (tax ID) for buyer and seller β€’ Uso de CFDI (invoice purpose code) β€’ Forma de Pago (payment method) β€’ MΓ©todo de Pago (payment timing) β€’ Producto/Servicio codes (SAT catalog) β€’ Unidad de Medida codes β€’ Digital stamp from PAC (authorized provider) β€’ Timbrado within 72 hours of transaction

Implementation Checklist

🎯 Consultant Insight

E-invoicing compliance is increasingly mandatory globally. Start by understanding which countries require it and by when. For multi-country operations, consider a provider that covers all your jurisdictions to avoid managing multiple integrations. The data quality requirements are strictβ€”clean up customer tax IDs and addresses before going live, as e-invoice rejections create operational headaches.