Skip to main content

Customer Record API

Create, read, update, and delete customer records using the NetSuite REST API.


Endpoints

MethodEndpointDescription
GET/record/v1/customerList all customers
GET/record/v1/customer/{id}Get specific customer
POST/record/v1/customerCreate new customer
PATCH/record/v1/customer/{id}Update existing customer
DELETE/record/v1/customer/{id}Delete customer

Base URL

https://{account_id}.suitetalk.api.netsuite.com/services/rest/record/v1/customer

Key Fields

Identification & Basic Info

FieldTypeDescriptionRequired
idstringInternal ID (read-only)-
entityIdstringCustomer ID/NameYes (if not auto)
autoNamebooleanAuto-generate nameNo
companyNamestringCompany nameYes (if company)
isPersonbooleanIndividual vs companyNo
firstNamestringFirst name (if person)Conditional
lastNamestringLast name (if person)Conditional
subsidiaryobjectPrimary subsidiaryYes (if OneWorld)

Contact Information

FieldTypeDescription
emailstringPrimary email address
altEmailstringAlternate email
phonestringPrimary phone
altPhonestringAlternate phone
faxstringFax number
urlstringWebsite URL

Financial Fields

FieldTypeDescription
balancenumberCurrent A/R balance (read-only)
creditLimitnumberMaximum credit allowed
termsobjectPayment terms
currencyobjectCustomer currency
taxablebooleanSubject to tax
taxItemobjectDefault tax code

Classification & Segmentation

FieldTypeDescription
categoryobjectCustomer category
salesRepobjectAssigned sales representative
partnerobjectReferral partner
departmentobjectDepartment
classobjectClassification
locationobjectLocation

Accounting Settings

FieldTypeDescription
receivablesAccountobjectA/R account
billingScheduleobjectRecurring billing schedule
priceLevelobjectDefault price level
discountItemobjectAutomatic discount

Status & Dates

FieldTypeDescription
entityStatusobjectCustomer status
inactivebooleanInactive flag
dateCreatedstringCreation date (read-only)
lastModifiedDatestringLast modified date (read-only)

Aging (Read-Only)

FieldTypeDescription
agingnumberCurrent balance
aging1number1-30 days overdue
aging2number31-60 days overdue
aging3number61-90 days overdue
aging4numberOver 90 days overdue

Sublists/Collections

FieldTypeDescription
addressBookcollectionCustomer addresses
contactRolescollectionAssociated contacts
creditCardscollectionSaved credit cards
currencyListcollectionAccepted currencies
itemPricingcollectionCustom item pricing

Example: Create Company Customer

POST /record/v1/customer
Content-Type: application/json
Authorization: Bearer {access_token}
{
"companyName": "Acme Corporation",
"entityId": "ACME-001",
"isPerson": false,
"subsidiary": {
"id": "1"
},
"email": "contact@acmecorp.com",
"phone": "555-0100",
"terms": {
"id": "2"
},
"currency": {
"id": "1"
},
"salesRep": {
"id": "123"
},
"category": {
"id": "1"
},
"taxable": true
}

Response

{
"links": [
{
"rel": "self",
"href": "https://1234567.suitetalk.api.netsuite.com/services/rest/record/v1/customer/456"
}
],
"id": "456",
"refName": "Acme Corporation",
"entityId": "ACME-001",
"companyName": "Acme Corporation",
"isPerson": false,
"email": "contact@acmecorp.com",
"phone": "555-0100",
"balance": 0,
"dateCreated": "2025-12-25T10:00:00Z",
"lastModifiedDate": "2025-12-25T10:00:00Z"
}

Example: Create Individual Customer

POST /record/v1/customer
Content-Type: application/json
{
"isPerson": true,
"entityId": "CUST-002",
"firstName": "John",
"lastName": "Smith",
"subsidiary": {
"id": "1"
},
"email": "john.smith@email.com",
"phone": "555-0200",
"terms": {
"refName": "Net 30"
},
"currency": {
"refName": "USA"
}
}

Example: Update Customer

PATCH /record/v1/customer/456
Content-Type: application/json
{
"email": "newemail@acmecorp.com",
"phone": "555-0999",
"creditLimit": 50000,
"terms": {
"id": "3"
}
}
Partial Updates

With PATCH, only include fields you want to change. All other fields remain unchanged.


Example: Add Address (Sublist)

PATCH /record/v1/customer/456
Content-Type: application/json
{
"addressBook": {
"items": [
{
"defaultShipping": true,
"defaultBilling": false,
"label": "Main Office",
"addressBookAddress": {
"addr1": "123 Main Street",
"city": "San Francisco",
"state": "CA",
"zip": "94102",
"country": {
"refName": "US"
}
}
}
]
}
}

Query Filters

Find Customers by Company Name

GET /record/v1/customer?q=companyName LIKE 'Acme%'

Find Customers by Email

GET /record/v1/customer?q=email='john.smith@email.com'

Find Inactive Customers

GET /record/v1/customer?q=inactive=true

Find Customers by Status

GET /record/v1/customer?q=entityStatus='13'

Find Customers with High Balance

GET /record/v1/customer?q=balance > 10000

Common Use Cases

1. Check Customer Credit Limit

const customer = await getCustomer(customerId);
if (customer.balance + orderTotal > customer.creditLimit) {
// Require approval or payment
}

2. Update Customer After Payment

// NetSuite automatically updates balance
// Just retrieve to see current balance
const updated = await getCustomer(customerId);
console.log(`New balance: ${updated.balance}`);

3. Activate/Deactivate Customer

await patchCustomer(customerId, {
inactive: true
});

4. Change Payment Terms

await patchCustomer(customerId, {
terms: { id: "1" } // Net 15
});

Important Notes

Required Fields

  • OneWorld Accounts: subsidiary is required
  • Company: companyName required if isPerson=false
  • Individual: firstName and lastName required if isPerson=true
  • Entity ID: Required unless autoName=true

Read-Only Fields

These fields are calculated by NetSuite and cannot be set via API:

  • balance - Current A/R balance
  • aging, aging1, aging2, aging3, aging4 - Aging buckets
  • dateCreated, lastModifiedDate - System timestamps
  • id - Internal ID

Reference Fields

Most reference fields accept either internal ID or display name:

{
"terms": { "id": "2" }
}
// OR
{
"terms": { "refName": "Net 30" }
}

Subsidiary Restrictions

In OneWorld accounts, you can only access customers in subsidiaries you have permission for.


Error Handling

Duplicate Customer

{
"type": "https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
"title": "Conflict",
"status": 409,
"o:errorDetails": [
{
"detail": "A customer with this name already exists",
"o:errorCode": "UNIQUE_CUST_ID_REQD"
}
]
}

Solution: Use a different entityId or enable autoName.

Missing Required Field

{
"status": 400,
"o:errorDetails": [
{
"detail": "Please enter value(s) for: Company Name",
"o:errorCode": "FIELD_REQUIRED"
}
]
}

Solution: Ensure companyName is provided for company customers.


See Also