SOAP Web Services Frequently Asked Questions (FAQ)

Where is the NetSuite WSDL located?

In general, the WSDL is located on the URL specific to your account. See URLs for Account-Specific Domains for information about finding your account-specific URLs.

What programming languages and platforms are supported in this release?

This release should work with any platform or tool that supports SOAP 1.1. NetSuite has verified that the Java Apache Axis and Microsoft .NET platforms work correctly, and sample programs for these environments are available in the Resources section of the Web Services portal. Also note that there is a PHP toolkit available for PHP developers wanting to build SOAP web services applications. See SOAP Web Services PHP Toolkit for more details.

What is an internal ID (or nsKey)? What is a RecordRef? How do I get the values for internal IDs?

An internal ID is a unique key used to reference a record within NetSuite. In SOAP web services, the RecordRef type is used to abstract the internal ID. For example, a RecordRef is required to uniquely identify the records for update, delete, or get operations. Also, a typical record exposed through SOAP web services will have references to other NetSuite records of different types through the RecordRef type.

The internal ID for a record can be obtained as follows:

  • If a record type has been exposed through SOAP web services, a search operation will return the internal ID.

  • Alternatively, you can also obtain the internal ID for that record in the UI on the list page for that record type. To see the internal ID, go to Home > Set Preferences > General and check the Show Internal IDs box.

What are the maximum number of records allowed for write operations such as addList, updateList, or deleteList?

This varies depending on whether records are submitted during peak or off-peak hours. For more detailed information, see the section called Understanding Record Limiting in the NetSuite Help Center.

Why can't I maintain a valid session using Apache Axis?

The NetSuite SOAP web services implementation requires the client application to support multiple cookies on one line, as is the standard for cookies. There is a bug in Apache Axis that puts each cookie on its own line in the HTTP Headers. A patched version of the axis.jar can be downloaded from NetSuite Web Services Developer's page to fix this problem. Please note that the patch you download depends on the version of Axis that you are using. Replace the existing axis.jar file in the lib directory of your project with the NetSuite version.

Why can't I maintain a valid session using Microsoft .NET?

The NetSuite SOAP web services implementation requires the client application to support multiple cookies. Please see the .NET sample application for an example of how to enable support for multiple cookies.

I have populated some fields in a record when adding or updating, but why are these fields not being populated in the SOAP document?

This is a .NET anomaly. For every field that's not of type string, the generated .NET object contains an additional attribute whose name is the field name concatenated with the word "Specified". For example, there is a Boolean field name called inactive in the Customer record type. When .NET generates this class, it adds an additional Boolean field called inactiveSpecified. This field needs to be set to true for the inactive field to be included in the SOAP document.

Can multiple users logged into the same account run SOAP web services simultaneously?

Yes. SOAP web services are associated to the user, NOT the account. Therefore, multiple users can access the same account through SOAP web services. Also, a single user can have a concurrent browser and SOAP web services session, and additional SOAP web services sessions for a certain user can exist for SOAP web services partner applications.

Is it possible to run SOAP web services and XML independently and simultaneously within an account without mutually exclusive restrictions?

There are currently no restrictions. However, to ensure adequate load distribution, the use of all NetSuite integration technologies will be analyzed and restrictions implemented as appropriate.

How do I query for all records of a certain type?

Use the search operation with a search record that has no fields populated.

I get a SOAP fault and a message which states “The Operation has timed-out.” when using my .Net client and I get no SOAP response back. What could be causing this?

If you have not explicitly set the timeout on your .Net application, this may be related to the preset timeout of 100 seconds on the SoapHttpClientProtocol class. You must change this timeout to be equal to or greater than the NetSuite timeout (15 minutes). Otherwise, your client will abort processing prematurely.

Note:

If you receive the same fault, or a service unavailable error which includes an HTTP error code (for example, 50x), this is likely a NetSuite related timeout. Server restarts can occur, and if you receive the HTTP 503 error code, you need to retry sending the request later.

Sample Code: .Net

                 public NSClient( )
   {
      _isAuthenticated = false;
      _pageSize = 40;
      // Instantiate the NetSuite web services
      _service = new NetSuiteService();
      // Set client timeout to 100 hours
      _service.timeout = 100*60*60*1000; 

            

Sample Code: Java

                 // Locate the NetSuite web service.
   NetSuiteServiceLocator service = new NetSuiteServiceLocator();
   // Enable client cookie management. This is required.
   service.setMaintainSession(true);
   // Get the service port
   _port = service.getNetSuitePort();
   // Setting client timeout to 2 hours for long running operations
   ((NetSuiteBindingStub) _port).setTimeout(1000 * 60 * 60 * 2); 

            

I am getting an unexpected server side protocol timeout error (502) and no SOAP response is sent back. What could be causing this?

Check the timeout settings on any intermediaries that you are using — such as proxy servers or port sniffers (SOAPScope).

To edit the timeout setting for SOAPScope, you need to edit the httpd.conf file to the desired settings and then restart the SOAPScope service. The httpd.conf file is located in the conf subdirectory of the SOAPScope data directory.

Note:

There is a link to the SOAPScope data directory in the Start menu.

In the following code the default Timeout value of 300 has been changed to 901.

                 PidFile nul:
   Timeout 901
   KeepAlive On
   MaxKeepAliveRequests 0
   KeepAliveTimeout 15 

            

Why do I receive socket timeout exception errors?

Networks are inherently unreliable, and a SocketTimeoutException can occur anytime. To handle this error, you must implement a mechanism to keep sending your SOAP web services requests. For information about setting up a retry mechanism, see Web Services and RESTlet Concurrency Governance.

Why are attachments uploaded with Messages getting corrupted?

This may be due to incorrectly encoding a file before sending it. The schema has a data type of xsd:base64Binary which is mapped to a byte array in .NET and Axis (java). On the client side we only need to pass a text or binary file as a byte array with no further base64 encoding. Therefore, do NOT Base64 Encode the file before sending it to Axis or .NET as these layers will do so themselves.

Sample Code:

  • Correct

                            --------
          fis = new FileInputStream(inFile);
          b = new byte[(int)inFile.length()];
          fis.read(b);
          myMediaItem.setContent(b);
          -------- 
    
                    
  • Incorrect

                    ---------
      fis = new FileInputStream(inFile);
      b = new byte[(int)inFile.length()];
      fis.read(b);
      myMediaItem.setContent(new String(Base64.encode(b))); 

            

How can I determine internal ID values for individual items in a custom list?

Generally, a certain list displays the internal IDs as one of the columns. For example, List > Relationships > Customers displays the internal IDs as the second column (when the Show Internal ID preference is enabled). In the NetSuite Help Center, see Setting the Show Internal IDs Preference for more details.

When referencing items in a custom list, you must first reference the SelectCustomFieldRef by its internal ID, which is displayed in the respective custom field list (for example, for a custom customer field it would be displayed at Customization > Lists, Records, & Fields > Entity Fields).

Next, reference the internal ID to the Custom List or Record. Internal IDs to custom lists are NOT displayed in the UI. You must refer to the HTML source for the internal ID. When in the HTML source, search for the name of the value and note the integer which follows. For example, if referring to the Items of Interest custom list (provided in most test accounts) and need to select Monitors as one of the values, view the HTML source in the browser and find that string:

Accessories1F[1]Computers3F[1] Monitors2 F[1]Peripherals4F

Note:

The display order is in the order the values appear, but the internal IDs may be different. Monitors in this case has a internal ID of 2.

If you are referring to a Record, you need to locate the internal ID displayed in the column of the appropriate list.

When working with custom records, why do I need a separate CustomRecordRef class, when even for creating a customRecord I have to instantiate the RecordRef type?

In general RecordRef is for get() and Record is for add(). We sometimes use RecordRef to store name/value pairs.

RecordRef and CustomRecordRef both descend from BaseRef. They are most prominently used in get(), and that is why they have a type attribute. CustomRecordRef has a typeId to indicate which kind of CustomRecord it is. Therefore, you can NOT get a CustomRecord by setting the RecordRef.type to customRecord on add — you must use CustomRecordRef to specify the kind of CustomRecord.

CustomRecord descends from Record, like Customer or Opportunity. This is what you submit to add() and it is what is returned through search(). CustomRecord uses a RecordRef() to store its type information.

Java Example

To add a CustomRecord

                 CustomRecord myCR = new CustomRecord();
   RecordRef rt = new RecordRef();
   rt.setName("Authors");
   rt.setId("3"); // This indicates a typeId of 3 and corresponds to the Authors CustomRecord type
   myCR.setRecType(rt); 
   myCR.setName("Ernest Hemmingway"); // This is what will show up in List->
   CustomRecords->Authors under Name
   myCR.setCustomFieldList(myCFL); // An already filled out CustomField List
   WriteResponse wr = port.add(myCR); 

            

Note that setTypeId is not submitted since this is the internal ID returned by the response, like for normal records.

To get a CustomRecord:

                 CustomRecordRef myCRR = new CustomRecordRef();
   myCRR.setKey("1200"); // The key we got back
   myCRR.setTypeId("3"); // For Authors
   myCRR.setType(RecordType.customRecord);
   ReadResponse rr = port.get(myCRR); 

            

.Net Example

To add a CustomRecord

                 CustomRecord myCR = new CustomRecord(); 
   RecordRef rt = new RecordRef(); 
   rt.name = "Authors"; 
   // This indicates a typeId of 3 and corresponds to the Authors CustomRecord type 
   rt.internalId = "3"; 
   customRecord.recType = rt; 
   // This is what will show up in List->CustomRecords->Authors under Name 
   customRecord.name = "Ernest Hemingway"; 
   customRecord.customFieldList = myCFL; // An already filled out CustomField List 
   WriteResponse wr = port.add(customRecord); 

            

To get a CustomRecord:

                 CustomRecordRef myCRR = new CustomRecordRef(); 
   myCRR.internalId = "1200"; // The key we got back 
   myCRR.typeId = "3"; // For Authors 
   ReadResponse rr = _service.get(myCRR); 

            

How can I set multiple fields' values to NULL when using the PHP toolkit?

You can set values to NULL by submitting the fields in nullFieldList. The following example sets the fax and phone field to NULL.

               // Include NetSuite Class Library
require_once '../PHPToolkit/NetSuiteService.php';
 
// Instantiate new service
$service = new NetSuiteService();
 
// Create contact record
$ctact = new Contact();
 
// Set up record fields
$aBook = array (
   "addressbook" => array( 
   array( 
   "defaultBilling" => true,
   "defaultShipping" => false,
   "addr1" => $_POST['bill_addr1'],
   "city" => $_POST['bill_city'],
   "state" => $_POST['bill_state'],
   "zip" => $_POST['bill_zip'] ),
   array( "defaultBilling" => false,
      "defaultShipping" => true,
      "addr1" => $_POST['ship_addr1'],
      "city" => $_POST['ship_city'],
      "state" => $_POST['ship_state'],
      "zip" => $_POST['ship_zip'] )));
 
// Use setFields to fill the contact record with the fields
setFields($ctact, array("addressbookList"=>$aBook));
 
// Create NullField record
$nfl = new NullField();
 
// Set the null fields in the record
setFields($nfl, array("name" => array( "fax","phone")));
setFields($ctact, array("internalId" => "87", "nullFieldList" => $nfl));
 
// Update the contact record
$response = $service->update($ctact); 

            
Note:

You cannot set the Custom Form field to NULL. (This field is available on transaction and entry forms to indicate the form that should be used.) Any request to set it this field to NULL with nullFieldList will be ignored.

Why do I not get data for all elements on a search for a certain record type?

When performing searches on records, by default only the body fields are returned.

For example, if a Get or GetList operation against a customer record is submitted, the addressbooklist element contains data but if a Search operation against a customer record is submitted, the addressbooklist element is un-defined.

To return field values for all lists on a record, you must set the bodyFieldsOnly element of the searchPreferences type to false. The default settings should be used wherever list values are not necessary since this significantly improves performance.

                 <complexType name="SearchPreferences"> 
      <sequence> 
         <element name="bodyFieldsOnly" type="xsd:boolean" default="true" /> 
      </sequence> 
   </complexType> 
   <element name=" searchPreferences" type="platformCore: SearchPreferences" /> 

            
Note:

You can perform quick and full searches as the same time. For example, to show a list of email folders, but only query for messages in the default folder, do a quick search to get folder names/keys, and a full search on all messages.

Does SOAP web services support double-byte character sets like those used in Japanese and Korean?

The WSDL itself is only in English, but data can be in any language that uses UTF-8 character encoding, including those that use double-byte character sets.

Why are some classes from the NetSuite WSDL not being generated?

If you are using Java, to generate unreferenced types you should set the all parameter in your axis-wsdl2java ant task to true. For example:

                 <axis-wsdl2java timeout="120000" output="${generated.src.dir}" verbose="true" 
   url="${wsdl-1.3.url}" all="true" wrapArrays="true"> 

            

What is the process flow for using SOAP web services asynchronous calls?

The process flow for using WS asynchronous calls is as follows:

  1. Make the desired asynchronous call defined in NetSuitePortType – asyncAddList, asyncUpdateList, asyncDeleteList, asyncGetList, asyncSearch.

    A job ID is returned.

  2. Call the checkAsyncStatus method with the job ID as the parameter. The returned object, AsyncStatusResult, encapsulates the object AsyncStatusType, which indicates the status of the asynchronous job. The defined statuses are failed, finishedWithErrors, pending, processing, and finished.

    This step may iterate until the desired status is reached. Alternatively, go to Setup > Integration > SOAP Web Services Process Status to obtain the status information.

  3. Call the getAsyncResult method with the job ID and page index as the parameters. The returned object AsyncResult contains the result of each record on which the asynchronous job operated.

Note:

AsyncResult is an abstract type; consequently one of its concrete subclasses AsyncAddListResult, AsyncDeleteListResult, AsyncGetListResult, AsyncSearchResult, AsyncUpdateListResult – is returned.

Are SOAP web services samples available for different development platforms?

The NetSuite SOAP web services implementation is designed to work with any development platform that is able to generate SOAP messages. We provide Java and C# sample applications, which are available for download in our SuiteTalk portal (http://www.netsuite.com/portal/developers/resources/suitetalk.shtml).

You may also find useful community-based developer assistance at the web services forum in the NetSuite Usergroup.

Can I use SOAP web services with my sandbox account?

Please note that the URL for the WSDL differs between your production account and your sandbox account. If you want to use SOAP web services with your sandbox account you will need to use the following URL:

https://<accountID>-sb1.suitetalk.netsuite.com

Note:

Provide your own account ID in your SOAP web services request.

Where can I download the current version of the WSDL?

The NetSuite SOAP WSDL provides a complete description of available services, operations, and messages for SOAP web services.

To download the current version of the WSDL:

  1. Go to http://www.netsuite.com/portal/developers/resources/suitetalk-documentation.shtml

  2. Click View Zipped.

For additional information, see the following areas in the the NetSuite Help Center:

  • Release Notes – Describes all changes in the newest release, including an overview of platform enhancements and a list of newly exposed records.

  • Platform Guide – Offers an overview of the NetSuite SOAP web services architecture. Includes a "Getting Started" section for users of both C# and Java.

  • Records Guide – Features detailed reference pages on all supported records.

For PDFs of Help Center documentation for download, see User Guides.

General Notices