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 |
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
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 - 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
- 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
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.
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."
}
]
} - 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
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.
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' };
}; - 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.
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.
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.
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:
| 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 - 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
- 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
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.
NetSuite AI Connector (MCP)
AI integration capabilities using the Model Context Protocol (MCP) standard.
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
- 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 |
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.
- 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
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.
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
- 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
- POS: Square, Lightspeed, Shopify POS
- Marketplaces: Amazon, eBay, Walmart, Etsy
- Shipping: ShipStation, ShipBob, EasyPost
- Returns: Loop, Returnly, Happy Returns
- Billing: Stripe Billing, Chargebee, Zuora
- CRM: Salesforce, HubSpot
- Support: Zendesk, Intercom, Freshdesk
- Usage: Product analytics for usage-based billing
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.
E-Invoicing
Electronic invoicing standards, compliance requirements, and NetSuite configuration.
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
- 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
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 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
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.
