Infor ION Messaging: Async Event-Driven Integration with BODs
Type: ERP Integration
System: Infor OS / ION (2024.x)
Confidence: 0.82
Sources: 8
Verified: 2026-03-02
Freshness: evolving
TL;DR
- Bottom line: ION Messaging uses Business Object Documents (BODs) — standardized XML messages with verb+noun structure — in a publish-subscribe architecture via ION Connect. Sync BODs broadcast changes from the system of record; Process/Acknowledge BODs handle request-reply patterns.
- Key limit: Message size caps at 5 MB (Essentials), 20 MB (Professional), or 50 MB (Enterprise) per tenant; intermediate-step flows should stay under 5 MB regardless of tier.
- Watch out for: System of Record (SOR) designation determines message flow direction — the ERP is not always the SOR; business requirements determine data ownership.
- Best for: Async event-driven integration between Infor CloudSuite apps (LN, M3, CSI) and third-party systems using standardized XML messaging with built-in routing, mapping, and monitoring.
- Authentication: OAuth 2.0 via ION API Gateway for external access; internal BOD messaging uses connection point credentials (JDBC Inbox/Outbox, IMS, or Enterprise Connector).
System Profile
Infor ION (Intelligent Open Network) is the middleware integration platform embedded in Infor OS. ION Messaging is its core async communication layer, routing Business Object Documents (BODs) between applications using a publish-subscribe model. ION Connect acts as the central messaging hub where you define connection points (application endpoints) and document flows (routing rules for BODs between connection points). This card covers the BOD messaging subsystem — not the ION API Gateway REST surface, ION Workflow automation, or ION Mapper transformations, though all three depend on ION Messaging.
All Infor CloudSuite applications (LN, M3, CloudSuite Industrial, CloudSuite Distribution, etc.) ship with pre-built BOD interfaces. Third-party systems connect via Technology Connectors — File, Database, Message Queue, API Gateway, or Kafka connection points.
| Property | Value |
| Vendor | Infor |
| System | Infor OS / ION 2024.x |
| API Surface | ION Messaging (BOD/XML pub-sub), ION API Gateway (REST) |
| Current Version | 2024.x (Cloud Edition) |
| Editions Covered | Essentials (350 units), Professional (3,500 units), Enterprise (35,000 units) |
| Deployment | Cloud (multi-tenant), On-Premise (12.0.x) |
| API Docs | Infor Documentation Central |
| Status | GA |
API Surfaces & Capabilities
ION provides multiple integration surfaces. BOD messaging is the native async mechanism; the API Gateway handles synchronous REST calls.
| API Surface | Protocol | Best For | Max Payload | Rate Limit | Real-time? | Bulk? |
| ION Messaging (BOD) | XML/HTTPS pub-sub | Event-driven sync between Infor apps | 5-50 MB (tier-dependent) | Throughput units (tier) | Near-real-time | No |
| ION API Gateway | REST/HTTPS | External system CRUD, real-time queries | No limit (streaming), 10 MB (buffered) | Not published | Yes | No |
| File Connection | FTP/SFTP/Windows share | Batch imports/exports, CSV/XML files | Filesystem limit | N/A | No | Yes |
| Database Connection | JDBC/SQL | Direct DB reads/writes for non-BOD apps | Query-dependent | N/A | Near-real-time | Yes |
| Message Queue | JMS | Integration with external MQ systems | JMS provider limit | N/A | Yes | No |
| Kafka Connection | Apache Kafka | High-throughput streaming integration | Kafka topic config | N/A | Yes | Yes |
Rate Limits & Quotas
Per-Message Limits
| Limit Type | Value | Applies To | Notes |
| Max message size (Essentials) | 5 MB | 1-3,499 processing units | Per tenant |
| Max message size (Professional) | 20 MB | 3,500-34,999 processing units | Per tenant |
| Max message size (Enterprise) | 50 MB | 35,000+ processing units | Per tenant |
| Intermediate-step payload | 5 MB recommended max | Document flows with mapping/enrichment | Regardless of tier |
| API Gateway payload (buffered) | 10 MB | Policies that buffer request/response | Streaming has no limit |
Throughput / Capacity Limits
| Limit Type | Value | Window | Edition Differences |
| Processing capacity | 350 / 3,500 / 35,000 units | Subscription-based | Add-ons in multiples of 350 |
| Data Lake ingestion | 600 per 1 TB storage | Per customer | Shared across all tiers |
| API Gateway timeout (sync) | Default 1 min, max 5 min | Per request | Configurable per endpoint |
| API Gateway timeout (async) | Up to 2 hours | Per request | For long-running operations |
| LN/Baan bshells | Max 10 per channel | Per connection point | Exceeding causes queue backpressure |
History Retention Limits
| Tier | Complete Records | In-Flight Records |
| Essentials (1-3,499 units) | 45 days | 180 days |
| Professional (3,500-34,999) | 90 days | 270 days |
| Enterprise (35,000+) | 180 days | 360 days |
Authentication
| Flow | Use When | Token Lifetime | Refresh? | Notes |
| OAuth 2.0 Authorization Code | Native/desktop apps, web apps | Session-based | Yes | Standard 3-legged flow via Infor IFS |
| OAuth 2.0 Resource Owner Password | Server-to-server via ION API Gateway | Session-based | Yes | Uses service account AccessKey + SecretKey |
| OAuth 2.0 SAML Bearer | Apps integrated with Infor Ming.le | Session-based | Yes | For SSO-enabled environments |
| JDBC Inbox/Outbox | BOD messaging between Infor apps | N/A (persistent) | N/A | Internal; uses application connection point credentials |
| Enterprise Connector | On-premise to cloud bridge | Certificate-based | N/A | Requires EC agent installation on-premise |
Authentication Gotchas
- ION API Gateway OAuth requires four credentials for backend services: ClientID, Client-Secret, Service Account AccessKey, and Service Account SecretKey — missing any one causes silent auth failure. [src6]
- Enterprise Connector certificate expiration breaks all on-premise-to-cloud BOD flows with no automatic renewal — set calendar reminders for cert rotation. [src2]
- OAuth token endpoints are tenant-specific — hardcoding URLs across environments (dev/test/prod) will break when tenants differ. [src6]
Constraints
- Tier-dependent message size: Essentials tier caps at 5 MB per message — large BODs (e.g., full item master syncs) may require splitting into multiple messages.
- Intermediate-step 5 MB recommendation: Even on Enterprise tier, document flows with ION Mapper or enrichment steps should keep payloads under 5 MB for reliable processing.
- LN/Baan channel limit: Maximum 10 bshells per channel — high-volume LN integrations need multiple connection points or queue-based throttling.
- No native replay/rewind: Unlike Kafka, ION Messaging does not support message replay from an offset — failed messages go to Confirm BOD (error queue) for manual resubmission via ION Desk.
- API Gateway sync timeout: 5-minute maximum for synchronous calls — long-running integrations must use async patterns or file-based flows.
- OneView retention: Historical message data is purged after 45-180 days depending on tier — export audit data before retention window closes.
Integration Pattern Decision Tree
START — User needs to integrate with Infor CloudSuite via ION
|-- What's the integration pattern?
| |-- Event-driven (BOD pub-sub, near-real-time)
| | |-- Infor-to-Infor app?
| | | |-- YES -> Application Connection Point (IOBOX/IMS), Sync BODs
| | | +-- NO -> Technology Connector (File/DB/MQ/Kafka/API)
| | |-- Need request-reply confirmation?
| | | |-- YES -> Process BOD (request) + Acknowledge BOD (response)
| | | +-- NO -> Sync BOD (broadcast, fire-and-forget)
| | +-- Need data enrichment in transit?
| | |-- YES -> ION Mapper in document flow (keep payload < 5 MB)
| | +-- NO -> Direct connection point to connection point
| |-- Real-time synchronous (individual records, <1s)
| | +-- ION API Gateway REST endpoint (max 5 min timeout)
| |-- Batch/Bulk (scheduled, high volume)
| | |-- Data volume < 5 MB per batch?
| | | |-- YES -> BOD messaging with scheduled trigger
| | | +-- NO -> File Connection Point via SFTP
| | +-- Need incremental or full load?
| | |-- Incremental -> Sync BODs (change-driven)
| | +-- Full -> Get/Show BOD pair or file export
| +-- File-based (CSV/XML)
| +-- File Connection Point (SFTP from Cloud or Enterprise Connector)
|-- Which direction?
| |-- Inbound (writing to Infor) -> Process BOD to system of record
| |-- Outbound (reading from Infor) -> Subscribe to Sync BODs from SOR
| +-- Bidirectional -> Define SOR per business object FIRST
+-- Error tolerance?
|-- Zero-loss required -> Monitor Confirm BODs in ION Desk + alerting
+-- Best-effort -> Sync BODs with retry on subscriber side
Quick Reference
BOD Verb Reference
| Verb | Direction | Pattern | Response Required | Use Case |
| Sync | SOR -> Subscribers | Publish-subscribe (broadcast) | No | Data changed in SOR — notify all subscribers |
| Process | Requester -> SOR | Point-to-point (request) | Yes (Acknowledge) | Request SOR to create/update a record |
| Acknowledge | SOR -> Requester | Point-to-point (response) | No | Accept/reject a Process request |
| Get | Requester -> SOR | Point-to-point (query) | Yes (Show) | Request specific records (initial load, recovery) |
| Show | SOR -> Requester | Point-to-point (response) | No | Return requested records |
| Post | Sender -> Receiver | Point-to-point | No | Similar to Process but no Acknowledge expected |
| Load | Non-SOR -> SOR | Point-to-point (push) | No | Force-create document — cannot be refused |
| Update | Non-SOR -> SOR | Point-to-point (notify) | No | Notify SOR of event-triggered changes |
| Confirm | ION -> ION Desk | System-generated (error) | No | Error notification with original message for resubmission |
Connection Point Types
| Type | Protocol | Use When | Cloud? | On-Prem? |
| Application (IOBOX) | JDBC Inbox/Outbox | Infor apps with native BOD support | Yes | Yes |
| IMS | REST/HTTPS | Infor apps using ION Messaging Service | Yes | Yes |
| LN/Baan | Bshell | Infor LN/Baan specific | Yes | Yes |
| File | FTP/SFTP/Windows share | Non-BOD apps, batch files | Yes (SFTP from Cloud) | Yes |
| Database | JDBC/SQL | Direct DB integration, non-BOD apps | Via EC | Yes |
| Message Queue | JMS | External MQ systems (IBM MQ, RabbitMQ) | Via EC | Yes |
| ION API | REST | External REST APIs | Yes | Yes |
| Kafka | Apache Kafka | High-throughput streaming | Yes | Yes |
Step-by-Step Integration Guide
1. Register application and create connection point
Open ION Desk and create a connection point matching your integration type. For third-party apps, use a Technology Connector. [src2]
ION Desk > Connect > Connection Points > + Add
- Name: "EXT_MyApp_CP"
- Type: Select connector type (File, Database, Message Queue, API, Kafka)
- Configure credentials and endpoint details
- Select BODs to send (outbox) and receive (inbox)
- Save and activate
Verify: Connection point status shows "Active" in ION Desk with green indicator.
2. Define a document flow between connection points
Create a document flow that routes specific BODs from source to target connection points. [src2, src7]
ION Desk > Connect > Document Flows > + Add
- Name: "ItemMaster_ERP_to_WMS"
- Source: Select source connection point
- Target: Select target connection point
- BODs: Select specific BODs (e.g., SyncItemMaster)
- Optional: Add ION Mapper node for field transformation
- Activate flow
Verify: Document flow shows active status; test with a sample BOD and confirm delivery in ION OneView.
3. Publish a Sync BOD from the source system
When data changes in the SOR, it publishes a Sync BOD to ION. For custom apps, write BOD XML to the outbox table or send via IMS/REST. [src3]
<SyncItemMaster xmlns="http://schema.infor.com/InforOAGIS/2"
releaseID="9.2" versionID="2.12.0">
<ApplicationArea>
<Sender>
<LogicalID>lid://infor.myerp.1</LogicalID>
<ComponentID>ERP</ComponentID>
</Sender>
<CreationDateTime>2026-03-02T10:00:00Z</CreationDateTime>
<BODID>bca4f1e8-3d7a-4b2e-9c1d-abc123456789</BODID>
</ApplicationArea>
<DataArea>
<Sync>
<ActionCriteria>
<ActionExpression actionCode="Replace"/>
</ActionCriteria>
</Sync>
<ItemMaster>
<ItemMasterHeader>
<ItemID><ID>ITEM-10042</ID></ItemID>
<Description>Widget Assembly Unit</Description>
</ItemMasterHeader>
</ItemMaster>
</DataArea>
</SyncItemMaster>
Verify: Check ION OneView for the published BOD — status should show "Delivered" to all subscriber connection points.
4. Handle Process/Acknowledge request-reply flow
For request-reply patterns, the requesting system sends a Process BOD and the SOR responds with an Acknowledge BOD. [src3, src5]
<!-- Requester sends ProcessPurchaseOrder -->
<ProcessPurchaseOrder>
<ApplicationArea>
<Sender><LogicalID>lid://infor.procurement.1</LogicalID></Sender>
<BODID>proc-order-001</BODID>
</ApplicationArea>
<DataArea>
<Process>
<ActionCriteria><ActionExpression actionCode="Add"/></ActionCriteria>
</Process>
<PurchaseOrder><!-- order details --></PurchaseOrder>
</DataArea>
</ProcessPurchaseOrder>
<!-- SOR responds with AcknowledgePurchaseOrder -->
<AcknowledgePurchaseOrder>
<ApplicationArea>
<Sender><LogicalID>lid://infor.erp.1</LogicalID></Sender>
<BODID>ack-order-001</BODID>
</ApplicationArea>
<DataArea>
<Acknowledge>
<OriginalApplicationArea><BODID>proc-order-001</BODID></OriginalApplicationArea>
<ResponseCriteria><ResponseExpression actionCode="Accepted"/></ResponseCriteria>
</Acknowledge>
</DataArea>
</AcknowledgePurchaseOrder>
Verify: Original Process BOD shows "Acknowledged" in ION OneView; Acknowledge BOD delivered to requester.
Code Examples
Python: Send a BOD via ION API Gateway
# Input: OAuth credentials (.ionapi file), BOD XML string
# Output: HTTP 200 on successful BOD submission
import requests
import json
# Load ION API credentials from .ionapi file
with open("myapp.ionapi", "r") as f:
creds = json.load(f)
# Step 1: Obtain OAuth token
token_url = f"{creds['pu']}/as/{creds['oa']}/token.oauth2"
token_resp = requests.post(token_url, data={
"grant_type": "password",
"username": creds["saak"], # Service Account Access Key
"password": creds["sask"], # Service Account Secret Key
"client_id": creds["ci"],
"client_secret": creds["cs"]
})
access_token = token_resp.json()["access_token"]
# Step 2: Send BOD XML via ION API
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/xml"
}
bod_xml = """<SyncItemMaster xmlns="http://schema.infor.com/InforOAGIS/2">
<!-- BOD content here -->
</SyncItemMaster>"""
response = requests.post(
f"{creds['pu']}/{creds['ot']}/IONMessaging/api/bod",
headers=headers,
data=bod_xml
)
print(f"Status: {response.status_code}") # 200 = success
cURL: Test ION API Gateway authentication
# Input: OAuth token endpoint, client credentials, service account keys
# Output: Access token JSON response
# Step 1: Get OAuth token
curl -X POST "https://{tenant}.inforcloudsuite.com/as/{tenant_id}/token.oauth2" \
-d "grant_type=password" \
-d "username={SERVICE_ACCOUNT_ACCESS_KEY}" \
-d "password={SERVICE_ACCOUNT_SECRET_KEY}" \
-d "client_id={CLIENT_ID}" \
-d "client_secret={CLIENT_SECRET}"
# Expected: {"access_token":"eyJ...", "token_type":"bearer", "expires_in":3600}
# Step 2: Send a BOD
curl -X POST "https://{tenant}.inforcloudsuite.com/{tenant_id}/IONMessaging/api/bod" \
-H "Authorization: Bearer {ACCESS_TOKEN}" \
-H "Content-Type: application/xml" \
-d @sync_item_master.xml
Data Mapping
BOD XML Structure Reference
| Element | Location | Type | Purpose | Gotcha |
| LogicalID | ApplicationArea > Sender | String (lid://...) | Unique app instance identifier | Must match connection point config exactly |
| BODID | ApplicationArea | UUID | Unique message identifier | Duplicates cause silent drops — use UUID v4 |
| CreationDateTime | ApplicationArea | DateTime (UTC) | When BOD was created | Must be UTC; local time causes routing errors |
| ActionExpression | DataArea > Verb | Attribute (actionCode) | Add, Replace, Change, Delete | Sync uses Add/Replace; Process uses Add/Change |
| Tenant | Embedded in LogicalID | String | Multi-tenant routing key | Wrong tenant ID routes BOD to wrong environment |
| AccountingEntity | DataArea > Noun | String | Financial entity context | Required for multi-entity deployments |
Data Type Gotchas
- All dates/times must use UTC format "yyyy-MM-ddTHH:mm:ssZ"; missing time values default to midnight (00:00:00Z) — can cause off-by-one-day errors in timezone-aware systems. [src4]
- BOD UserArea allows custom fields via Property/NameValue elements — no schema validation on UserArea content, so the receiver must validate. [src4]
- Quantity elements require a UnitCode attribute — omitting it does not cause a BOD schema error but will fail in the receiving application. [src4]
Error Handling & Failure Points
Common Error Patterns
| Error | Meaning | Cause | Resolution |
| Confirm BOD generated | Message processing failed | Receiver threw exception or timed out | Review in ION Desk; fix data; resubmit |
| Connection point "Paused" | No messages processed | Manual pause or maintenance | Resume in ION Desk; messages replay from queue |
| BOD schema validation error | XML doesn't match OAGIS schema | Wrong namespace or missing elements | Validate against Infor OAGIS schema |
| LN/Baan processing timeout | Bshell did not respond | Complex logic or DB locks in LN | Increase timeout; optimize LN processing |
| "Message size exceeds limit" | BOD payload too large | Large master data sync | Split into multiple BODs; upgrade tier |
| OAuth token expired (401) | API Gateway auth failed | Token not refreshed | Implement token refresh with TTL check |
Failure Points in Production
- Confirm BOD accumulation: Failed messages generate Confirm BODs that pile up silently until limits are hit. Fix:
Set ION Desk alerts for Confirm BOD count > threshold; review daily. [src3]
- Enterprise Connector disconnection: EC loses cloud connection — BODs queue locally until reconnection, but local queue has finite storage. Fix:
Monitor EC health endpoint; auto-restart EC agent service. [src2]
- SOR designation mismatch: Two apps both configured as SOR for the same noun — Sync BODs conflict causing data oscillation. Fix:
Define SOR per noun explicitly; use Process/Acknowledge for non-SOR updates. [src5]
- BOD versioning drift: Apps running different OAGIS versions — newer fields silently ignored by older receivers. Fix:
Pin BOD versionID; test all receiver versions before upgrading sender. [src4]
Anti-Patterns
Wrong: Polling ION API Gateway for changes
# BAD — Polling REST API every 30 seconds for changes
while True:
response = requests.get(f"{base_url}/api/items?modifiedAfter={last_check}")
process_changes(response.json())
time.sleep(30)
# Wastes API Gateway capacity, misses changes between polls
Correct: Subscribe to Sync BODs via document flow
# GOOD — Configure document flow in ION Desk
# 1. Create connection point for your application
# 2. Create document flow: ERP (source) -> YourApp (target)
# 3. Select SyncItemMaster BOD
# 4. ION pushes changes to your inbox automatically
# Result: Zero polling, guaranteed delivery, near-real-time
Wrong: Sending large bulk data as a single BOD
<!-- BAD — 50,000 line items in one BOD = ~30 MB -->
<!-- Exceeds Essentials/Professional tier limits -->
Correct: Chunk into smaller BODs
<!-- GOOD — Split into batches of 500 items each (~300 KB) -->
<!-- Use BODID convention (batch-001-of-100) to track completeness -->
Wrong: Assuming SOR is always the ERP
# BAD — Hardcoding ERP as system of record for all objects
# "Customer master comes from ERP" — WRONG if CRM owns customer data
Correct: Define SOR per business object
# GOOD — SOR designation per noun:
# Customer -> CRM is SOR (publishes SyncCustomer)
# ItemMaster -> ERP is SOR (publishes SyncItemMaster)
# Document the SOR map before configuring any document flows
Common Pitfalls
- Ignoring Confirm BODs: Teams that don't monitor Confirm BODs lose data silently. Fix:
Configure ION Desk alert rules; assign daily review. [src3]
- Not testing message size across tiers: BODs that work in Enterprise dev/test fail in Essentials production at 5 MB. Fix:
Test with production-volume data in tier-matched environment. [src1]
- Hardcoding LogicalIDs: LogicalIDs change between environments. Fix:
Parameterize per environment using config files. [src5]
- Missing BODID uniqueness: Duplicate BODIDs cause silent message discards. Fix:
Generate UUID v4 for every BODID; never reuse. [src4]
- Overloading document flows with mapping: Complex ION Mapper transformations on high-volume flows hit the 5 MB buffer. Fix:
Keep high-volume flows simple; transform at the application layer. [src1]
- Not accounting for message ordering: ION does not guarantee ordering across connection points. Fix:
Include sequence numbers; implement idempotent receivers. [src2]
Diagnostic Commands
# Check ION connection point status
# ION Desk > Connect > Connection Points > select CP > Status tab
# Look for: Active (green), Paused (yellow), Error (red)
# Monitor document flow throughput
# ION Desk > Connect > Document Flows > select flow > Monitoring tab
# Shows: messages/hour, failed count, queue depth
# View Confirm BODs (failed messages)
# ION Desk > Connect > OneView > filter by Status = "Error"
# Test BOD delivery end-to-end
# ION Desk > Connect > Test > select document flow > Send test BOD
# Check Enterprise Connector health (on-premise)
# EC Admin Console > Status > check "Connected" indicator
# Monitor message queue depth
# ION Desk > Connect > Connection Points > select CP > Queue tab
Version History & Compatibility
| Version | Release Date | Status | Breaking Changes | Migration Notes |
| 2024.x (Cloud) | 2024-01 | Current | Kafka connection points added | New connector — no impact on existing flows |
| 2023.x (Cloud) | 2023-01 | Supported | SFTP from Cloud connector added | Alternative to EC-routed SFTP |
| 12.0.x (On-Premise) | 2020-01 | Supported | Last major on-premise release | Cloud migration via Enterprise Connector |
| 11.x (On-Premise) | 2017-01 | EOL | — | Upgrade to 12.0.x or cloud |
When to Use / When Not to Use
| Use When | Don't Use When | Use Instead |
| Async event-driven sync between Infor CloudSuite apps | Synchronous real-time CRUD with <1s response | ION API Gateway REST endpoints |
| Standardized XML messaging with built-in routing and monitoring | Custom binary or non-XML payload formats | File or Kafka Connection Point |
| Multi-subscriber broadcast of data changes (pub-sub) | Point-to-point low-latency API calls | ION API Gateway direct REST |
| Need guaranteed delivery with error handling via Confirm BODs | Need message replay/rewind from arbitrary offset | Kafka-based integration |
| Integration between on-premise and cloud Infor systems | Pure cloud-to-cloud REST API integration | ION API Gateway with OAuth |
Important Caveats
- Processing unit capacity is contractual — exceeding your tier causes throttling, not hard failures. Contact Infor for capacity upgrades before peak seasons.
- Message size limits are per tenant, not per connection point — a single large BOD impacts capacity for all flows in the tenant.
- ION Desk monitoring (OneView) data retention is tier-dependent — Essentials retains only 45 days. Export audit data before the retention window closes.
- On-premise deployments (12.0.x) may have different constraints than cloud 2024.x — always verify limits against your specific deployment.
- BOD schemas follow OAGIS standards but Infor extends them with custom namespaces — third-party systems must handle Infor-specific extensions.
Related Units