NetSuite
Stream NetSuite records into Streamkap using OAuth 2.0 with a certificate, or an existing token-based integration
The NetSuite source pulls records — customers, vendors, items, transactions, and more — out of your NetSuite account and streams them into Kafka topics, one topic per record type. Records land flat in your destination like any other Streamkap source, so every existing destination consumes them unchanged.
How It Works
Streamkap queries your account with SuiteQL, NetSuite’s SQL interface over SuiteTalk REST. Each selected record type becomes one query and one topic, and each poll asks only for rows changed since the previous poll.
Streamkap uses SuiteQL rather than the REST record service because the record service returns a list of links — one extra API call per row — and cannot filter or sort on the server. SuiteQL returns whole rows in one call and can ask NetSuite for only what changed, which is what makes incremental streaming possible.
Authentication options
NetSuite offers two, and the form opens on the first.
OAuth 2.0 with a certificate (recommended)
Streamkap signs each token request with a private key whose public certificate you upload to NetSuite. There is no shared secret to leak or rotate on a schedule, and it is the method Oracle recommends for server-to-server integrations.
Token-based authentication (TBA)
The older method, based on OAuth 1.0a. Choose it only if you already have a working TBA integration you want to point at Streamkap.
Prerequisites
- A NetSuite account, and a role with administrator access to create integration records.
- The SuiteCloud features enabled — see below.
- OpenSSL, or any tool that can generate a key pair, if you are using the certificate method.
NetSuite Setup
1. Enable the required features
Go to Setup → Company → Enable Features → SuiteCloud and enable:
- REST Web Services
- OAuth 2.0 (for the certificate method) or Token-Based Authentication (for TBA)
2. Find your Account ID
Go to Setup → Company → Company Information. Your Account ID looks like TSTDRV1234567 or 1234567; a sandbox adds a suffix, 1234567_SB1.
3. Generate a key pair (certificate method)
Run this locally. The private key never leaves your machine except to be pasted into Streamkap, where it is encrypted at rest.
openssl req -new -x509 -newkey rsa:2048 -sha256 -days 730 -nodes \
-keyout netsuite-private.pem -out netsuite-public.pem -subj "/CN=streamkap"
An EC P-256 key works too if you prefer one; Streamkap detects which you used and signs accordingly.
4. Create the integration record
Go to Setup → Integration → Manage Integrations → New.
- Give it a name, for example
Streamkap. - Under OAuth 2.0, tick Client Credentials (machine to machine) Grant and the REST Web Services scope.
- Untick Token-Based Authentication and Authorization Code Grant — Streamkap does not use either in this mode.
- Save, then copy the Client ID (also called Consumer Key). NetSuite shows it once.
For TBA instead: tick Token-Based Authentication, save, and copy the Consumer Key and Consumer Secret.
5. Map the certificate (certificate method)
Go to Setup → Integration → OAuth 2.0 Client Credentials (M2M) Setup → Create New.
- Pick the integration record from step 4, the role you prepared in step 6, and the entity that role belongs to.
- Upload
netsuite-public.pem. - Save, then copy the Certificate ID.
6. Grant the role its permissions
The role you mapped above needs:
- Setup → REST Web Services
- Setup → SuiteAnalytics Workbook
- Setup → Log in using OAuth 2.0 Access Tokens (or Access Tokens for TBA)
- View access to every record type you plan to stream
Streamkap checks each record type you select before saving the source, so a missing permission is reported against that record type rather than failing quietly later.
7. Create an access token (TBA only)
Go to Setup → Users/Roles → Access Tokens → New, pick the integration and role, and copy the Token ID and Token Secret.
Streamkap Setup
Follow these steps to configure your new connector:
1. Create the Source
- Navigate to Add Connectors.
- Choose NetSuite.
2. Connection Settings (Auth tab)
- Name: A name for your connector (for example
netsuite-prod). - Account ID: From step 2, exactly as NetSuite shows it.
- Authentication: OAuth 2.0 with a certificate (the default) or Token-based authentication. The rest of the form follows your choice.
OAuth 2.0 with a certificate
- Client ID: The Client ID from your integration record.
- Certificate ID: From the M2M setup screen.
- Private Key: The contents of
netsuite-private.pem, including theBEGINandENDlines. Stored encrypted at rest and never shown again. - Private Key Passphrase: Only if you protected the key with one.
Token-based authentication
- Consumer Key and Consumer Secret from the integration record.
- Token ID and Token Secret from the access token.
3. Settings tab
- Records: The record types to stream. Each becomes its own topic.
- Backfill start date (optional): How far back the first sync reaches. Leave it empty to load everything.
4. Review and create
Check the summary and click Create. Streamkap verifies your credentials and confirms it can read each record type you selected, then the source moves to Active.
Editing the Source
Rotating the certificate
Upload a new certificate in NetSuite, then edit the source and paste the new private key and Certificate ID. Streaming continues from where it left off.
Adding records
Edit the source and add record types to the Records field. New topics appear for the new records; existing ones keep their position and are not re-read.
Sending Topics to a Destination
API sources do not use pipelines. Use Send to destination from the Topics page, the source’s Destinations tab, or a destination’s Add topics dialog. See API sources.
Supported Records
Streamkap offers these record types:
| Entities | Items and transactions | Accounting and dimensions |
|---|---|---|
| Customer | Item | Account |
| Vendor | Transaction | Subsidiary |
| Contact | Department | |
| Employee | Location | |
| Partner | Classification | |
| Currency | ||
| Accounting Period |
Transaction covers every transaction type — invoices, sales orders, purchase orders and the rest — in one topic, with a type column identifying each row. NetSuite models them as one table, so Streamkap follows suit.
Custom records
Custom records are supported. Enter the record’s SuiteQL table name, which starts with customrecord, for example customrecord_project_phase. Streamkap verifies it before saving.
Behavior & Limits
Incremental sync
Each poll asks NetSuite for rows whose last-modified timestamp is at or after the previous poll’s high-water mark. The boundary is re-read each time and duplicates removed, so a row modified in the same second as the cutoff is never skipped.
An extra column
Every row carries an additional streamkap_lastmodified column alongside your record’s own fields. NetSuite returns dates in your account’s display format by default, which cannot be compared reliably, so Streamkap asks for a second copy of the timestamp in a fixed format and uses that to track progress. It is safe to ignore, and safe to use.
Every value arrives as text. NetSuite’s query service returns numbers as strings — a record’s id is "101", not 101 — and booleans as "T" or "F" rather than true/false. Streamkap passes rows through as NetSuite sends them, so that is what your destination receives: columns created from these rows are string-typed, and downstream models should cast them rather than assume a numeric or boolean type.
Deletes
Streamkap periodically reads NetSuite’s deleted-records log and writes a delete marker for each deleted row — a record carrying __deleted = true, not an empty Kafka tombstone — and your destination removes the row when it applies it. Every deletion is confirmed against the live record first, so a record that was deleted and recreated under the same internal ID is never removed by mistake.
Delete markers cover the standard record types. Custom records do not get them: NetSuite’s deleted-records log identifies a custom record by its script ID rather than its table name, so those deletions cannot be matched reliably and are left out rather than guessed at.
Rate limits
NetSuite limits how many API requests an account runs at once, based on your service tier and any SuiteCloud Plus licences. Streamkap uses a single connection per source and paces its requests, so it does not compete with your other integrations.
Record volume
A single poll reads up to 10,000 records, then continues from that point on the next poll. Large initial loads therefore arrive over several polls rather than in one long run.
Troubleshooting
“NetSuite rejected the integration’s client assertion” — the Client ID, Certificate ID, or private key does not match what NetSuite has. Check the Certificate ID on the M2M setup screen, and that the certificate has not expired or been rotated.
“NetSuite private key could not be read” — the key was not pasted whole. Include the BEGIN and END lines, and supply the passphrase if the key has one.
A record type is rejected when you save — the message names it. Either the role lacks View access, or that record type has no last-modified timestamp and cannot be streamed incrementally. Grant the permission, or remove that record from the selection.
Nothing arrives after the source goes Active — confirm the records you selected have rows modified since your backfill start date. A source with no recent changes is idle, not broken.