Infor LN Web Services Development
If you already run Infor LN and your team is past the “what is a web service” stage, this article is for you. It walks through how Infor LN actually exposes business logic over SOAP and REST, what decisions you make when modeling a BDE or BOD interface in LN Studio, how the Connector for Web Services (C4WS) and Infor ION API fit together, and where most integration projects lose time. Every technical claim below is drawn from Infor’s own documentation: the Infor Enterprise Server Connector for Web Services Administration and User Guide, the Infor LN Studio Integration Development Guide, and the Infor LN Configuration Guide for Infor ION API. No third party blogs, no aggregator research, no guesswork.
The two interface types you are actually choosing between
Before writing a single line of integration code, every Infor LN web services project makes one foundational decision: will the business object expose a BDE interface or a BOD interface. This is not a minor technical detail. It determines which transport layer you use, which tooling applies, and how the object behaves at runtime.
A Business Data Entity, or BDE, is a synchronous, request and response interface. A client sends a request such as List, Show, Create, or Change, and the business object replies immediately with a result. This is the model used when an external application needs to query or update LN data on demand, the way a procurement portal might look up a purchase order or a customer self-service site might check order status.
A Business Object Document, or BOD, interface follows the OAGIS standard and is event driven. Instead of a client asking for data, LN publishes an event, such as a Sync or Process BOD, when something changes inside the application, and that BOD is routed asynchronously through Infor ION to whatever system is listening. A business object with a BOD interface can still expose protected BDE methods internally, but the public contract is asynchronous and message based.
This split exists for a structural reason. Before Enterprise Server 8.3, business objects were modeled in the Business Object Repository, which only supported BDE-style synchronous methods. From 8.4.2 onward, LN Studio is the tool of record, and it is the only path that supports BOD modeling. If your current implementation still lives in the BOR, it is functionally frozen to synchronous, request driven integration patterns, and migrating to BOD-based event publishing requires moving the object into LN Studio first.
For teams maintaining older BDE-only integrations who are now being asked to support real-time event flows into Infor ION, this is usually the first wall they hit, and it is worth confirming early which generation of tooling actually produced the business object you are extending.
What LN Studio actually generates when you model a BII
A Business Interface Definition, or BID, is the abstract shape of the interface, the components, attributes, and methods, independent of any one application. The Business Interface Implementation, or BII, is where you map that abstract shape onto actual LN tables, columns, and business logic. When you generate the runtime from a BII, LN Studio creates two libraries on the application server, named from an eight character implementation identifier such as ppmmm123: a public library, ppmmmbl123sb00, and a protected library, ppmmmbl123st00. The public library handles the externally exposed methods and is what the WSDL describes; the protected library exposes the same operations to other LN code through a typed function interface rather than XML.
This separation matters in practice because it is also where the WSDL for the Connector for Web Services originates. WSDL is only available in LN for business objects that were generated from LN Studio, not from the BOR. So if a developer asks why a particular legacy business object cannot be deployed through C4WS, the honest answer is almost always that it predates LN Studio generation and needs to be remodeled before a WSDL exists for it at all.
A few modeling constraints from the official Integration Development Guide consistently catch developers off guard:
Identifying attributes on a component mapped to a table must map to the identifying columns of that table, and for aggregated components, the aggregation relation must use the parent’s identifying columns. Get this wrong and the generator either refuses to build the implementation or, worse, builds something that behaves unpredictably under concurrent access.
Repeatable attributes, what LN calls attributes with “dimensions,” cannot be mapped directly to separate rows of a child table. If you need an Order.note attribute that maps to multiple rows in an OrderNotes table, you cannot do a one-to-one mapping; you need an on-get and on-set hook that reads and writes through the table’s DAL manually. This single rule explains a large share of “why is my array field not populating” support tickets.
Method arguments cannot use scope “unknown,” “result set,” or “return” in LN, and controlling attributes cannot be used as method arguments except for the standard controlling attributes of standard methods. These are LN-specific restrictions that do not exist in the generic BID modeling layer, so a BID imported from another application server’s implementation can fail LN-specific validation even though it looked fine elsewhere.
Building web services in Infor LN and stuck choosing between BDE and BOD?
Sama Consulting Inc. helps you model BDE and BOD interfaces in LN Studio, deploy them through the Connector for Web Services and Infor ION API, and migrate legacy BOR objects so your synchronous and event-driven integrations both hold up in production.
Hooks: where the actual business logic lives
The BID and BII define structure, but hooks are where you write behavior. LN Studio supports before, on, and after hooks for both get and set operations on attributes, plus before, on, and after hooks for entire methods. Hook code is written in the same scripting language used in LN Enterprise Server 8 libraries, and each hook body must either return(0) for success or call dal.set.error.message() and return(DALHOOKERROR) on failure.
A detail that trips up developers coming from other ERP scripting environments: in an on-set or on-get hook, you may only reference the attributes explicitly modeled as “used attributes” for that specific attribute implementation. You cannot reach into arbitrary other fields from inside a hook. If your calculation genuinely needs five other fields, all five need to be declared as used attributes in the BII model first, not just referenced ad hoc in code.
Default conversions are handled automatically for several standard data type pairs, boolean to long or enumerate, UTC date-time to ISO 8601 string, enumerate strings, text columns, and numeric to string. You only need a conversion hook when you are deviating from these standard mappings, and the documentation is explicit that conversion hooks carry a performance cost: a filter on a calculated or converted value cannot be pushed down to the database, so LN ends up reading more rows than necessary and post filtering in memory. If a List or Show operation against a large transaction table is unexpectedly slow, an unindexed conversion or calculated attribute in the filter path is a common root cause, and it pairs with the kind of query and index tuning work that often follows a slow integration rollout.
Concurrency control with checksums
Because BDE calls do not hold a database lock the way an interactive LN session does, there is a real risk that two systems modify the same record between a Show and a subsequent Change. Infor’s documented mitigation is a checksum mechanism. For each component with a Change method, LN Studio generates a CalculateChecksum function based on the concatenated values of every table field linked to an attribute implementation. You model a calculated checksum attribute, populate it in the on-get hook by calling that generated function, and then in the BeforeExecute hook for Change you compare the checksum supplied in the incoming request against a freshly calculated one. If they differ, the hook sets an error message and cancels the request, signaling the caller that the record changed underneath them and a fresh Show is required.
This is the supported pattern for any integration where two channels, say an LN UI user and a portal sending automated Change requests, might race against the same record. Skipping it does not cause an immediate failure; it causes silent data loss the first time a timing collision actually happens, which is exactly the kind of defect that is invisible in testing and expensive in production.
Customizing standard business objects without breaking upgrades
A recurring problem for LN shops is wanting to expose a custom field, either a normal customization column or a Customer-Defined Field configured through the Customer-Defined Fields session, through a standard BDE or BOD without forking the standard interface. Infor’s documented answer is the customization library. You create a new library using the cc suffix instead of sb or st, in your customization VRC, and inside it call addTableField() or addCdfField() for each column you want surfaced, specifying the element name, table code, column name, and data type, which must be one of String, Integer, Numeric, Date, DateOnly, or Checkbox.
At runtime this custom data is automatically included in BDE List and Show responses and in events or BODs published through the ShowAndPublish family of methods, landing inside the UserArea element (or whichever element the standard business interface designated for customization) as NameValue properties prefixed with ln.cust. It is not handled for methods with a specific batch implementation through an on-execute hook, and it will not appear if the underlying database row does not exist, which matters for components mapped across multiple tables.
The practical payoff is upgrade safety. A new feature pack can ship a new version of the standard BDE or BOD, and as long as the interface change does not remove the component or stop using the table that holds your custom data, your customization library keeps working without modification. This is the same upgrade-safe extension principle that applies to custom OData and REST API development in LN Studio, where custom logic belongs in the Extensions package rather than inside generated standard code.
Connector for Web Services: the SOAP gateway for BDEs and BOIs
The Infor Enterprise Server Connector for Web Services, abbreviated C4WS, is the Java servlet that actually turns a BDE or BOI business interface implementation into a callable SOAP endpoint. It runs inside a Tomcat servlet container, receives SOAP requests over HTTP, unwraps them into BDE-specific XML, forwards that XML to the LN application server over a JCA-based TCP/IP connection, and wraps the response back into SOAP for the caller.
In an on-premises deployment, setting this up has three distinct configuration layers. First, you define an ERP Server connection in C4WS, which specifies the LN server host name, activation type (rexec, baanlogin, baanlogin_ssl, or none for manual bshell debugging), port, authentication credentials, BSE path, and bshell name. Second, you deploy a specific BDE as a web service by selecting it from the connected ERP Server and importing its WSDL, which is only possible if that BDE’s implementation was generated through LN Studio. Third, if you are running with ION API in front of C4WS rather than exposing it directly, you configure OAuth based authentication on the Advanced Settings page, which is where the Consumer Key and Consumer Secret for OAuth 1.0a live.
Connection pooling deserves specific attention because it directly affects both performance and license consumption. The Max Connections, Max References, Keep Alive Time, and Max Threads settings on the ERP Server page control how many physical bshell connections are opened, how many requests share one connection, how long an idle connection stays in the pool before closing, and how many requests queue while waiting for an available connection. Leaving Max Connections at zero disables the limit entirely and disables pooling, meaning every request potentially opens a fresh bshell, which is rarely what you want for any production-volume integration. If a high-throughput integration is reporting intermittent timeouts under load, checking these four settings before assuming it is a network or application issue will save real debugging time.
The Web Services Status page is the operational dashboard for this layer. It lists every deployed service, its status (ACTIVE, STILL ACTIVE after an incomplete undeploy that needs a server restart, or NO WSDL if the file failed to load), the ERP Server it points to, and a running count of SOAP requests handled, refreshing automatically every fifteen seconds. This is the first place to check, before digging into application logs, when a partner integration reports that calls are failing or silently not arriving.
Authenticating BDE web services correctly
C4WS supports three authentication models for the connection between the connector and the LN application server itself: rexec, which sends credentials over the network unencrypted and is documented as the default but least secure option; baanlogin, which encrypts credentials before transmission; and baanlogin_ssl, which adds a secure sockets layer and is specifically required for cloud and ION API-fronted deployments where Infor ION API performs the actual user authentication and passes user, tenant, and OAuth 1.0a token information to C4WS through HTTP headers.
Separately, the SOAP requests arriving at C4WS from web clients can themselves require authentication. If Allow Anonymous Requests is disabled on the ERP Server configuration, every SOAP request must carry username and password either in the SOAP header itself or, from version 10.5.1.0042 onward, in an HTTP Basic Authentication header. You can also override the user name, password, and company at the request level rather than relying on the static ERP Server configuration, which is documented behavior intended for multi-tenant style flexibility, though it is blocked entirely for connections using baanlogin_ssl activation, where the user account passed by ION API always takes precedence and any overriding values in the SOAP header are ignored.
Building web services in Infor LN and stuck choosing between BDE and BOD?
Sama Consulting Inc. helps you model BDE and BOD interfaces in LN Studio, deploy them through the Connector for Web Services and Infor ION API, and migrate legacy BOR objects so your synchronous and event-driven integrations both hold up in production.
Putting ION API in front: OAuth 2.0 and the practical request flow
Once Infor Operating Service is in the picture, most organizations stop calling C4WS directly and instead route requests through the Infor ION API Gateway. The gateway acts as a single authentication and throttling front end across LN and other Infor applications, which is the entire point of consolidating integration traffic through Infor OS rather than maintaining separate credentials per backend service.
Setting this up for LN specifically requires Infor LN 10.4 or 10.5 and later, Infor Operating Service 12.0.23 or later, LN Tools version ES 10.6 or later, and the Connector for Web Services with the latest KB 22881149 solution installed. Configuring the LN API Suite inside Infor Ming.le requires the Infor-SystemAdministrator, IFSApplicationAdmin, and ION API Administrator roles, and you specify the C4WS host name, port, and the LN ERP Server name as the Context value, along with whether target endpoint security uses OAuth 1.0a (matching the Consumer Key and Secret configured on the C4WS Advanced Settings page) or Basic authentication.
For client applications calling through the gateway, the actual request mechanics are documented precisely: the authorization token is obtained from a grid REST security sessions OAuth endpoint, that token is active for two hours, and it must be passed as a Bearer token in the Authorization header alongside a Content-Type of text/xml, because LN APIs accessed this way remain SOAP based under the hood even though the outer transport is REST-fronted through the gateway. The endpoint URL pattern itself drops the Context suffix at request time even though it appears in the configured endpoint shown in ION API, since the gateway resolves that internally. A typical Show request against a Purchase Order business interface, sent as the SOAP body, wraps the request inside a soapenv:Envelope with an Activation header carrying the company number and a Body containing the ShowRequest with the relevant identifying field. Testing this with Postman or SoapUI using the POST method against the stripped endpoint URL is the documented verification step before considering an ION API Suite configuration complete.
It is worth being precise here because it is a common point of confusion: ION API’s OAuth 2.0 token management governs access to the gateway itself, while the OAuth 1.0a Consumer Key and Secret pair governs the trust relationship between the gateway and C4WS underneath it. These are two different credential layers solving two different problems, not redundant configuration.
Publishing events and BODs from LN
For organizations building real-time integrations rather than polling-based ones, the relevant mechanism is event publishing from inside LN application logic, using PublishEvent for simple cases or ShowAndPublishEvent when you need to publish a complete current snapshot of a component rather than just a delta. ShowAndPublishStandardEvent exists specifically for standard, predictable event scenarios and has its own modeling pattern in the BII separate from custom event logic.
Debugging event publishing that silently does not arrive is a documented, named problem in the Integration Development Guide, not an edge case. The tracing facility is enabled by setting BOL_PUBLISHER_TRACE in the BW configuration to a writable file path, and the resulting trace file shows the Show request LN internally generates to gather the component data for the event, which filter or selection criteria a subscription applied, and whether an event action matched or was skipped by a subscription’s filter. If application-specific events specifically are not firing, the trace setting needs to be present both where the SubscribeEvent request was received and in the BW process actually running the publishing application logic, because those can be two different processes.
Two further environment variables matter operationally once event-driven integrations are running in production. BOL_DISPCALLS controls how many BOD or BDE invocations occur before the underlying subprocess is closed and refreshed, defaulting to 1000 for BODs and no refresh at all for BDEs; this exists because business object implementations can leak memory over a long-running process, and a periodic refresh recovers it. BOL_AUT_PROC_WAIT controls the timeout, defaulting to sixty seconds, before control returns to a caller waiting on automatic processing BDEs tied to BOD handling. If a Data Lake publishing pipeline or downstream automation appears to hang intermittently under load, these two settings are the documented first place to look before assuming an application-level bug.
For teams running advanced financial or supply chain workflows on top of these event streams, this publishing layer is effectively the backbone that keeps downstream reporting and reconciliation systems synchronized in near real time rather than on a batch schedule.
ION Messaging Service and Data Lake publishing
From Connector for Web Services version 10.7.0 onward, C4WS also supports the ION Messaging Service, IMS, which is the REST and JSON layer that lets LN publish into Infor Data Lake. This is distinct from the BOD publishing mechanism above; IMS exposes ping, protocol, and discovery endpoints, and from version 12.2.2 a multipartMessage endpoint that actually carries BOD payloads, optionally scoped to a specific LN company by inserting the company number into the URL path between the service and v2 segments.
An IMS-capable environment specifically requires baanlogin_ssl activation, which in turn requires matching keystores containing certificates with public and private keys present on both the C4WS server and the LN server, configured through the LN Environments session in the LN UI Administration Webapp rather than through the C4WS configuration pages directly. This is one of the more operationally fiddly parts of the stack precisely because certificate provisioning sits outside C4WS’s own UI, and it is worth budgeting real time for in any project plan that includes Data Lake publishing as a deliverable, rather than treating it as a checkbox alongside standard BDE deployment.
Handling non-standard SOAP clients without rewriting the client
Occasionally a third party system already has a fixed WSDL and generated client code that does not match the WSDL LN Studio produces for the equivalent BDE. Rather than forcing a client rewrite, C4WS supports XSLT transformation of non-standard requests, version 1.0 of XSLT specifically, using a stylesheet file named after the deployed service and placed in the WEB-INF/wsdl folder of the c4ws application, or a generic default.xsl fallback if no service-specific stylesheet exists. The transformation converts the incoming non-conforming request body into the standard format LN expects, and transforms the response back into whatever shape the client’s existing code requires. The one hard constraint documented here is that this only applies to the SOAP body; any ERP Server activation overrides still have to be set the normal way in the SOAP header, because the header is untouched by the transformation step, and only BDE services support this mechanism, not the older BOI services.
This is a narrow but genuinely useful escape hatch when you are integrating with an external platform that owns its own contract and will not change it, and it avoids the much costlier alternative of building and maintaining a separate adapter service purely to reshape XML.
Where teams actually lose time on these projects
Across real implementations, the recurring causes of schedule slippage are rarely about LN Studio modeling itself. They cluster around three areas documented above: confirming whether an existing business object was generated from the BOR or from LN Studio before promising a delivery timeline for exposing it as a web service, since BOR-based objects have no WSDL and no path to BOD-based events without remodeling; underestimating the keystore and certificate provisioning work required for baanlogin_ssl and IMS, which sits outside the normal C4WS configuration screens; and skipping checksum-based concurrency control on Change methods that are reachable from more than one integrated system, which does not fail in testing but fails expensively in production once two systems genuinely race against the same record.
None of these are exotic problems. They are documented, named, and solvable using the mechanisms Infor ships with LN Studio and the Connector for Web Services. The cost is almost always in not knowing the mechanism exists before the project timeline assumed it would not be needed, which is precisely why scoping a Baan to LN migration or any new integration build benefits from an early audit of which generation of tooling produced the business objects you are about to extend.
Building web services in Infor LN and stuck choosing between BDE and BOD?
Sama Consulting Inc. helps you model BDE and BOD interfaces in LN Studio, deploy them through the Connector for Web Services and Infor ION API, and migrate legacy BOR objects so your synchronous and event-driven integrations both hold up in production.
Frequently asked questions
Why does my BDE business object have no WSDL available to deploy in C4WS?
WSDL is only generated for business objects whose implementation was created through LN Studio. If the business object was modeled in the older Business Object Repository, no WSDL exists for it, and the Deploy BDE Web Services page in C4WS will not show it as available. The fix is to import the implementation into LN Studio, where supported, and regenerate it, rather than searching for a missing configuration setting.
What is the actual difference between BDE and BOD interfaces, and can one object have both?
BDE is a synchronous request and response interface for List, Show, Create, and Change style operations. BOD is an asynchronous, event-driven interface following the OAGIS standard, used for publishing Sync, Process, or Acknowledge messages through Infor ION. A business object with a BOD interface can still expose protected BDE methods internally, but its public, externally callable contract is the BOD interface.
Why is my List or Show request slow against a large table even though the equivalent LN UI session is fast?
A common cause documented in the Integration Development Guide is a calculated or converted attribute being used in the filter. Filters on calculated attributes or attributes using a conversion hook cannot be pushed down to the database as a WHERE clause; LN reads a broader result set and applies the filter afterward in memory, which is far more expensive at scale. Checking whether the filtered attribute is a direct column mapping or a calculated one is the first diagnostic step.
How do I add a custom field to a standard BDE or BOD without losing it on the next feature pack upgrade?
Use a customization library, with the cc library suffix, created in your customization VRC, and register the field with addTableField() or addCdfField(). This keeps the custom data tied to the standard interface’s designated customization element without modifying the generated standard code, so a new feature pack version of the same BDE or BOD typically continues to work without changes, unless the new version removes the component or table the customization depends on.
My event-driven integration is not receiving events even though the underlying LN data is changing. Where do I start debugging?
Enable the BOL_PUBLISHER_TRACE environment variable to a writable file path in the BW configuration and reproduce the change. The trace file will show whether the underlying Show request used to gather event data is running, what selection or filter criteria the active subscription applied, and whether the event action matched or was filtered out. For application-specific events specifically, tracing needs to be active both where the SubscribeEvent request was received and in the process actually executing the publishing logic.
Do I need ION API, or can I call the Connector for Web Services directly?
You can call C4WS directly with rexec, baanlogin, or baanlogin_ssl authentication in an on-premises setup without ION API in the picture at all. ION API becomes the documented and required path once you need OAuth 2.0-based, centrally managed authentication across multiple Infor applications behind a single gateway, or once you are in a multi-tenant cloud environment, where C4WS’s own configuration pages for manual BDE deployment are not available and ION API’s suite configuration becomes the only supported entry point.
What is the difference between the OAuth 1.0a Consumer Key and Secret on C4WS and the OAuth 2.0 token from ION API?
They protect two different legs of the same request path. The OAuth 2.0 Bearer token, valid for two hours, authenticates the client application to the ION API Gateway. The OAuth 1.0a Consumer Key and Secret pair, configured separately on the C4WS Advanced Settings page, authenticates the trust relationship between the ION API Gateway and the underlying C4WS instance for activation type baanlogin_ssl. Misconfiguring either one produces an authentication failure, but at a different point in the chain, which is why isolating which leg is failing matters before changing credentials.
Why does my Change request occasionally overwrite data that another system just updated?
This is the documented case for checksum-based concurrency control. BDE Change requests do not hold a database lock between the initial Show and the later Change call, so two systems can race against the same record. Implementing a calculated checksum attribute, populated through the generated CalculateChecksum function and validated in the BeforeExecute hook of the Change method, causes LN to reject a stale Change request with an error rather than silently applying it over newer data.