What this audit checks
Authentication & access
- Token URL resolves against the per-merchant account-segmented host https://.suitetalk.api.netsuite.com (production accountid, not a _SB1 sandbox)
- Auth flow confirmed at onboarding - TBA (HMAC-SHA256 over consumer_key + consumer_secret + token_id + token_secret) OR OAuth2 refresh-token flow - and the matching credential fields are populated
- rest_webservices scope granted on the Integration record and the role tied to the token has REST permission
- Concurrent-request budget respected (typically 5 concurrent per Integration record) so high-volume record pulls do not 429
GL health
- Open transactions in PENDING_APPROVAL or REJECTED status below 50 (spike = SuiteScript integration error or broken approval-routing rule)
- Zero imbalanced transactions persisting (NetSuite rejects imbalanced postings; persistence = calling-side integration logic broken)
- SuiteScript execution errors below 10 in the last 24h (record-save failures block transactions silently inside background scripts)
- Manual JournalEntry transactions under 25% of total postings over 30d (controls gap if higher)
AP/AR cycle
- AR aging 60+ days below 15% of open receivables, segmented by Subsidiary on OneWorld accounts
- DSO under 60 days and not rising more than 10 days vsP
- AP aging 60+ days below 30% of open payables
- Customers on credit hold (onCreditHold ON or AUTO) reviewed; sudden growth flags collection or terms breakdown
Inventory reconciliation
- NetSuite locationquantityavailable vs ecom availability variance below 5% on top-velocity SKUs (itemid = sku)
- No InventoryItem locationquantityavailable gone negative in any Location (double-posting or fulfilment-sync error)
- Items below reorder point flagged so reorder happens before stockout
- Slow-moving inventory (no movement >90d) under 10% of on-hand inventory value
Period close
- Accounting period close not past deadline (more than 5 days overdue blocks OneWorld consolidation)
- Open reconciliation items cleared before the close date
- Accrual reversals from the last close within expected range (>10 signals manual close churn)
- Period close on-time rate at or above 90% over the trailing 12 months
Cross-channel: revenue reconciliation
- Ecom orders have a matching NetSuite transaction (Cash Sale / Invoice) with externalid set within 7d (sibling = bigcommerce/shopify/adobe_commerce.order); unmatched = silently failing order-import SuiteScript
- Ecom customers with completed orders present in NetSuite CustomerMaster by email (no Cash Sale / Invoice posting gap), with Subsidiary set on OneWorld accounts
- AR aging on customers with active ecom orders (credit-control gap: ordering while past due; should auto-flag onCreditHold)
- SKUs with NetSuite-vs-ecom location-level inventory drift >5% surfaced to prevent multi-channel overselling
Severity thresholds
| Signal | Warn | Critical |
|---|---|---|
open_journal_count | 25 | 50 |
ar_aging_60d_pct | 10 | 15 |
dso_days | 45 | 60 |
inventory_variance_pct | 3 | 5 |
period_close_overdue_days | 2 | 5 |
Data sources
GET https://{accountid}.suitetalk.api.netsuite.com/services/rest/record/v1/account- Chart of accounts: number, name, type, currency for GL structureGET https://{accountid}.suitetalk.api.netsuite.com/services/rest/record/v1/transaction- Transactions: type, status, total, subsidiary, externalid for GL health + order reconciliationGET https://{accountid}.suitetalk.api.netsuite.com/services/rest/record/v1/customer- Customer master: terms, credit limit, onCreditHold, subsidiary, email for AR + drift checksGET https://{accountid}.suitetalk.api.netsuite.com/services/rest/record/v1/vendor- Vendor master: terms, subsidiary for AP cycleGET https://{accountid}.suitetalk.api.netsuite.com/services/rest/record/v1/inventoryitem- Inventory items: location-level available / on-order, cost for reconciliationPOST https://{accountid}.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token- OAuth2 token exchange (OAuth2 accounts only; TBA signs per-request in engine code)