A Practical NetSuite Migration Guide: Moving Off SOAP Before 2028
Oracle is deprecating NetSuite SOAP APIs by 2028. Learn to architect a modern migration with SuiteQL, REST, and RESTlets - plus how Truto and Prismatic compare for the job.
Oracle NetSuite is aggressively phasing out its legacy SOAP web services. If your B2B SaaS platform relies on SuiteTalk SOAP endpoints to sync accounting, inventory, or HRIS data—or if you are connecting AI agents to ERP data—you are currently operating on borrowed time.
Oracle has set a hard deadline: by the 2028.2 NetSuite release, all SOAP endpoints will be permanently disabled, and SOAP-based integrations will stop working. If you maintain a NetSuite integration at a B2B SaaS company, this is not a "nice to have" migration. It is a mandated one with a fixed countdown. Engineering teams must immediately plan to create a practical NetSuite migration guide without SOAP to avoid breaking critical customer workflows.
Migrating off NetSuite SOAP is rarely a simple endpoint swap. Modern REST APIs offer predictable semantics, standard JSON payloads, and logical routing. NetSuite's API ecosystem offers none of these out of the box. Attempting to map legacy SOAP XML requests directly to NetSuite's SuiteTalk REST API will immediately expose your infrastructure to severe performance bottlenecks, missing metadata, and aggressive concurrency throttling.
This guide provides the architectural playbook you need to survive this transition. We will examine the exact deprecation timeline, why a naive move to REST is an engineering trap, and how to architect a modern, reliable NetSuite integration using a hybrid approach of SuiteQL, REST, and SuiteScript.
The NetSuite SOAP API Deprecation Timeline (2025–2028)
Oracle has been methodical about this retirement. The deprecation is a phased rollout, not a sudden cliff. Oracle's messaging to developers is unambiguous: any new capability introduced in NetSuite will only be available through modern REST surfaces. The legacy XML endpoints are entering a strict maintenance phase.
Here is the strict schedule you must architect around:
| Release | What Happens |
|---|---|
| 2025.2 | Last planned SOAP endpoint ships. No subsequent SOAP endpoints will be released unless required for critical business continuity. |
| 2026.1 | No new features will be exposed via SOAP. Any new capabilities introduced in NetSuite will only be available through REST. |
| 2027.2 | SOAP usage is restricted exclusively to the single 2025.2 endpoint. All older endpoints are permanently retired. |
| 2028.2 | Complete removal. All SOAP endpoints are disabled. All SOAP integrations break. |
Oracle's own documentation is blunt about the reasoning: SOAP does not support the latest business features, new records have not been made available to SOAP for years, and the underlying XML technology stack does not support modern architecture standards like SuiteAnalytics Workbooks and SuiteScript 2.x Analytics APIs.
For engineering teams, this timeline creates an immediate architectural mandate. You cannot wait until 2027 to begin this migration. Enterprise ERP integrations are notoriously difficult to refactor. Gartner research indicates that 75% of ERP implementation projects run into serious setbacks, often due to integration architecture and data mapping failures. Rebuilding a NetSuite integration requires auditing hundreds of custom fields, validating multi-currency routing logic, and rewriting complex data transformations.
If you are still on SOAP right now, you are already accumulating technical debt with every NetSuite release. You must transition your infrastructure to communicate directly with NetSuite's modern API surfaces before the hard cutoff.
Why "Just Use the REST API" is a Migration Trap
When developers realize SOAP is dying, their first instinct is to rewrite every request to target the suitetalk.api.netsuite.com/services/rest/record/v1/ endpoints. The most common mistake teams make is treating this as a find-and-replace from SOAP to REST.
This approach will fail in production. The SuiteTalk REST API is fundamentally designed for single-record CRUD operations. It is actively hostile to bulk data extraction and complex relational queries. Attempting a 1-to-1 migration will expose you to three severe limitations:
1. The N+1 Sub-Resource Problem
The most severe limitation is how the REST Record Service handles sub-resources. When retrieving a list of records, the REST API does not allow developers to use the expandSubResources parameter.
If you query a list of 200 Purchase Orders and need the line-item details for each, the REST API forces you to make 200 additional, separate API calls. SOAP's legacy getList operation returned everything in one shot. REST forces you into a massive N+1 query bottleneck.
2. No Ordering and Hard Pagination Ceilings
The REST Record API lacks basic querying flexibility. You cannot specify the order in which records are returned—there is no equivalent of an ORDER BY clause. Furthermore, you can get a maximum of 1,000 records per page, and you can only retrieve the first 1,000 pages of results. For enterprise NetSuite accounts that have a massive volume of historical transaction records, this hard ceiling makes complete data synchronization impossible.
3. Single-Record Writes (Until Recently)
Historically, NetSuite's REST Record API processed exactly one record per request for creates or updates, whereas SOAP handled batch operations of up to 1,000 records. The 2026.1 release finally introduces homogeneous batch operations for REST, allowing developers to submit multiple same-type operations in a single asynchronous REST call. However, if your customers are on older releases or rely on heterogeneous batches, you are stuck with one-at-a-time writes.
The bottom line: a 1-to-1 SOAP-to-REST migration will dramatically increase your API call volume. Given NetSuite's strict concurrency limits, this spike in network requests will instantly trigger a cascade of HTTP 429 errors and block all other integration traffic for that customer. To safely architect a reliable NetSuite API integration, you must abandon the idea of a pure REST implementation.
The Tri-Partite Architecture: SuiteQL, REST, and RESTlets
The real replacement for SOAP isn't just REST. It is a combination of three distinct API surfaces, each handling what it does best. To bypass the limitations of the REST API, your integration layer must intelligently route requests based on the operation type.
flowchart TD
A[Unified API Request] --> B{Operation Type}
B -->|Complex Reads / Lists / JOINs| C[SuiteQL Endpoint]
B -->|Single Record Write / Update| D[SuiteTalk REST API]
B -->|PDFs / Dynamic Metadata / Gaps| E[SuiteScript RESTlet]
C --> F[(NetSuite Database)]
D --> F
E --> F1. SuiteQL: Your Primary Read Layer
SuiteQL is NetSuite's proprietary, SQL-like query language. It is exposed via a POST request to /services/rest/query/v1/suiteql. It is the single biggest upgrade over SOAP for data reads, and nearly all list and get operations in your migration should target this endpoint.
Unlike the REST Record API, SuiteQL allows you to execute complex JOINs across related tables in a single network request. A query for vendors can easily JOIN entity addresses, subsidiary relationships, and currency tables without triggering N+1 bottlenecks. It supports advanced WHERE clauses, aggregation (SUM, COUNT, GROUP BY), case-insensitive LIKE searches, standard offset pagination, and computed columns via BUILTIN.DF() for display values.
Here is what a typical SuiteQL vendor list query looks like:
SELECT
v.id,
v.companyname,
v.email,
ea.addr1,
ea.city,
ea.state,
ea.zip,
BUILTIN.DF(v.subsidiary) AS subsidiary_name
FROM vendor v
LEFT JOIN entityaddress ea ON v.defaultbillingaddress = ea.nkey
WHERE v.isinactive = 'F'
AND v.lastmodifieddate >= '2026-01-01'
ORDER BY v.companyname
FETCH FIRST 100 ROWS ONLYOne API call. Vendors, addresses, subsidiary names. No N+1. The trade-off is that SuiteQL is strictly read-only. It is your data extraction engine, not your mutation engine.
2. SuiteTalk REST: Your Write Layer
Reserve the SuiteTalk REST API exclusively for writes. When your application needs to create a customer, update an invoice, or delete a tracking category, format a standard JSON payload and issue a POST, PATCH, or DELETE request to the specific record endpoint.
Because these are targeted, single-record operations, they are less likely to exhaust concurrent thread limits. For single-record reads where you need expanded sub-resources (like line items on a specific purchase order), the REST API with ?expandSubResources=true works well. Just do not use it for bulk listing.
3. RESTlets (SuiteScript): Filling the Gaps REST Can't
Certain critical capabilities are entirely absent from both SuiteQL and the REST API. Oracle's own documentation acknowledges that developers should not expect 100% parity of REST with SOAP, explicitly stating that when an object or method is not available in REST, developers should use SuiteScript RESTlets instead.
For these edge cases, you must deploy a custom SuiteScript Suitelet into the customer's NetSuite account:
- PDF Generation: The REST API has no PDF rendering capability. If your integration needs to download a Purchase Order PDF, your Suitelet must utilize the server-side
N/rendermodule to generate the binary viarender.transaction(). - Dynamic Form Metadata: NetSuite forms are highly dynamic. Custom fields vary per account, and select options change based on the current record state. The standard REST metadata catalog provides basic schema info, but it cannot tell you which fields are mandatory on a specific custom form at runtime. A deployed Suitelet can create an in-memory record using
record.create()and introspect its properties to return accurate field IDs and mandatory flags. - Legacy Tax Data: Currently, the SuiteQL
salestaxitemtable does not expose the full tax rate configuration, including nested tax type references. If your application requires deep tax compliance data, a RESTlet acts as your escape hatch.
Handling NetSuite Authentication and Concurrency Limits
The OAuth 1.0 TBA Math Problem
NetSuite uses OAuth 1.0 Token-Based Authentication (TBA) for server-to-server integrations. This is not modern OAuth 2.0. Every single API request requires an Authorization header containing an OAuth 1.0 signature that must be computed dynamically.
The signature requires combining five credentials (the Consumer Key and Consumer Secret from the integration record, plus the Token ID and Token Secret from the TBA access token, and the Account ID), a randomly generated nonce, a Unix timestamp, the full canonical request URL, and the HTTP method.
These elements must be sorted and encoded according to strict OAuth 1.0 parameter rules to form a base string. You then compute the signature using HMAC-SHA256(consumer_secret&token_secret, base_string). A single misplaced character or incorrect URL encoding will result in an opaque authentication failure.
Building this logic from scratch is a massive engineering tax. This is why shipping API connectors as data-only operations using declarative configuration—where the auth scheme, credential paths, and signature algorithm are defined as data rather than hardcoded logic—is vastly superior to writing custom NetSuite authentication handlers. (Note: NetSuite's newer releases do support OAuth 2.0 for REST, which you should evaluate to simplify your auth layer going forward, but TBA remains ubiquitous).
Surviving Concurrency Limits, Not Rate Limits
Here is a point many teams get wrong: NetSuite does not impose traditional daily API rate limits. It enforces concurrent thread limits based on the customer's service tier.
The default tier allows just 15 concurrent requests. Tier 2 gets 25; Tier 3 gets 35; Tier 4 gets 45; Tier 5 gets 55. Each SuiteCloud Plus license adds 10 additional concurrent threads to this base pool. This means you can make millions of requests per day—as long as no more than your allotted limit are in flight at the exact same time.
When you exceed the allowed concurrent threads, NetSuite immediately responds with an HTTP 429 Too Many Requests error. How your external system reacts determines whether your integration recovers or crashes entirely. A common mistake in custom middleware is to retry a failed request immediately. NetSuite rejects Request A, middleware immediately retries Request A, meanwhile Request B arrives, and NetSuite rejects both, causing a distributed deadlock.
Your integration architecture must treat HTTP 429s as an expected operational state. The correct pattern is exponential backoff with jitter. The platform should normalize upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF specification. When NetSuite returns a 429, you must pass that error directly back to the caller. Do not automatically retry or silently absorb rate limit errors in a proxy layer, as this obscures the real concurrency situation. If you want to know how to normalize pagination and error handling across 50+ APIs, the secret is aggressive standardization at the proxy layer and disciplined retry logic at the client layer.
How to Create a Practical NetSuite Migration Guide Without SOAP
To successfully move your infrastructure off legacy XML endpoints without breaking production, execute the following architectural steps.
1. Audit Existing SOAP Payloads for Complex JOINs
Begin by logging every legacy SOAP request your system currently makes. Categorize each by operation type (read, write, metadata), record types touched, and batch usage. Identify the operations that rely heavily on nested XML structures to pull data across multiple NetSuite tables. These are the danger zones. Do not attempt to map these to the REST Record API. Document the exact tables and fields required, and prepare to rewrite these extractions as SuiteQL queries.
2. Implement Polymorphic Resource Routing
NetSuite's underlying data model is heavily fragmented. From an accounting perspective, vendors and customers are both simply entities you transact with. However, NetSuite treats them as entirely separate record types with separate database tables. Similarly, classes, departments, and locations are all forms of organizational segmentation but exist in isolation.
When migrating off SOAP, do not expose this fragmentation to your internal application logic. Implement a mapping configuration that links unified fields to provider-specific fields. Create a single, polymorphic contacts resource in your application. Use a query parameter or discriminator field (contact_type) to dynamically route the request to either the vendor or customer SuiteQL table or REST endpoint. This isolates your core application from NetSuite's schema quirks and matches how modern accounting platforms expose similar concepts.
3. Build Feature-Adaptive Query Logic
No two NetSuite instances are identical. NetSuite is a platform with wildly different configurations per customer. Some use NetSuite OneWorld (which requires subsidiary mapping), while others use standard editions. Some operate in multi-currency environments, while others are single-currency.
Your SuiteQL queries cannot be static strings; they must be feature-adaptive. A vendor query that JOINs the currency and subsidiary tables will fail fatally on a standard account that doesn't have those features enabled. During the initial connection setup, your integration should query the customer's NetSuite metadata to detect the active features. Based on this context, your query construction logic must dynamically include or exclude specific JOINs.
4. Transition to Declarative Mappings
Maintaining integration-specific code for NetSuite is a massive liability. Every time Oracle updates a schema requirement, you are forced to initiate a code deployment.
Transition your integration layer to use declarative mappings. Define the translation between your application's unified schema and NetSuite's native format using functional expression languages like JSONata. This allows you to handle NetSuite's flat PascalCase fields, custom field detection, and dynamic URL generation entirely as data operations. Separating your mapping logic from your execution pipeline is non-negotiable for long-term stability.
5. Run in Parallel, Then Cut Over
Do not attempt a big-bang migration. Run your new REST/SuiteQL integration in shadow mode alongside the existing SOAP integration:
- Route reads through SuiteQL first, and compare the JSON output to your legacy SOAP XML output.
- Once reads match flawlessly, route writes through the REST API, verifying the results against SOAP.
- Cut over workflow by workflow, hidden behind feature flags.
- Decommission SOAP paths only once validated in production.
More than 70% of ERP initiatives fail due to poor change management and insufficient testing. A parallel-run approach drastically de-risks the transition.
Truto vs Prismatic: Choosing Your Integration Platform for the NetSuite Migration
Once you understand the SuiteQL-first architecture, the next question is: what platform actually executes it? Two categories dominate the B2B SaaS integration space in 2026 - embedded iPaaS platforms like Prismatic and declarative unified APIs like Truto. They solve different problems at different architectural layers, and the NetSuite SOAP deprecation exposes exactly where those differences matter.
Prismatic is a workflow orchestration engine. It provides a low-code visual designer and a TypeScript SDK for building multi-step integration flows. Each integration is a distinct workflow artifact with triggers, steps, branches, and custom logic. Truto is a declarative unified API where every integration - including NetSuite - is defined entirely as data (JSON configuration and JSONata expressions) with zero integration-specific code in the runtime. For a deep architectural comparison, see our full Truto vs Prismatic guide.
The right choice depends entirely on what your product needs from the NetSuite integration.
Decision Checklist: Embedded iPaaS vs Unified API for ERP Migration
| Question | If Yes: Prismatic | If Yes: Truto |
|---|---|---|
| Do your end-users need to visually build custom NetSuite workflows inside your product? | ✓ | |
| Does your engineering team need normalized CRUD access across NetSuite, QuickBooks, Xero, and others through one API? | ✓ | |
| Do you need conditional branching and multi-step orchestration that varies per customer? | ✓ | |
| Do you want to add new ERP integrations without code deploys? | ✓ | |
| Is your primary use case letting customers configure their own automation triggers? | ✓ | |
| Do you need SuiteQL orchestration, TBA signature handling, and feature-adaptive queries managed for you? | ✓ | |
| Do you need to embed an integration marketplace for non-technical users? | ✓ | |
| Must customer ERP data never be stored on the integration platform? | ✓ |
5 Real-World Scenarios and Recommendations
Scenario 1: Your customers need to configure their own NetSuite sync rules.
Your customers operate in different industries, and each needs unique trigger-action sequences - "When an invoice is created in NetSuite with amount > $10,000, route for approval in our system and notify Slack."
Recommendation: Prismatic. This is user-defined orchestration logic. Prismatic's embedded workflow builder lets your customers wire up these flows without your engineering team building custom code for each one. Expect 2-4 weeks to build the initial NetSuite workflow template, plus ongoing per-workflow maintenance as the upstream API changes.
Scenario 2: Your SaaS product needs to read and write accounting data across NetSuite, QuickBooks, and Xero through one API.
Your product powers dashboards, compliance reports, or financial analytics. Your engineering team should call GET /unified/accounting/invoices and get identical JSON whether the customer uses NetSuite or QuickBooks. You do not want to build separate SuiteQL queries, QuickBooks GraphQL calls, and Xero REST handlers.
Recommendation: Truto. The unified API normalizes the data model across all three platforms. Truto handles SuiteQL orchestration, OAuth 1.0 TBA signature math, and feature-adaptive queries behind a single endpoint. Implementation is typically days for the initial integration, not weeks.
Scenario 3: Non-technical staff need to deploy and manage NetSuite integrations.
Your customer success team needs to configure new customer NetSuite accounts, troubleshoot sync issues, and deploy integration instances without filing engineering tickets.
Recommendation: Prismatic. Prismatic's embedded marketplace and configuration wizards are purpose-built for this operational model. Technical support staff configure known integrations; engineers only get involved for new workflow types. Budget 4-8 weeks for initial setup and team training.
Scenario 4: Strict data residency or compliance requirements prohibit storing customer financial data on any third-party platform.
Your compliance team requires that customer ERP data never be persisted on the integration vendor's infrastructure. Every API call must pass through directly to the source.
Recommendation: Truto. Truto's pass-through architecture makes API calls directly to the underlying provider without caching or storing customer data. It is SOC 2 Type II and ISO 27001 compliant and also supports on-premises deployment. Prismatic stores integration execution data on its platform as part of its workflow engine, which may require additional compliance review for regulated industries.
Scenario 5: You are migrating from a homegrown SOAP integration and want to minimize re-engineering.
Your team has a working SOAP integration with hundreds of custom field mappings, multi-currency logic, and subsidiary routing. You need to get off SOAP with minimal disruption to your existing application architecture.
Recommendation: Truto. Your application code changes are minimal - swap the SOAP client for HTTP calls to the unified endpoint. Truto's three-level override hierarchy means your custom field mappings, subsidiary routing, and multi-currency logic can be reproduced as JSONata configuration without code deploys. Expect 1-3 weeks for migration depending on the complexity of your existing SOAP payloads.
Estimated Engineering Effort and Timelines
| Task | Prismatic (Embedded iPaaS) | Truto (Unified API) |
|---|---|---|
| Initial NetSuite integration setup | 2-4 weeks (build workflow, handle TBA auth, wire SuiteQL) | Days (NetSuite config already exists) |
| Adding a second ERP (e.g., QuickBooks) | 2-4 weeks (new workflow from scratch) | Hours (same unified endpoint, new config) |
| Custom field mapping per customer | Per-workflow TypeScript customization | JSONata override, no code deploy |
| Handling NetSuite API breaking changes | Update specific workflow, test, redeploy | Update mapping configuration, no code deploy |
| Ongoing maintenance at 20+ integrations | ~0.5 FTE dedicated | Near-zero, config-only changes |
| Non-engineering staff training | 2-4 weeks (visual designer, marketplace) | Minimal, API-first and engineers self-serve |
Migration and Maintenance Considerations
If you are currently on a homegrown SOAP integration or re-evaluating your middleware stack, keep these factors in mind:
Switching from homegrown SOAP to Prismatic: You are replacing custom SOAP code with custom workflow code. The net benefit is Prismatic's managed infrastructure (monitoring, retries, deployment tooling) and its embedded marketplace for customer self-service. The trade-off is that you still build and maintain per-integration workflow logic. For NetSuite specifically, your team still needs to understand SuiteQL, TBA authentication, and concurrency limits. Prismatic provides the execution environment, not the NetSuite-specific query orchestration.
Switching from homegrown SOAP to Truto: You are replacing custom SOAP code with a single API call. The platform handles SuiteQL orchestration, TBA signature generation, feature-adaptive queries, and concurrency management. Your engineering team does not need deep NetSuite domain expertise. The trade-off is that Truto does not provide end-user workflow builders or embedded marketplaces. If your product requires customers to configure their own multi-step automation flows, you will need a separate tool for that layer.
Using both: Some teams use Truto for core normalized data access - syncing invoices, vendors, and purchase orders across ERPs - and layer Prismatic on top for customer-specific automation workflows that operate on that data. This is a valid architecture if your product genuinely needs both capabilities.
Securing Your NetSuite Infrastructure for 2028
The SOAP shutdown is not a distant problem. The countdown is already running, and the degradation of SOAP performance has already begun. Engineering teams that migrate to a SuiteQL-first architecture today will secure a massive reliability advantage over competitors still wrestling with legacy XML.
If you are a B2B SaaS company building NetSuite integrations for your customers—particularly if you need to build ERP integrations without storing customer data—the complexity multiplies. Handling OAuth 1.0 TBA math, SuiteQL orchestration, polymorphic routing, and feature-adaptive queries across dozens of unique customer accounts is a significant engineering investment. To go deeper on abstracting this architecture, read our guide on how to integrate the Oracle NetSuite API without SOAP complexity or explore enterprise auth patterns to see how declarative configuration solves the TBA signature problem out of the box.
FAQ
- What is the NetSuite SOAP API deprecation timeline?
- Oracle is phasing out SOAP in stages: the last SOAP endpoint ships in 2025.2, no new SOAP features after 2026.1, older endpoints retire in 2027.2, and all SOAP endpoints are permanently disabled in the 2028.2 release.
- Why is a direct SOAP-to-REST migration a mistake for NetSuite?
- The SuiteTalk REST API is designed for single-record CRUD, not bulk extraction. It forces N+1 sub-resource fetches, lacks ORDER BY support, and has hard pagination ceilings. A 1-to-1 migration will spike API call volume and trigger concurrency throttling.
- What is the tri-partite architecture for replacing NetSuite SOAP?
- Use SuiteQL for complex reads and JOINs, the SuiteTalk REST API for single-record writes, and SuiteScript RESTlets for capabilities absent from both (like PDF generation and dynamic form metadata).
- When should I choose Prismatic over Truto for NetSuite migration?
- Choose Prismatic if your product needs to let end-users visually build custom multi-step NetSuite automation workflows, or if non-technical staff need to deploy and manage integration instances through an embedded marketplace.
- When should I choose Truto over Prismatic for NetSuite migration?
- Choose Truto if your engineering team needs normalized CRUD access across NetSuite, QuickBooks, and Xero through one API, if you want SuiteQL orchestration and TBA auth handled for you, or if compliance requires that customer data never be stored on the integration platform.
- Can Truto and Prismatic be used together for NetSuite integrations?
- Yes. Some B2B SaaS teams use Truto for core normalized data access (syncing invoices, vendors, purchase orders across ERPs) and layer Prismatic on top for customer-specific automation workflows that fall outside the common data model.