The situation
A security systems integrator runs its field service desk in ServiceNow. Its customers, job sites, contacts, technicians, equipment models, stock and service contracts all live in NetSuite. Dispatchers looked up a site or a contract in one system and re-created it in the other, and the two drifted apart as soon as anything changed.
What we built
An SDF project that pushes NetSuite master data into ServiceNow tables through the ServiceNow Table API. One Map/Reduce job carries every flow, and a configuration record switches each flow on or off. The flows cover companies, site locations, manufacturers and models, contacts, technicians, items with their stock, and active and expired service contracts.
The job sends records in dependency order, so a site exists before the asset installed at it, and a company exists before its contacts. For each record it looks up the target row by the NetSuite internal id, updates the row if it finds one and creates it if not. After a successful write it stores the ServiceNow sys_id on the NetSuite record.
Technician accounts work differently. The company directory owns ServiceNow users, so the sync never creates one. It matches on email the first time and only updates after that.
A User Event on sales orders links each service order to the right project, based on the job site and the order date, so service revenue lands on the correct contract.
What it does now
A scheduled deployment runs in delta mode and picks up only records changed since the last run, with an overlap window between runs. Separate deployments of the same script run a full resync or a validation pass. Deployment parameters choose the mode, so nobody edits the shared configuration to switch.
When a run finishes, administrators get one email with a CSV of every record that was skipped or failed, and the reason. A failed record keeps an empty sys_id, which makes it easy to find and send again.
Two Suitelets support the rollout. One checks the field mappings. The other fetches each test record back from ServiceNow and shows the NetSuite and ServiceNow values side by side, field by field, with mismatches flagged.
Under the hood
- Upserts are keyed on the NetSuite internal id, with an email fallback for directory-owned users, so running a flow again never duplicates a row.
- The job refuses to update when the lookup key is missing or matches more than one row.
- Every reference field resolves because the flows run in a fixed order.
- The OAuth token is cached between calls, and a deployment switch forces a fresh one.
- Delta, full and validation modes each have their own deployment parameters.
- Scripts, custom fields and the configuration record ship together as one SDF project.