Systems
NetSuite integration with your store, warehouse and suppliers
NetSuite gives an integration four ways in and a fixed number of concurrent requests: 5 on the Standard tier, 15 on Premium, 20 above that. We build the integration around those numbers and your account's custom fields, then host and run it.
What NetSuite is and who runs it
NetSuite is Oracle's cloud ERP: general ledger, inventory, order management, purchasing and CRM in one multi-tenant system. Every account runs the same version. Oracle ships two releases a year, numbered 2026.1 and 2026.2, and no account chooses its own upgrade date. An integration therefore follows Oracle's calendar: when a release changes an interface, it changes for everyone in the same weeks.
Its home market is the United States, among wholesale distributors, manufacturers, retailers and software companies that have outgrown a bookkeeping package. Outside the US it mostly arrives through OneWorld, the edition for companies with several legal entities. A US parent with a Dutch and a German subsidiary runs one account, and every customer, item and transaction belongs to a subsidiary with its own currency and tax setup. Each account has its own API host, in the form 1234567.suitetalk.api.netsuite.com, and its sandbox has another: 1234567-sb1.
What connects to NetSuite
NetSuite is the system of record for items, stock, prices and the financial side of an order. The store is where the order starts. The table gives the flows we build as part of an e-commerce ERP integration, with the NetSuite record each one lands in.
| Flow | Direction | NetSuite record |
|---|---|---|
| Orders | store to NetSuite | Sales Order, Cash Sale or Invoice |
| Customers and contacts | both ways | Customer, Contact, subcustomer |
| Payments | store to NetSuite | Customer Deposit |
| Fulfillment and tracking | NetSuite or WMS to store | Item Fulfillment |
| Stock per location | NetSuite to store | item quantity available per Location |
| Items and prices | NetSuite to store | Inventory Item, matrix items, price levels |
| Returns and refunds | both ways | Return Authorization, Credit Memo, Cash Refund |
| Supplier stock and delivery dates | supplier to NetSuite and store | custom item fields |
The choice between Sales Order and Cash Sale changes the rest of the flow. A Cash Sale posts the sale and the payment in one transaction and takes the stock down at once, without an Item Fulfillment. A Sales Order waits for fulfillment and billing, which is what a warehouse and a B2B customer on payment terms need.
How NetSuite exposes data
Four interfaces
| Interface | Used for | Limit |
|---|---|---|
| SuiteTalk REST web services | reading and writing records; upsert by external ID | 1,000 results per page |
| SuiteQL over REST | bulk reads with SQL | 1,000 rows per page, 100,000 rows per query |
| RESTlets (SuiteScript) | shaped writes: one call that creates an order with its lookups | 5,000 usage units per call, 10 MB payload |
| SuiteTalk SOAP web services | integrations built before REST | all endpoints disabled with release 2028.2 |
A stock read is a SuiteQL query, paged by 1,000 rows:
POST /services/rest/query/v1/suiteql?limit=1000&offset=0
Host: 1234567.suitetalk.api.netsuite.com
Prefer: transient
{ "q": "SELECT id, itemid FROM item WHERE isinactive = 'F'" }
An order write is a PUT to /services/rest/record/v1/salesOrder/eid:SHOP-100482. The eid: prefix makes it an upsert on the external ID: the record is created when it does not exist and updated when it does. A retry of the same order can therefore never produce a second sales order. That is the core of how we prevent duplicate customers and orders.
Oracle's SOAP schedule is fixed. The 2025.2 endpoint is the last one planned. With 2027.1 no new SOAP integration can be built, and with 2028.2 every SOAP endpoint is switched off. An integration that still calls SOAP has a migration ahead of it, and replacing an integration while orders keep flowing is a separate job.
Authentication
NetSuite has two schemes. Token-based authentication signs every request with a consumer key and a token that belong to one user and one role. OAuth 2.0 is the scheme Oracle now points new integrations to. Its access token is valid for 60 minutes. In the authorization code flow the refresh token is valid for seven days, after which a person has to give consent again. An unattended integration therefore uses the client credentials flow: a certificate signs the token request, the certificate is valid for at most two years, and an integration record holds at most five active certificates.
Either way the integration runs under its own role with only the permissions its flows need, never under Administrator.
Governance units
Every SuiteScript call costs usage units, and every script type has a budget.
| Operation | Transaction record | Other standard record | Custom record |
|---|---|---|---|
record.load, record.create |
10 | 5 | 2 |
Record.save |
20 | 10 | 4 |
ResultSet.each (search) |
10 | 10 | 10 |
query.runSuiteQL |
10 | 10 | 10 |
A RESTlet gets 5,000 units per call, a scheduled script 10,000, a user event script 1,000. A map/reduce script is metered per stage: 10,000 units for getInputData, 1,000 per map call, 5,000 per reduce call.
Worked through for an order RESTlet: two searches to resolve the customer and the items cost 20 units. Creating and saving the sales order costs 10 plus 20. Creating and saving the customer deposit costs another 30. That is 80 units per order, so one RESTlet call carries 5,000 divided by 80, which is 62 orders. A batch of 50 orders uses 4,000 units and leaves 1,000 as margin for orders that need an extra lookup or a new customer record.
Concurrency
The limit that decides throughput is the account concurrency limit: the number of requests NetSuite processes at the same moment.
The limit covers REST, SOAP and RESTlet requests together, from every integration on the account. A Standard account with a 3PL connection, an EDI provider and a reporting export has three other parties using the same 5 slots. A request over the limit is rejected:
{
"title": "Bad Request",
"status": 429,
"o:errorDetails": [
{
"detail": "Concurrent request limit exceeded. Request blocked.",
"o:errorCode": "CONCURRENCY_LIMIT_EXCEEDED"
}
]
}
The arithmetic for a Standard account: with 2 of the 5 slots given to the store integration and an order write that takes 2 seconds, the maximum is 60 orders a minute. A nightly read of 40,000 items at 1,000 rows per page is 40 requests in one slot. We set the number of workers below the slots available, put everything else in a queue, and answer a 429 with a retry after a growing pause. The note on NetSuite concurrency limits has the full calculation, and API throttling and backoff covers the retry pattern.
Where a NetSuite integration gets stuck
Custom fields named years ago. Custom fields carry the prefixes custbody (transaction header), custcol (transaction line), custitem (item) and custentity (customer). Their IDs were typed by whoever configured the account: custbody_web_order_no next to custitem14. Mapping starts with an inventory of which of these fields are mandatory, which a script fills, and which nobody uses anymore.
Matrix items. A matrix consists of a parent item and subitems, one per combination of options such as size and color, with a maximum of 2,000 combinations. The parent never appears on a transaction, only the children do. A store models the same product as one product with variants, so variant mapping needs a table from each child item to each variant.
Subsidiary, location, department and class. In a OneWorld account an order for subsidiary 3 can only carry items and customers that are available to subsidiary 3. When that does not hold, the response is one line:
INVALID_KEY_OR_REF: Invalid item reference key 4417 for subsidiary 3.
The integration checks these references before it writes, and reports the order with the item name instead of the internal ID.
Sandbox refreshes. A refresh overwrites the sandbox with production data. Token key and token secret are deleted and have to be regenerated. Internal IDs of anything created only in the sandbox are gone, which is why we map on script IDs and external IDs.
The customer hierarchy. A hierarchy of a parent customer with its subcustomers holds at most 10,000 customers. B2B setups that store every ship-to location as a subcustomer, or that place all web customers under one parent, reach that number. NetSuite then refuses a new subcustomer under that parent, and the order that needed it fails.
Pricing as a feature switch. The pricing sublist on an item depends on which features are enabled: Multiple Prices for price levels, Quantity Pricing for price breaks, Multiple Currencies for a price per currency. The REST item record leaves out the quantity pricing discount and level fields. Customer-specific pricing with price breaks therefore comes out through SuiteQL or a RESTlet.
What NetSuite leaves to others
EDI. NetSuite has no X12 or EDIFACT translator. Oracle's documentation for NetSuite WMS describes the route for an advance shipping notice: the rule "Generate EDI 856 outbound ASNs?" makes NetSuite write the shipping data to custom records, and a NetSuite EDI partner reads those records and produces the 856. The same split applies to the 850 purchase order coming in and the 810 invoice going out. See NetSuite EDI integration.
E-invoicing formats. The Electronic Invoicing SuiteApp generates outbound documents in XML or JSON from templates you write, and reads inbound XML. Which standard that XML follows, and how it reaches the receiver's network, is left to the template and a sending method.
Supplier availability. NetSuite knows what is in its own locations. A supplier's stock file and the expected delivery date per item do not arrive by themselves. We read them from the supplier's CSV, XML or API and write them to item fields and to the store, which is the subject of supplier feeds.
Platforms we integrate with NetSuite
Each platform stores products, stock and customers in its own way, so each pair has its own mapping and its own limits.
- Shopify NetSuite integration: variants against matrix items, Shopify's GraphQL cost budget against NetSuite's concurrency limit, B2B companies against subcustomers.
- Magento NetSuite integration: configurable and simple products, inventory sources against NetSuite locations, customer groups against price levels.
- WooCommerce NetSuite integration: variable products, one stock quantity per product against stock per location, webhooks that are switched off after repeated failures.
- BigCommerce NetSuite integration: B2B Edition companies against the customer hierarchy, price lists against price levels, tax calculated on both sides.
We build the integration to your account: your custom fields, your subsidiaries, your concurrency limit. Then we host it, monitor it and fix it when Oracle or the store platform changes something. Before go-live it runs as a dry run that writes nothing, so you see every order and stock change it would make. All integrations come with a dashboard, logs and a per-run diff. Tell us what runs on your NetSuite account.
Frequently asked questions
Does NetSuite have an API for a web store integration?
It has four interfaces: SuiteTalk REST web services for records, SuiteQL for bulk reads, RESTlets for custom endpoints written in SuiteScript, and SuiteTalk SOAP. SOAP is being retired: the 2025.2 endpoint is the last one planned and Oracle disables all SOAP endpoints with the 2028.2 release. New integrations go on REST with OAuth 2.0.
How many requests can NetSuite handle at the same time?
The account limit is 5 concurrent requests on the Standard tier, 15 on Premium and 20 on Enterprise and Ultimate. Each SuiteCloud Plus license adds 10. The limit is shared by REST, SOAP and RESTlet calls from every integration on the account. The number for your account is at Setup, Integration, Integration Governance.
What happens when the concurrency limit is reached?
NetSuite rejects the request. REST web services return HTTP 429 with CONCURRENCY_LIMIT_EXCEEDED, a RESTlet returns HTTP 400 with SSS_REQUEST_LIMIT_EXCEEDED. Oracle expects the client to retry. Our integrations keep the request in a queue, retry with a growing pause, and run with fewer workers than the account has slots, so the limit is rarely reached at all.
Can the integration be tested in our NetSuite sandbox?
Yes. A sandbox has the same concurrency limit as production. After every sandbox refresh the token key and token secret are deleted and have to be created again. We map on script IDs and external IDs instead of internal IDs, so a refresh costs one new token and no remapping.
Does NetSuite handle EDI itself?
No. Oracle's documentation for NetSuite WMS describes writing the shipping data to custom records, which a NetSuite EDI partner then converts into the advance shipping notice. X12 and EDIFACT translation happens outside NetSuite. See NetSuite EDI integration for how that layer is built.
Should we still use token-based authentication?
Existing integrations on token-based authentication keep working. For new work Oracle points to OAuth 2.0: from release 2026.1 new integrations should use REST with OAuth 2.0, and with 2027.1 no new integration can be created on token-based authentication. For a server-to-server integration that means the client credentials flow with a certificate.
Tell us what you need
Tell us which systems you use and what needs to work better. We reply personally within one working day. We help you define the work, then agree the price and timing before you commit.
- You know the price and the timeline before you commit to anything
- We work out the connection that takes the work off your hands
- We handle the build, hosting, monitoring and maintenance
- Your team has less information to retype and fewer discrepancies to chase