NetSuite Integration with SuiteAPI and Xojo

Published on October 30, 2022.

A number of people have reached out to me today with questions about a LinkedIn post that I made last night. The post included a short animation of a "NetSuite item lookup" Web app that I've developed, using Xojo, to demonstrate some of the capabilities of SuiteAPI.

Here's the animation.

Click the image to view a larger version.

In this post, I'll answer some of the questions that I've received, briefly introduce SuiteAPI, and talk a little about the application that I demonstrated.

Xojo

Over the past several months, I've written quite a bit about Xojo.

In July I wrote about low-code software development tools, why I think they're needed in the NetSuite space, and why I've selected Xojo as my low-code development tool. (See "NetSuite and Low-Code App Development.")

In August, Geoff Perlman (Xojo's Founder and CEO) and I gave a live webinar where we discussed low-code in general and showed how you can use Xojo to quickly and easily build apps that integrate with and extend NetSuite. (See "NetSuite: Xojo Low-Code Webinar Follow-Up" as a follow-up, with a link to a recording of the webinar and example Xojo projects.)

SuiteAPI

SuiteAPI is an alternative NetSuite Web API that I've developed and frequently use as the foundation for client integration projects. It provides the type of functionality that I often need for those types of projects, whether I'm developing Web, mobile, or desktop applications.

With SuiteAPI, you can easily retrieve records, run SuiteQL queries, access the results of saved searches, upload and download files to and from the NetSuite file cabinet, send emails via NetSuite, generate PDFs based on NetSuite transactions, generate PDFs based on ad-hoc XML code, and more. SuiteAPI can be extended to add support for additional functionality, including creating and updating transactions (sales orders, purchase orders, quote, entities (customers, vendors, employees, etc), items, and more.

Unlike NetSuite's SuiteTalk REST Web service, SuiteAPI isn't RESTful, but is instead an RPC-style (remote procedure call) Web API. All SuiteAPI requests are made as HTTP POSTs with JSON-encoded payloads, and the responses are also JSON-encoded. SuiteAPI is extremely easy to use, it's reliable, and it's secure (it uses NetSuite's native security model, including roles, tokens, etc). SuiteAPI has a small footprint, and consists of a single RESTlet.

I've been wanting to make SuiteAPI available under an open source license, and that's finally happening this week.

About The Xojo Project

The application that I demonstrated in the animation is one of several apps that I've been developing with Xojo to both test and serve as examples of what you can do with SuiteAPI. That particular application is a Xojo Web application, developed using Xojo's Web 2.0 framework. The Xojo project consists of a single WebPage, a Container, and a WebDialog. Here are a few screen shots of the project.

Click the image to view a larger version.

Click the image to view a larger version.

Click the image to view a larger version.

The nsConnection Class and SuiteAPI Requests

To make the calls to SuiteAPI, I used the nsConnection class that I've written about in previous posts. The app uses three instances of that class to make three different types of calls to SuiteAPI.

The first call uses SuiteAPI's "queryRun" procedure to lookup the item based on its ItemID. The payload looks like this.

{
  "procedure": "queryRun",
  "query": "SELECT 
	ID,
	ItemID, 
	ItemType,
	DisplayName,
	StoreDescription,
	( SELECT SUM (quantityOnHand) FROM ItemInventoryBalance WHERE ItemInventoryBalance.Item = Item.ID ) AS quantityOnHand,
	( SELECT SUM (quantityAvailable) FROM ItemInventoryBalance WHERE ItemInventoryBalance.Item = Item.ID ) AS quantityAvailable,
	( SELECT TOP 1 Price FROM itemPrice WHERE itemPrice.Item = Item.ID AND itemPrice.pricelevelname = 'Base Price' ) AS price
FROM 
	Item
WHERE
	( ItemID = ? )",
  "params": [
    "RB431"
  ]
}

The response looks like this.

{
  "records": [
    {
      "id": 431,
      "itemid": "RB431",
      "itemtype": "InvtPart",
      "displayname": "Rhinestone Blouse",
      "storedescription": "A deep blue high neck blouse with neck tie. 100% polyester.",
      "quantityonhand": 200,
      "quantityavailable": 200,
      "price": 70
    }
  ]
}

The second call uses the item's internal NetSuite record ID to load the record, and it does so using SuiteAPI's "recordGet" procedure. The payload for that request looks like this.

{
  "procedure": "recordGet",
  "type": "inventoryitem",
  "id": 431
}

The response is very long, so I've included at the end of this post.

The reason that I load the record is that I need to get access to any images that are associated with the item. At this point, there's no way to do that using SuiteQL. So I load the record, and then drill down into the response to get to the "itemimages" sublist. In the response, it looks like this:

"itemimages": {
	"line 1": {
	  "altTagCaption": null,
	  "name": "B763451.media.blouse.jpg",
	  "nkey": "229551",
	  "siteList": "229551",
	  "sys_id": "3840635349246702",
	  "sys_parentid": "3840635349119410"
	}
}

The "nkey" attribute is actually NetSuite's internal ID for the image file. Once I have that, I can make one last call to SuiteAPI to get the image itself. Here's what the request looks like:

{
  "procedure": "fileGet",
  "id": 229551,
  "returnContent": false
}

And the response looks like this:

{
  "file": {
    "info": {
      "type": "file.File",
      "id": "229551",
      "name": "B763451.media.blouse.jpg",
      "description": null,
      "path": "Web Site Hosting Files/Live Hosting Files/assets/all-item-images/B763451.media.blouse.jpg",
      "url": "/core/media/media.nl?id=229551&c=TSTDRV2533109&h=7vD3PtxHdH8tHPYFCpzHLdGWevLSpbTokjErOqyttRcRV2Nw",
      "folder": 53179,
      "fileType": "JPGIMAGE",
      "isText": false,
      "size": 23972,
      "encoding": "UTF-8",
      "isInactive": false,
      "isOnline": true
    }
  }
}

I then use the URL from the response to load the image into an instance of Xojo's WebImageViewer class.

Wrapping Up

The application shown in the animation is relatively simple, and yet potentially quite helpful - especially to businesses that are running on NetSuite and need to provide access to inventory information to non-NetSuite users. It's also a great example of SuiteAPI's capabilities, and how easy Xojo makes it to develop this type of Web application.

I'm really excited to making SuiteAPI available to the NetSuite community, and I hope it helps developers with their NetSuite integration projects - especially developers who might not have extensive experience with the platform. I'm hoping to release it on Tuesday afternoon, and I'll announce it's release both here on my blog and on LinkedIn.

And as I've mentioned in previous posts, I'm hoping that NetSuite developers will take a look at Xojo and give it a try. As you can see from the app described in this post, Xojo makes developing Web apps that integrate with NetSuite incredibly easy to develop. And when you throw in SuiteAPI's capabilities, the possibilities are compelling. You can develop desktop, Web, and mobile apps that seamlessly integrate with and extend NetSuite.

Sample SuiteAPI "recordGet" Response

{
  "record": {
    "id": "431",
    "type": "inventoryitem",
    "isDynamic": false,
    "fields": {
      "costingmethoddisplay": "Average",
      "autoleadtime": "T",
      "custitem_fg_go_adult": "F",
      "custitem_ns_sc_ext_id_hide_invt_msg": "F",
      "custitem_nsts_scis_exclude_from_wstore": "F",
      "_eml_nkey_": "TSTDRV2533109~1545~1064~N",
      "storedisplayname": "Rhinestone Blouse",
      "type": "item",
      "custitem_ns_sc_ext_ts_exclude": "F",
      "price6quantity1": "0",
      "purchaseconversionrate": "1",
      "lastpurchaseprice": "50.00",
      "price3header": "price3quantity",
      "price6header": "price6quantity",
      "pricingchange": "F",
      "cogsaccount": "134",
      "id": "431",
      "unitswarningdisplayed": "F",
      "price1headercount": "5",
      "custitem_ns_sc_ext_ts_override": "F",
      "totalquantityonhand": "200",
      "costestimatetype": "AVGCOST",
      "purchaseunit": "1",
      "entryformquerystring": "itemtype=InvtPart&e=T&id=431",
      "price4headercount": "5",
      "islotitem": "F",
      "version": "4",
      "subsidiary": "1",
      "alternatedemandsourceitem": "",
      "isdonationitem": "F",
      "nextagproductfeed": "F",
      "shopzillaproductfeed": "F",
      "custitem_ns_ib_badges": "",
      "custitem_ns_sc_grid_order_show_stock": "F",
      "price5quantity1": "0",
      "custitem_ns_ib_show_badges": "F",
      "handlingcostunits": "per Ea",
      "saleunit": "1",
      "stockunit": "1",
      "createddate": "12/28/2021 7:29 am",
      "isserialitem": "F",
      "price5header": "price5quantity",
      "froogleproductfeed": "F",
      "incomeaccount": "288",
      "supplyreplenishmentmethod": "REORDER_POINT",
      "itemidorig": "RB431",
      "storeDisplayNameOrig": "Rhinestone Blouse",
      "custitem_ns_sc_page_printer_behavior": "1",
      "custitem_ns_sc_ext_id_hide_low_qty_msg": "F",
      "nluser": "1545",
      "currency": "1",
      "price5headercount": "5",
      "origbinactive": "F",
      "custitem_scis_include_item_in_fallback": "F",
      "usebins": "F",
      "enforceminqtyinternally": "T",
      "seasonaldemand": "F",
      "shippingcostunits": "per Ea",
      "unitstypewarningdisplayed": "T",
      "showdefaultdonationamount": "F",
      "custitem_ef_smh_social_media_hashtag": "",
      "custitem_ns_sc_ext_only_pdp": "F",
      "custitem_cust_include_item_in_fallback": "F",
      "shipindividually": "F",
      "price2quantity1": "0",
      "minimumquantityunits": "Ea",
      "displayname": "Rhinestone Blouse",
      "isdropshipitem": "F",
      "nlloc": "0",
      "nlsub": "2",
      "custitem_ef_badges": "",
      "unitstypefracconv": "F",
      "custitem_size": "",
      "binmapchange": "F",
      "shoppingproductfeed": "F",
      "custitem_ns_pr_item_attributes": "",
      "price6headercount": "5",
      "custitem_ns_sc_ext_plt_leadtimemessage": "F",
      "itemtypename": "Inventory Item",
      "isonline": "T",
      "price3quantity1": "0",
      "totalquantityonhandunits": "Ea",
      "autoreorderpoint": "T",
      "custitem_bed_size": "",
      "accchange": "F",
      "custitem_is_variable_amount": "F",
      "totalvalue": "10000.00",
      "costestimateunits": "per Ea",
      "salesdescription": "Rhinestone Blouse",
      "origcost": "50.00",
      "gainlossaccount": "100",
      "baseunit": "1",
      "price4quantity1": "0",
      "origexchangerate": "1.00",
      "price4header": "price4quantity",
      "taxschedule": "2",
      "includechildren": "T",
      "custitem3": "",
      "custitem2": "",
      "internalid": "431",
      "price3headercount": "5",
      "custitem1": "",
      "vendreturnvarianceaccount": "173",
      "isstorepickupallowed": "T",
      "producer": "F",
      "storedescription": "A deep blue high neck blouse with neck tie. 100% polyester.",
      "matchbilltoreceipt": "F",
      "usemarginalrates": "F",
      "custitem_waist_size": "",
      "modifiableitemid": "RB431",
      "isinactive": "F",
      "origcostunits": "per Ea",
      "price2headercount": "5",
      "wfinstances": "",
      "purchasedescription": "Rhinestone Blouse",
      "dontshowprice": "F",
      "exchangerate": "1",
      "maximumquantityunits": "Ea",
      "atpmethod": "CUMULATIVE_ATP_WITH_LOOK_AHEAD",
      "nsapiCT": "1667164902294",
      "itemid": "RB431",
      "price1matrixfields": "price",
      "sys_id": "3840635349119410",
      "lastpurchasepriceunits": "per Ea",
      "offersupport": "F",
      "price2matrixfields": "price",
      "custitem_ef_badges_2": "",
      "nldept": "0",
      "price1header": "price1quantity",
      "assetaccount": "127",
      "custitem_ns_sc_grid_order_behavior": "1",
      "custitem_ns_sc_grid_order_stock_notif": "F",
      "price4matrixfields": "price",
      "price5matrixfields": "price",
      "custitem_bed_type": "",
      "unitstype": "1",
      "custitem_colors": "",
      "price3matrixfields": "price",
      "costunits": "per Ea",
      "custreturnvarianceaccount": "148",
      "price1quantity1": "0",
      "tracklandedcost": "F",
      "copydescription": "F",
      "cost": "50.00",
      "custitem_ns_sc_ext_id_hide_qty_avl": "F",
      "excludefromsitemap": "F",
      "price6matrixfields": "price",
      "autopreferredstocklevel": "T",
      "costingmethod": "AVG",
      "lastmodifieddate": "10/29/2022 9:15 pm",
      "weightunits": "per Ea",
      "custitem_image_code": "B763451",
      "nlrole": "1064",
      "yahooproductfeed": "F",
      "quantityreorderunits": "Quantity On Hand, Reorder Point, Quantity On Order, and Quantity Committed are in Ea",
      "isgcocompliant": "T",
      "baserecordtype": "inventoryitem",
      "averagecostunits": "per Ea",
      "averagecost": "50.00",
      "keywordschange": "F",
      "hasparent": "F",
      "outofstockbehavior": "DEFAULT",
      "itemtype": "InvtPart",
      "custitem_fg_go_is_bundle": "F",
      "safetystocklevelunits": "Ea",
      "saleconversionrate": "1",
      "originalusebins": "F",
      "isspecialorderitem": "F",
      "pagetitle": "Rhinestone Blouse",
      "transferpriceunits": "per Ea",
      "haschildren": "F",
      "urlcomponent": "Rhinestone-Blouse",
      "vendormapchange": "F",
      "price2header": "price2quantity",
      "stockconversionrate": "1"
    },
    "sublists": {
      "sitecategory": {
        "currentline": {
          "category": "",
          "categorydescription": "",
          "isdefault": "",
          "sys_id": "-3840635357253803",
          "sys_parentid": "3840635349119410",
          "website": "",
          "#": "3"
        },
        "line 1": {
          "category": "-130",
          "category_display": "Home",
          "categorydescription": null,
          "isdefault": "F",
          "sys_id": "3840635349238809",
          "sys_parentid": "3840635349119410",
          "website": "3"
        },
        "line 2": {
          "category": "-142",
          "category_display": "Home",
          "categorydescription": null,
          "isdefault": "F",
          "sys_id": "3840635349229757",
          "sys_parentid": "3840635349119410",
          "website": "6"
        }
      },
      "quantitypricinglevel": {},
      "itemvendor": {
        "currentline": {
          "preferredvendor": "",
          "purchaseprice": "",
          "schedule": "",
          "subsidiary": "",
          "sys_id": "-3840635359206013",
          "sys_parentid": "3840635349119410",
          "vendor": "",
          "vendorcode": "",
          "vendorcurrencyid": "",
          "vendorcurrencyname": "",
          "vendorprices": "",
          "#": "1"
        }
      },
      "urlcomponentaliases": {
        "currentline": {
          "alias": "",
          "sys_id": "-3840635357231853",
          "sys_parentid": "3840635349119410",
          "#": "1"
        }
      },
      "commercecategories": {
        "line 1": {
          "catalogid": "2",
          "catalogname": "SS4C B2C - Single Solution Catalog",
          "categoryid": "69",
          "categoryname": "Apparel",
          "enddate": null,
          "isinactive": "No",
          "primarycategory": "No",
          "startdate": null,
          "sys_id": "3840635349219507",
          "sys_parentid": "3840635349119410",
          "websiteid": "3",
          "websitename": "SC B2C Threads"
        },
        "line 2": {
          "catalogid": "2",
          "catalogname": "SS4C B2C - Single Solution Catalog",
          "categoryid": "3",
          "categoryname": "Women",
          "enddate": null,
          "isinactive": "No",
          "primarycategory": "No",
          "startdate": null,
          "sys_id": "3840635349207353",
          "sys_parentid": "3840635349119410",
          "websiteid": "3",
          "websitename": "SC B2C Threads"
        },
        "line 3": {
          "catalogid": "2",
          "catalogname": "SS4C B2C - Single Solution Catalog",
          "categoryid": "12",
          "categoryname": "Shirts",
          "enddate": null,
          "isinactive": "No",
          "primarycategory": "No",
          "startdate": null,
          "sys_id": "3840635349171997",
          "sys_parentid": "3840635349119410",
          "websiteid": "3",
          "websitename": "SC B2C Threads"
        }
      },
      "itemimages": {
        "line 1": {
          "altTagCaption": null,
          "name": "B763451.media.blouse.jpg",
          "nkey": "229551",
          "siteList": "229551",
          "sys_id": "3840635349246702",
          "sys_parentid": "3840635349119410"
        }
      },
      "price5": {
        "line 1": {
          "currency": "5",
          "discount": null,
          "discountdisplay": null,
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "1",
          "pricelevelname": "Base Price",
          "sys_id": "3840635349310032",
          "sys_parentid": "3840635349119410"
        },
        "line 2": {
          "currency": "5",
          "discount": "-10.0%",
          "discountdisplay": "-10.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "2",
          "pricelevelname": "Alternate Price 1",
          "sys_id": "3840635349298274",
          "sys_parentid": "3840635349119410"
        },
        "line 3": {
          "currency": "5",
          "discount": "-15.0%",
          "discountdisplay": "-15.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "3",
          "pricelevelname": "Alternate Price 2",
          "sys_id": "3840635349286437",
          "sys_parentid": "3840635349119410"
        },
        "line 4": {
          "currency": "5",
          "discount": "-20.0%",
          "discountdisplay": "-20.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "4",
          "pricelevelname": "Alternate Price 3",
          "sys_id": "3840635349274393",
          "sys_parentid": "3840635349119410"
        },
        "line 5": {
          "currency": "5",
          "discount": "-5.0%",
          "discountdisplay": "-5.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "5",
          "pricelevelname": "Online Price",
          "sys_id": "3840635349260700",
          "sys_parentid": "3840635349119410"
        }
      },
      "price6": {
        "line 1": {
          "currency": "6",
          "discount": null,
          "discountdisplay": null,
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "1",
          "pricelevelname": "Base Price",
          "sys_id": "3840635349368371",
          "sys_parentid": "3840635349119410"
        },
        "line 2": {
          "currency": "6",
          "discount": "-10.0%",
          "discountdisplay": "-10.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "2",
          "pricelevelname": "Alternate Price 1",
          "sys_id": "3840635349356870",
          "sys_parentid": "3840635349119410"
        },
        "line 3": {
          "currency": "6",
          "discount": "-15.0%",
          "discountdisplay": "-15.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "3",
          "pricelevelname": "Alternate Price 2",
          "sys_id": "3840635349345319",
          "sys_parentid": "3840635349119410"
        },
        "line 4": {
          "currency": "6",
          "discount": "-20.0%",
          "discountdisplay": "-20.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "4",
          "pricelevelname": "Alternate Price 3",
          "sys_id": "3840635349333510",
          "sys_parentid": "3840635349119410"
        },
        "line 5": {
          "currency": "6",
          "discount": "-5.0%",
          "discountdisplay": "-5.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "5",
          "pricelevelname": "Online Price",
          "sys_id": "3840635349321584",
          "sys_parentid": "3840635349119410"
        }
      },
      "price3": {
        "line 1": {
          "currency": "3",
          "discount": null,
          "discountdisplay": null,
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "1",
          "pricelevelname": "Base Price",
          "sys_id": "3840635349427206",
          "sys_parentid": "3840635349119410"
        },
        "line 2": {
          "currency": "3",
          "discount": "-10.0%",
          "discountdisplay": "-10.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "2",
          "pricelevelname": "Alternate Price 1",
          "sys_id": "3840635349415459",
          "sys_parentid": "3840635349119410"
        },
        "line 3": {
          "currency": "3",
          "discount": "-15.0%",
          "discountdisplay": "-15.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "3",
          "pricelevelname": "Alternate Price 2",
          "sys_id": "3840635349403599",
          "sys_parentid": "3840635349119410"
        },
        "line 4": {
          "currency": "3",
          "discount": "-20.0%",
          "discountdisplay": "-20.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "4",
          "pricelevelname": "Alternate Price 3",
          "sys_id": "3840635349391555",
          "sys_parentid": "3840635349119410"
        },
        "line 5": {
          "currency": "3",
          "discount": "-5.0%",
          "discountdisplay": "-5.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "5",
          "pricelevelname": "Online Price",
          "sys_id": "3840635349379702",
          "sys_parentid": "3840635349119410"
        }
      },
      "price4": {
        "line 1": {
          "currency": "4",
          "discount": null,
          "discountdisplay": null,
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "1",
          "pricelevelname": "Base Price",
          "sys_id": "3840635349497061",
          "sys_parentid": "3840635349119410"
        },
        "line 2": {
          "currency": "4",
          "discount": "-10.0%",
          "discountdisplay": "-10.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "2",
          "pricelevelname": "Alternate Price 1",
          "sys_id": "3840635349485638",
          "sys_parentid": "3840635349119410"
        },
        "line 3": {
          "currency": "4",
          "discount": "-15.0%",
          "discountdisplay": "-15.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "3",
          "pricelevelname": "Alternate Price 2",
          "sys_id": "3840635349473954",
          "sys_parentid": "3840635349119410"
        },
        "line 4": {
          "currency": "4",
          "discount": "-20.0%",
          "discountdisplay": "-20.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "4",
          "pricelevelname": "Alternate Price 3",
          "sys_id": "3840635349450147",
          "sys_parentid": "3840635349119410"
        },
        "line 5": {
          "currency": "4",
          "discount": "-5.0%",
          "discountdisplay": "-5.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "5",
          "pricelevelname": "Online Price",
          "sys_id": "3840635349438099",
          "sys_parentid": "3840635349119410"
        }
      },
      "presentationitem": {
        "currentline": {
          "baseprice": "",
          "description": "",
          "item": "",
          "itemtype": "",
          "onlineprice": "",
          "presentationitem": "",
          "presitemid": "",
          "presitemurl": "",
          "presitemurlperm": "",
          "sys_id": "-3840635357210620",
          "sys_parentid": "3840635349119410",
          "#": "1"
        }
      },
      "price1": {
        "line 1": {
          "currency": "1",
          "discount": null,
          "discountdisplay": null,
          "price[1]": "70.00",
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "1",
          "pricelevelname": "Base Price",
          "sys_id": "3840635349570731",
          "sys_parentid": "3840635349119410"
        },
        "line 2": {
          "currency": "1",
          "discount": "-10.0%",
          "discountdisplay": "-10.0%",
          "price[1]": "63.00",
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "2",
          "pricelevelname": "Alternate Price 1",
          "sys_id": "3840635349559041",
          "sys_parentid": "3840635349119410"
        },
        "line 3": {
          "currency": "1",
          "discount": "-15.0%",
          "discountdisplay": "-15.0%",
          "price[1]": "59.50",
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "3",
          "pricelevelname": "Alternate Price 2",
          "sys_id": "3840635349535069",
          "sys_parentid": "3840635349119410"
        },
        "line 4": {
          "currency": "1",
          "discount": "-20.0%",
          "discountdisplay": "-20.0%",
          "price[1]": "56.00",
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "4",
          "pricelevelname": "Alternate Price 3",
          "sys_id": "3840635349522992",
          "sys_parentid": "3840635349119410"
        },
        "line 5": {
          "currency": "1",
          "discount": "-5.0%",
          "discountdisplay": "-5.0%",
          "price[1]": "66.50",
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "5",
          "pricelevelname": "Online Price",
          "sys_id": "3840635349509960",
          "sys_parentid": "3840635349119410"
        }
      },
      "price2": {
        "line 1": {
          "currency": "2",
          "discount": null,
          "discountdisplay": null,
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "1",
          "pricelevelname": "Base Price",
          "sys_id": "3840635349632196",
          "sys_parentid": "3840635349119410"
        },
        "line 2": {
          "currency": "2",
          "discount": "-10.0%",
          "discountdisplay": "-10.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "2",
          "pricelevelname": "Alternate Price 1",
          "sys_id": "3840635349617379",
          "sys_parentid": "3840635349119410"
        },
        "line 3": {
          "currency": "2",
          "discount": "-15.0%",
          "discountdisplay": "-15.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "3",
          "pricelevelname": "Alternate Price 2",
          "sys_id": "3840635349605848",
          "sys_parentid": "3840635349119410"
        },
        "line 4": {
          "currency": "2",
          "discount": "-20.0%",
          "discountdisplay": "-20.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "4",
          "pricelevelname": "Alternate Price 3",
          "sys_id": "3840635349594201",
          "sys_parentid": "3840635349119410"
        },
        "line 5": {
          "currency": "2",
          "discount": "-5.0%",
          "discountdisplay": "-5.0%",
          "price[1]": null,
          "price[2]": null,
          "price[3]": null,
          "price[4]": null,
          "price[5]": null,
          "pricelevel": "5",
          "pricelevelname": "Online Price",
          "sys_id": "3840635349582169",
          "sys_parentid": "3840635349119410"
        }
      }
    }
  }
}
About Me

Hello, I'm Tim Dietrich. I develop custom software for businesses that are running on NetSuite, including mobile apps, Web portals, Web APIs, and more.

I'm the developer of several popular NetSuite open source solutions, including the SuiteQL Query Tool, SuiteAPI, and more.

I founded SuiteStep, a NetSuite development studio, to provide custom software and AI solutions - and continue pushing the boundaries of what's possible on the NetSuite platform.

Copyright © 2025 Tim Dietrich.