NetSuite
11 min
connect your netsuite erp data to chord chord's netsuite connector is cost focused it pulls per transaction cost of goods sold, procurement costs, landed costs, and inventory cost movements out of netsuite and into snowflake, alongside the revenue side records needed to attribute those costs back to orders, skus, channels, and cohorts the result is true margin per order, per sku, per channel, and per cohort modeled in the same place as the rest of your stack what chord ingests from netsuite heads up the final list of datasets will be published here when the connector ships chord's netsuite ingestion is cost focused it pulls per transaction cogs, procurement costs, landed costs, and inventory cost movements alongside the sales side records needed to attribute those costs to orders, skus, channels, and cohorts reach out to your chord contact if you need the planned scope ahead of ga generate a netsuite tba credential netsuite authenticates chord using token based authentication (tba) you'll generate two pairs of credentials inside netsuite a consumer key/secret on an integration record, and a token id/secret tied to a dedicated integration user and role once you have all four values plus your account id, you'll paste them into chord hub heads up you'll need an admin role in netsuite (or a custom role with the integration application and access token permissions) to complete every step below if your user doesn't have admin access, ask a netsuite administrator at your company to either run these steps or grant your role the needed permissions first 1\ enable the required features log in to netsuite as an administrator go to setup → company → enable features open the suitecloud subtab under the manage authentication section, check token based authentication netsuite will pop up the suitecloud terms of service click i agree to continue under the suitetalk (web services) section, check rest web services click save at the top of the page you don't need to enable client suitescript or server suitescript, those are only required for restlets, which chord's netsuite connector does not use 2\ create an integration record this record gives chord its consumer key and consumer secret go to setup → integration → manage integrations → new in the name field, enter something memorable like chord connector set state to enabled under the authentication tab check token based authentication check tba issuetoken endpoint uncheck tba authorization flow (this is checked by default and chord doesn't use it) under the oauth 2 0 section, uncheck authorization code grant (also checked by default) click save heads up if you leave authorization code grant checked, netsuite will refuse to save the record and return an "invalid redirect uri" error that checkbox requires a redirect url that chord doesn't supply — uncheck it before saving after you save, netsuite shows a confirmation page with the consumer key and consumer secret for this integration these values are displayed only once copy the consumer key and consumer secret immediately and store them somewhere safe if you navigate away from this page without copying them, the only way to recover is to regenerate the pair, which invalidates the original values and breaks any integration already using them 3\ create an integration role create a dedicated role for the chord integration so you can grant the minimum permissions needed for cost focused ingestion go to setup → users/roles → manage roles → new name the role something like chord integration role optionally check web services only role so the role can never be used to log in through the netsuite ui on the permissions subtabs, add the following permissions all are read only (level view ) except the two setup permissions, which need full setup subtab log in using access tokens level full rest web services level full transactions subtab — revenue attribution backbone sales order level view invoice level view cash sale level view credit memo level view customer payment level view transactions subtab cost data (the headline scope) item fulfillment level view (this is where per line cogs posts when goods ship) find transaction level view (required for transaction record gets through rest) vendor bill level view purchase order level view item receipt level view adjust inventory level view adjust inventory worksheet level view lists subtab customers level view items level view vendors level view subsidiaries level view accounts level view (needed to resolve the cogs gl account references on item records and transactions) departments level view classes level view locations level view reports subtab financial statement level view landed cost templates (only if your account uses landed cost tracking) netsuite doesn't expose a single "landed cost" permission under the lists subtab landed cost amounts already flow through chord on the item receipt and vendor bill records the role can read if you also want chord to pull the landed cost templates themselves (the rules that allocate freight, duty, and handling across receipt lines), grant the following on the custom record subtab, otherwise skip them landed cost template level view landed cost template detail level view landed cost template mapping level view click save 4\ create the integration user create (or reuse) a dedicated employee record that the integration role will be assigned to we recommend a service account, not a real person's user go to lists → employees → employees → new give the employee a recognizable name like chord integration under the access subtab, check give access add the chord integration role you created in step 3 if your netsuite account is oneworld, also assign the integration employee access to every subsidiary whose data chord should ingest see the oneworld callout above click save 5\ create the access token this generates the token id and token secret tied to the user/role/integration combination go to setup → users/roles → access tokens → new application name select the integration record from step 2 ( chord connector ) user select the integration employee from step 4 role select the integration role from step 3 token name is auto populated; you can leave it or rename it click save netsuite shows the token id and token secret on the confirmation page like the consumer key/secret, these are displayed only once copy the token id and token secret immediately if you lose them, you'll need to delete the access token and create a new one — the original values cannot be retrieved 6\ find your account id go to setup → company → company information copy the value in the account id field production account ids are numeric, e g 1234567 sandbox account ids add a suffix with an underscore, e g 1234567 sb1 or 1234567 sb2 heads up in your browser url bar, netsuite normalizes the account id the underscore becomes a hyphen and uppercase letters become lowercase (e g 1234567 sb1 app netsuite com ) the chord hub credential field requires the underscore form exactly as it appears on the company information page , not the url normalized form connect the credentials in chord you should now have five values an account id, a consumer key, a consumer secret, a token id, and a token secret open chord hub and go to data sources → add source pick netsuite from the data source list paste each value into the matching field account id field your numeric account id, with the sandbox underscore suffix if applicable consumer key field from the integration record consumer secret field from the integration record token id field from the access token token secret field from the access token click save chord encrypts and stores the credentials the first sync kicks off automatically when the netsuite ingestion is enabled for your tenant; subsequent syncs run on your tenant's standard ingestion schedule troubleshooting what does the validate step actually check? at the moment, the save step in chord hub stores your netsuite credentials but does not make a live call against netsuite to verify them the first real check happens when the ingestion job runs against your tenant, if any of the five values are wrong, the failure will surface in the ingestion logs rather than at credential save time if you've just connected netsuite and the first sync hasn't run yet, ask your chord contact to trigger a manual ingestion so you can confirm the credentials early i'm getting an "invalid redirect uri" error when saving the integration record this happens when authorization code grant is left checked under the oauth 2 0 section of the integration record chord uses tba, not oauth 2 0, so that checkbox isn't relevant, uncheck it (and also uncheck tba authorization flow while you're there) and save again my sandbox account id isn't being accepted netsuite displays sandbox account ids with an underscore (e g 1234567 sb1 ) on the company information page, but the same id appears with a hyphen and lowercase letters in your browser url (e g 1234567 sb1 app netsuite com ) use the underscore form from company information, not the url form also double check the trailing digit sb1 vs sb2 matters if your company has multiple sandboxes i lost the consumer key/secret or token id/secret can i retrieve them? no netsuite displays each pair exactly once on the confirmation page after you save to recover, you'll need to regenerate for consumer key/secret open the integration record ( setup → integration → manage integrations ), click reset credentials , and save the previous consumer key/secret stops working immediately for token id/secret delete the access token under setup → users/roles → access tokens and create a new one then update chord hub with the new values do tba credentials expire? no netsuite tba tokens stay valid until they're explicitly revoked or until the underlying user/role is disabled if a previously working credential suddenly fails, the most common causes are the integration record was disabled, the access token was revoked, the integration user was disabled, or the role's permissions were changed check those four things in order before assuming the token itself is broken i'm on oneworld and some subsidiaries are missing from the data netsuite's rest api silently filters every response by the integration user's subsidiary scope, so a subsidiary the integration employee can't see will simply not appear in the data there's no error to catch open the integration employee record ( lists → employees → employees ), and on the access subtab confirm that every subsidiary whose data chord should ingest is selected see the oneworld callout in section 3 for the full pattern cogs values look low or missing on recent orders in netsuite, cogs posts when goods ship via item fulfillment , not when the sales order is created or invoiced if an order is still pending fulfillment, its cogs won't yet be in the data, that's expected and will resolve once fulfillment is recorded if cogs looks systematically empty across many fulfilled orders, the most likely cause is that the item fulfillment view permission was missed when the integration role was set up only the sales side will land in chord and cogs will be absent entirely re open the integration role and confirm item fulfillment is present on the transactions subtab at level view before assuming a data issue how do i rotate the credentials? the cleanest rotation is at the access token level, it lets you cycle credentials without touching the integration record or user in netsuite, go to setup → users/roles → access tokens → new and create a new token pointing at the same application, user, and role paste the new token id and token secret into chord hub and save once you've confirmed the next sync runs cleanly with the new token, delete the old token in netsuite if you need to rotate the consumer key/secret as well (e g after a suspected leak), open the integration record and click reset credentials , then update chord hub with all four new values together who can see the credentials after they're saved in chord? all five values are encrypted at rest in chord hub and are never displayed back in the ui you can rotate or delete them any time, but you can't view the original values once they're saved need help? if you hit a credential or connectivity issue you can't resolve, reach out to help\@chord co mailto\ help\@chord co with the exact error message we'll trace the request and tell you what's failing