NetSuite WSDL to REST Migration: 2026.1 Compatibility
2025.2 is the last planned SOAP endpoint, and from 2026.1 NetSuite adds no new ones. Here are the three phases and what each does to you.

On this page
Oracle's timeline is now concrete. The 2025.2 SOAP endpoint is the last planned SOAP endpoint, and from 2026.1, NetSuite stops adding new SOAP endpoints to the WSDL. Existing SOAP calls will keep running, but you'll never see new features or operations through that interface. If you're planning a migration to REST APIs before the full WSDL phase-out, you need to know where the gaps actually are, not just the marketing version of this transition.
What Changes With 2026.1 and Beyond
The deprecation has three distinct phases, and each affects your integration differently:
| Release | What Changes | Impact on Your Integrations |
|---|---|---|
| 2026.1 | No new SOAP endpoints added | Existing SOAP calls work, but no new operations available |
| 2027.1 | TBA restricted to existing integrations only | New TBA credential creation stops; sandbox refreshes break integration re-authentication |
| 2028.2 | SOAP no longer available in NetSuite | All SOAP integrations stop working entirely |
The 2027.1 TBA restriction is the one most teams miss. When you refresh from Production to Sandbox, your integration credentials get wiped. Under current rules, you can re-setup those integrations. After 2027.1, if your integration wasn't already registered, you won't be able to create new TBA credentials. That means your sandbox testing environment becomes useless for integration validation.
Oracle's SuiteTalk SOAP Web Services Platform Guide confirms that SuiteTalk REST web services is the technology intended to replace SOAP, and all newly built integrations should use REST with OAuth 2.0.
The Functional Gaps You'll Hit First
REST APIs are not a drop-in replacement for SOAP. Several operations that worked cleanly through WSDL behave differently or don't exist yet.
Multi-Record Processing Requires Async
This is where most migrations break. SOAP's upsertList and similar batch operations let you send multiple records in a single synchronous call. REST APIs don't work that way for large payloads.
If you're processing more than a few records per request, you must use async REST requests. The pattern looks like this:
/**
* @NApiVersion 2.1
* @NScriptType Restlet
*/
define(['N/https', 'N/log'], function(https, log) {
/**
* POST handler for async batch processing
*/
function doPost(requestBody) {
var config = {
endpoint: 'https://your-account.suitecommerce.com/app/site/hosting/restlet.nl?script=123&deploy=1',
method: https.Method.POST,
headers: {
'Authorization': 'Bearer ' + requestBody.token,
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody.records)
};
var response = https.request(config);
// Check for 202 Accepted - indicates async processing
if (response.code === 202) {
log.debug('Async request accepted', response.headers['location']);
return {
status: 'accepted',
pollUrl: response.headers['location']
};
}
return JSON.parse(response.body);
}
return {
post: doPost
};
});The response returns a 202 Accepted status with a location header you poll for completion. This changes your error handling strategy significantly, you can't just read the response body and move on.
Customer Refunds and Refund Method
The refund method setting is a concrete example of REST's functional gap. SOAP exposed the refund method directly on customer refund records. REST doesn't expose this field the same way through standard endpoints.
The REST API Browser shows the customerRefund record type exists, but the refundMethod field isn't available through the standard REST endpoints. You have two options:
- RESTlet workaround: Build a SuiteScript RESTlet that reads and sets the refund method using the
N/recordmodule - Wait for native support: Oracle has not given a timeline for this field
/**
* @NApiVersion 2.1
* @NScriptType Restlet
*/
define(['N/record'], function(record) {
function doPost(requestBody) {
var refundRecord = record.load({
type: record.Type.CUSTOMER_REFUND,
id: requestBody.refundId
});
// Set refund method - field ID varies by account
refundRecord.setValue({
fieldId: 'refundmethod',
value: requestBody.methodId
});
refundRecord.save();
return { success: true, id: refundRecord.id };
}
return {
post: doPost
};
});Authentication Migration: OAuth 2.0 vs TBA
OAuth 2.0 is the authentication standard for REST APIs, and it's more complex than TBA. The authentication documentation Oracle provides is thorough but dense, plan to read it multiple times.
The key difference: TBA uses a simple consumer key/consumer secret pair plus token ID/secret. OAuth 2.0 requires an authorization flow with tokens that expire and refresh. Your integration needs to handle token refresh logic that didn't exist with TBA.
Step 1: Create an OAuth 2.0 integration record at Setup > Integration > Manage Integrations > New
Step 2: Configure the authorization grant type. For server-to-server integrations, use Client Credentials Grant. This avoids the browser redirect flow entirely.
Step 3: Exchange your client ID and secret for an access token:
/**
* @NApiVersion 2.1
* @NScriptType Restlet
*/
define(['N/https', 'N/log'], function(https, log) {
function getAccessToken(clientId, clientSecret, accountId) {
var authUrl = 'https://' + accountId + '.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token';
var response = https.request({
url: authUrl,
method: https.Method.POST,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'grant_type=client_credentials&client_id=' + clientId +
'&client_secret=' + clientSecret
});
var result = JSON.parse(response.body);
log.debug('Access token received', 'Expires in: ' + result.expires_in + ' seconds');
return result.access_token;
}
return {
get: getAccessToken
};
});Step 4: Store the refresh token securely. Access tokens are valid for one hour (3600 seconds). When the token expires, send a refresh token POST request to the same token endpoint to get a new access token without re-authenticating.
Sandbox Refresh and Authentication Revalidation
The 2027.1 TBA restriction creates a specific failure scenario you should plan for now.
When you refresh Production to Sandbox, the integration records in the Sandbox get reset. TBA tokens you create in production aren't copied to sandbox or Release Preview accounts. Under current behavior, you can re-enter your TBA credentials and continue testing. After 2027.1, new TBA setup won't be available for refreshed Sandbox accounts.
The workaround: Build your integration to support OAuth 2.0 from day one. Even if you're migrating existing SOAP integrations, switch the authentication layer to OAuth 2.0 before you tackle the REST endpoint migration. That separates the authentication problem from the functional migration problem.
The validation step: After a sandbox refresh, attempt to call a REST endpoint with your stored credentials. If you get a 401 Unauthorized response, you know the credentials were reset. With OAuth 2.0, you can re-run the authorization flow without creating a new integration record.
Saved Searches and SuiteQL: The Data Access Shift
REST APIs change how you query data. SOAP's search operation maps directly to saved searches. REST doesn't have an equivalent search endpoint, you use SuiteQL instead.
This migration has a specific compatibility issue: SuiteQL previously only exposed SuiteTax fields, while saved searches had legacy tax fields. Oracle added legacy tax fields to SuiteQL in recent releases, but you should verify your specific tax configuration works before migrating queries.
Oracle is also working on a method that generates SQL from saved searches, similar to what SuiteAnalytics Workbooks already offers. This will let you convert existing saved searches to SuiteQL queries without rewriting them from scratch.
The practical approach: Audit your saved searches now. For each one, identify:
- Which fields it references
- Whether those fields exist in SuiteQL
- Whether the join behavior matches
Test each converted query against production data before switching your integration to REST.
What to Audit Before You Start
Before writing any migration code, inventory your existing SOAP integrations:
- WSDL version: Find which WSDL endpoint version each integration uses. Check the integration record at Setup > Integration > Manage Integrations and review the deployment records
- Record types used: List every record type your integrations touch. Compare against the REST API Browser to identify gaps
- Batch operations: Identify any
upsertList,searchMoreWithId, or other multi-record operations. These need async REST redesign - Custom fields: Verify custom fields are accessible through REST. Most are, but field-level security settings can hide them
The Migration Sequence That Works
Start with read-only integrations. These are the lowest risk and build your team's familiarity with REST authentication and SuiteQL.
Step 1: Migrate saved search queries to SuiteQL. Test them side by side against the same data.
Step 2: Migrate single-record create and update operations. These map directly to REST endpoints with minimal redesign.
Step 3: Migrate multi-record operations. This is where you implement async request handling and build your polling logic.
Step 4: Re-validate authentication after a sandbox refresh. Confirm your OAuth 2.0 flow survives the refresh process.
Step 5: Test with a single record first. Run one transaction through the REST endpoint, verify it in the UI, then scale to batch processing.
The error response tells you exactly what went wrong, read it carefully. REST returns structured error objects with error codes and details, unlike SOAP's fault strings. Log these responses in your integration for troubleshooting.
The Compatibility Checklist
Before you cut over any production integration, verify these items:
- Field-level security: Confirm REST API users have the same field access as SOAP users. The REST API respects field-level security differently in some record types
- Custom segments: Check that custom segments and custom record types are visible through REST
- Attachments: File attachments behave differently in REST. The
filerecord type requires base64 encoding in the request body - Currency and exchange rates: Multi-currency transactions may expose different fields through REST than SOAP
- Subsidiary context: If you use OneWorld, confirm the subsidiary field is set correctly in REST requests. SOAP's
subsidiaryfield has different validation rules
Test this with a single record first. Create one transaction through REST, verify all fields landed correctly, then process a small batch. Only after those pass should you migrate the full integration.
The migration window is real, and the 2027.1 TBA restriction will catch teams that wait. Start with your authentication layer, then move to read-only queries, then tackle the multi-record operations that require async handling. The SOAP migration guide walks through the full upgrade path if you need a structured reference.


