The framework the built-in connectors use
Building an integration is easy. Building one that behaves correctly when the other system is down, when somebody edits a published record, or when a run half-completes is the actual work — and it is the part the SDK exists to stop you rewriting.
What it is, and what it is not
The same connector framework the six built-in ERP integrations are written against, exposed so you can write one for a system we do not cover — a homegrown MES, a regional ERP, a customer's procurement portal.
It is not an SDK in the client-library sense. Wrapping the REST API in your language of choice is useful and it is not this: what the SDK gives you is the lifecycle, which is the part that takes months to get right and is invisible until it fails.
It is also not a way to bypass the rules. A connector written on the SDK is subject to the system-of-record matrix, the tenant predicate and change control exactly as the built-in ones are. You are extending the framework, not escaping it.
What the framework actually gives you
Six things, and each one is a place a hand-rolled integration goes wrong.
- Object and field mapping as declarative configuration rather than code, so a mapping change is a config change with a preflight rather than a deployment.
- Direction and ownership, expressed as matrix rows — which system masters each object, which way values move, and what happens when they disagree. Declaring it is what makes a conflict detectable at all.
- Triggers with defined semantics: on release, on schedule, on demand. Never “continuously”, which is how integrations end up firing during a month-end close.
- Bounded, idempotent retries. A retried run does not produce a duplicate revision, and a failed run leaves nothing behind rather than a half-written structure that looks complete to whatever reads it next.
- Reconciliation, which raises a task naming the object, the field, both values and the owner — instead of overwriting somebody's deliberate edit at two in the morning.
- Sync history, queryable, with every run attributed in the audit trail alongside human actions.
The failure it prevents
A team writes an integration to a regional ERP over the API and a scheduler. It works. Six weeks later a planner edits a published BOM in that ERP for a good reason, and the next run overwrites their edit.
It happens again, and again. By the third occurrence the site has stopped trusting the integration and is maintaining the ERP structure by hand — which is exactly the outcome the project existed to prevent, reached by a team who did everything they were asked.
Reconciliation is not hard to describe and it is genuinely hard to build: it requires resolving both sides through the same engine, diffing them properly, knowing who owns each field, and surfacing the result somewhere people actually look. The SDK exists because that work should be done once.
How it meets the rest of the product
Connectors read and write through the same domain services the interface and the agents use, so a connector cannot edit a released revision, write an ERP-mastered field, or create a change without an attributed actor. The constraints live in the services rather than in the connector.
Connector runs establish the same tenant context a user request does, so the isolation predicate applies to sync work. Background jobs are where isolation usually leaks, and a custom connector is precisely where somebody might otherwise be tempted to hold broad credentials and iterate.
Every run is an attributed audit row naming the connector, the run and the direction — including yours. “Which system changed this value” has the same answer for a connector you wrote as for one we did.
Publication triggered by change release happens inside the atomic release transaction, so a custom connector gets the same guarantee: the change lands completely in both systems, or in neither.
How it meets your ERP
The six built-in connectors are the reference implementations, and their source shape is the documentation. NetSuite's dated BOM Revision, SAP's Change Master with a valid-from, Acumatica's effective-start field — each shows a different way of expressing the same publication against a different target model.
Start by writing your matrix. Object by object: master, direction, trigger, conflict rule. That table is the connector's configuration at run time rather than a document, and filling it in is where the real decisions get made — before any code exists.
The commonest mistake in a custom connector is treating identity as solved. Your ERP holds items engineering never created, and matching on manufacturer part number then internal number, with unmatched surfaced for a person, is the same discipline the built-in connectors follow for the same reason.
Where the boundary is
The SDK does not let a connector define new ownership semantics. You choose which system masters an object; you do not get to make an object have two masters, or to write a field the matrix assigns elsewhere. Those constraints are enforced below the framework.
There is also no arbitrary code execution inside Manufacturing PLM. A connector runs where you run it, calling in — rather than as a plugin executing in our runtime, which would make an upgrade an archaeology exercise and put somebody else's code inside the tenant boundary.
Facts
| Gives you | The lifecycle — not a REST client wrapper |
| Mapping | Declarative config with a preflight, not code |
| Triggers | On release · on schedule · on demand — never “continuously” |
| Retries | Bounded and idempotent; a failed run leaves nothing |
| Conflicts | Raise a reconciliation task, never overwrite |
| Isolation | Runs inside the same tenant context as a request |
| Audit | Your connector's runs are attributed like ours |
| Not offered | New ownership semantics · code running in our runtime |
Frequently asked
Is this a client library?
No, and the distinction matters. Wrapping the REST API in your language is useful but easy. What the SDK gives you is the connector lifecycle — mapping, triggers, retries, reconciliation, sync history — which takes months to build correctly and stays invisible until it fails.
Why not just use the API and a scheduler?
You can, and the thing you will not build is reconciliation. It needs both sides resolved through the same engine, diffed properly, field ownership known, and the result surfaced where people look. Without it, your integration overwrites somebody's deliberate edit at 2am.
Where do I start?
With the matrix, before any code. Object by object: which system masters it, which direction values move, what triggers the move, and what happens on conflict. That table is the connector's run-time configuration, and filling it in is where the real decisions get made.
Can my connector break the ownership rules?
No. You choose which system masters an object, but you cannot give an object two masters or write a field the matrix assigns elsewhere. Those constraints are enforced below the framework, in the same domain services the interface and the agents call.
Does my code run inside Manufacturing PLM?
No. A connector runs where you run it and calls in, rather than executing as a plugin in our runtime. Arbitrary code inside the tenant boundary would make upgrades an archaeology exercise and put somebody else's failure modes inside our isolation guarantees.
Are custom connector runs audited?
Yes, identically to the built-in ones — an attributed audit row naming the connector, the run and the direction. The question of which system changed a value has the same quality of answer for a connector you wrote as for one that shipped with the product.
What is the commonest mistake?
Treating identity as a solved problem. Your ERP holds items engineering never created — packaging, freight, consumables, services — and matching on manufacturer part number then internal number, with anything unmatched surfaced for a person, is the same discipline the built-in connectors follow.