How to Sync NetSuite Item Pricing to an ERP With No Native Tile via the HTTP Connector

Build a scheduled Spojit workflow that reads current item prices from NetSuite, reshapes them to your downstream ERP's payload, and writes them to that ERP's REST API using the http connector, even when there is no native tile for that ERP.

What This Integration Does

Manufacturers and wholesalers usually treat NetSuite as the system of record for item pricing, but the warehouse, line-of-business, or legacy ERP that actually fulfills orders often has no native connector in Spojit. This workflow keeps that downstream ERP in step with NetSuite by reading the current price for each item, mapping it to the shape the downstream ERP expects, and pushing it straight to that ERP's REST API. Because the downstream system is reached through the generic http connector rather than a vendor tile, you are not blocked waiting for an integration to exist: any ERP that exposes an authenticated REST endpoint can receive master-data pushes today.

The run model is a pull-then-push on a fixed cadence. A Schedule trigger fires on cron (for example, every weekday morning), a Connector node runs a SuiteQL read against NetSuite to list item prices, a Transform reshapes the rows into the downstream ERP's price payload, a Connector node on the code connector mints a short-lived bearer token, and a final Connector node uses http-put to write each price. The workflow holds no state between runs: each run reads the live NetSuite price and overwrites the downstream value, so re-runs are idempotent. This is master-data replication from one system of record to one unsupported ERP, which is different from mirroring prices store to store between two e-commerce platforms.

Prerequisites

  • A working NetSuite connection in Spojit (added under Connections) with REST and SuiteQL access to the item and price records.
  • The downstream ERP's REST API base URL, its price-update endpoint path, and a way to authenticate (a token endpoint plus client credentials, or a static API key).
  • A mapping between your NetSuite item identifiers (for example itemid or a custom SKU field) and the downstream ERP's item keys.
  • Knowledge of which NetSuite price level you sync (for example the base price level) so your SuiteQL targets the right row.
  • A test item in the downstream ERP you can safely overwrite while validating.

Step 1: Start the workflow on a schedule

Add a Trigger node and set its type to Schedule. Enter a 5-field cron expression and an IANA timezone, for example 0 6 * * 1-5 with Australia/Sydney to run at 6am on weekdays. A single Schedule trigger can hold more than one schedule if you need both a morning and an evening sync. The trigger output is { scheduledAt }; you do not need that value downstream, it simply marks each run.

Step 2: Read current item prices from NetSuite

Add a Connector node in Direct mode, choose the netsuite connector, and select the run-suiteql tool. SuiteQL lets you join the item and price tables in one read instead of paging the record API per item. Put your query in the query field, set limit to control page size (default 100, max 1000), and use offset for pagination on large catalogs. For example, to pull the base price for active inventory items:

SELECT i.itemid AS sku, i.displayname AS name, p.unitprice AS price
FROM item i
JOIN itemprice p ON p.item = i.id
WHERE i.isinactive = 'F' AND p.pricelevel = 1
FETCH FIRST 1000 ROWS ONLY

Map the node's output to a variable such as nsPrices. Confirm the exact table and field names for your account in the NetSuite Analytics Data Source Schema Browser, since custom price levels and item subtypes vary by account.

Step 3: Reshape the rows into the downstream ERP payload

Add a Transform node to map the SuiteQL rows into the structure your downstream ERP's price endpoint expects. Read from the read step's rows (for example {{ nsPrices.items }}, matching the field your run-suiteql node exposes) and emit a clean array keyed by the downstream ERP's item identifier. A typical target shape:

{
  "prices": [
    { "itemKey": "{{ row.sku }}", "amount": "{{ row.price }}", "currency": "AUD" }
  ]
}

Keep this node focused on structure and naming only: rename sku to the downstream key, cast prices to the expected type, and drop fields the ERP does not accept. Map the result to a variable such as payload.

Step 4: Mint a bearer token with the code connector

If your downstream ERP uses OAuth client-credentials rather than a static key, add a Connector node in Direct mode on the code connector and select execute-javascript. Use it to call the ERP's token endpoint and return only the access token, so the value never has to be hand-built. For example:

const res = await fetch("https://erp.example.com/oauth/token", {
  method: "POST",
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
  body: new URLSearchParams({
    grant_type: "client_credentials",
    client_id: process.env.ERP_CLIENT_ID,
    client_secret: process.env.ERP_CLIENT_SECRET
  })
});
const json = await res.json();
return { token: json.access_token };

Map the output to a variable such as auth so you can reference {{ auth.token }} in the next step. If your ERP instead uses a static API key, skip this step and pass the key directly in the request header in Step 5.

Step 5: Write the prices to the ERP via http-put

Add a Connector node in Direct mode on the http connector and select http-put. Set the url to your ERP's price endpoint, for example https://erp.example.com/api/v1/item-prices. Add an Authorization header of Bearer {{ auth.token }} (or your static API key) and a Content-Type of application/json. Set the request body to your mapped payload, {{ payload }}. If the ERP requires one item per request instead of a batch, wrap this node in a Loop node set to ForEach over {{ payload.prices }} and send a single-item body each iteration. Use http-patch instead of http-put if the ERP expects partial updates rather than full replacement.

Step 6: Confirm the response and alert on failure

Add a Condition node that checks the http step's response status (for example, that {{ erpResult.status }} is below 300). On the false branch, add a Send Email node to notify your operations inbox with the failing item keys in the body, so a rejected price push does not pass silently. Send Email uses Spojit's built-in mail service and needs no connection; the recipient must be on your org allowlist under Settings > General > Email recipients. If you want a single channel for all sync failures, route the alert through a Subworkflow node that wraps your standard notification logic instead.

Tips

  • Page large catalogs: SuiteQL caps at 1000 rows per call, so for big item lists use limit and offset in run-suiteql, or wrap the read and push in a Loop that advances the offset until a short page returns.
  • Batch where the ERP allows it: one http-put with an array of prices is far faster and cheaper than a per-item Loop. Only fall back to per-item calls when the API requires it.
  • Keep the token fresh: mint it inside the run with execute-javascript rather than storing a long-lived token, so an expired credential cannot cause silent rejects.
  • Ask Miraxa, the intelligent layer across your automation, to scaffold this graph from a sentence, then fine-tune fields in the properties panel: "Build a scheduled workflow that runs SuiteQL on NetSuite, transforms the rows, and sends them to an http-put on my ERP's REST API."

Common Pitfalls

  • Wrong price level: itemprice holds multiple levels per item. If you omit a pricelevel filter you will push duplicate or wrong rows. Pin the level explicitly in the SuiteQL.
  • Schema drift in SuiteQL: custom item subtypes and custom price fields differ per NetSuite account. Verify table and column names in the Schema Browser before relying on the query.
  • Currency and rounding: NetSuite may store more decimal places than the ERP accepts. Cast and round in the Transform node so the ERP does not reject the body.
  • PUT versus PATCH semantics: http-put typically replaces the full resource. If your ERP treats a partial PUT as "clear the missing fields", switch to http-patch to avoid wiping unrelated attributes.
  • Timezone surprises: the Schedule trigger uses the IANA timezone you set, not the viewer's clock. Confirm the cron fires when you expect during daylight-saving changes.

Testing

Before turning the schedule on, narrow the SuiteQL to a single known item by adding a WHERE i.itemid = 'TEST-SKU' clause, then run the workflow with the Run button. Inspect each step in the execution log: confirm run-suiteql returned the expected price, the Transform produced the exact downstream shape, the code step returned a token, and the http-put response status is in the 2xx range. Verify the price actually changed in the downstream ERP for that one item. Once the single-item path is correct, widen the query, raise limit, and enable the schedule.

Learn More

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.