Choosing the Right Integration Layer in Maximo Application Suite 9.2

MAS 9.2 exposes five distinct integration layers, each with specific trade-offs. This guide breaks down when to use each one, with code examples and architecture patterns for real-world scenarios.

Share
Choosing the Right Integration Layer in Maximo Application Suite 9.2

Choosing the Right Integration Layer in Maximo Application Suite 9.2

The Maximo Application Suite has converged around JSON and REST, but that does not mean integration is simple. It means the opposite. With five distinct integration layers available in MAS 9.2, the architecture decision is no longer "how do I connect to Maximo?" but "which layer should I use for this specific scenario?" The wrong choice leads to fragile integrations, unnecessary complexity, and maintenance burdens that outlast the original developers.

This article walks through each integration layer in MAS 9.2, explains the scenarios where each one earns its complexity, and provides code examples and decision frameworks that integration architects can apply directly. The goal is not to advocate for one layer over another but to give you the criteria to choose correctly the first time.

The Five Integration Layers in MAS 9.2

MAS 9.2 exposes a layered integration surface. Understanding what each layer does and when to use it is the foundation of every integration architecture decision.

Layer 1: The Maximo Manage REST API. This is the default integration surface. IBM describes it as a complete rewrite of the REST APIs introduced after version 7.1, and it shares the same code base as the OSLC REST APIs used by Maximo Mobile. The REST API exposes every Maximo business object through consistent, OpenAPI-style endpoints. Authentication is handled through API keys or OAuth 2.0, with OAuth becoming the recommended approach in MAS 9.2. The API supports JSON natively, with XML as a secondary format. This is the layer where new integrations should begin.

Layer 2: The Maximo Integration Framework (MIF). MIF remains the umbrella term for the configuration-driven integration layer that includes publish channels, enterprise services, object structures, external systems, processing rules, and XSL transforms. In MAS 9.x, MIF supports JSON and REST alongside its legacy SOAP and XML formats. MIF is built around four core concepts: object structures define which business objects and attributes are exposed, publish channels define outbound messages triggered by record changes, enterprise services define inbound messages that Maximo accepts from external systems, and endpoints define the delivery mechanism.

Layer 3: OSLC (Open Services for Lifecycle Collaboration). OSLC provides an industry-standard protocol for linked data across systems. In MAS, OSLC and the REST API share the same underlying code base, but OSLC adds RDF and linked-data semantics. OSLC is the right choice when you need cross-system resource linking and OSLC-standard compliance.

Layer 4: Apache Kafka. Kafka is required by Maximo IoT and optional for Manage. It provides the event-driven backbone for high-throughput, distributed environments. Kafka runs on OpenShift via the Red Hat AMQ Streams operator (based on the Strimzi operator) for on-premises installations, or you can use a managed Kafka service from your cloud provider. Kafka enables real-time event streaming patterns that are fundamentally different from the request-response model of the REST API.

Layer 5: The MCP Server. The most strategically significant integration change in MAS 9.2 is the Model Context Protocol (MCP) Server. It allows organizations to bring their own AI agents and integrate them directly with Maximo Manage APIs. An AI agent running in Claude, IBM Bob, Codex, or any MCP-compatible client can interact with Maximo without custom integration code. The MCP architecture has three components: the MCP Host (the application running the AI model), the MCP Client (manages communication between the model and external services), and the MCP Server (exposes tools, resources, and capabilities through a standardized interface).

REST API in Practice: Code Patterns for Common Operations

The REST API is where most integration work happens. Understanding the URL patterns, authentication flow, and response format is essential for any Maximo integration developer.

The base URL pattern for the REST API follows a predictable structure:

# Base URL pattern
https://{mas-host}/maximo/oslc/os/{resourcetype}

# Authentication via OAuth 2.0 token
Authorization: Bearer {access_token}
Content-Type: application/json

# The lean=1 parameter strips OSLC metadata
# Recommended for most integration scenarios

Core endpoints for common operations follow standard RESTful conventions:

Operation Endpoint Method
Get Work Order /maximo/oslc/os/mxwo/{wonum} GET
Create Work Order /maximo/oslc/os/mxwo POST
Update Work Order /maximo/oslc/os/mxwo/{wonum} PATCH
Query Assets /maximo/oslc/os/mxasset?oslc.where=assetnum="{num}" GET
Create Service Request /maximo/oslc/os/mxsr POST

Here is a Python example for creating a work order using the REST API with OAuth authentication:

import requests
import json
from requests.auth import HTTPBasicAuth

class MaximoRestClient:
    def __init__(self, base_url, api_key=None, oauth_token=None):
        self.base_url = base_url.rstrip('/')
        self.session = requests.Session()
        if oauth_token:
            self.session.headers.update({
                'Authorization': f'Bearer {oauth_token}',
                'Content-Type': 'application/json'
            })
        elif api_key:
            self.session.headers.update({
                'MAXAUTH': api_key,
                'Content-Type': 'application/json'
            })

    def create_work_order(self, wonum, description, siteid, assetnum=None):
        """Create a new work order in Maximo."""
        endpoint = f"{self.base_url}/maximo/oslc/os/mxwo"
        payload = {
            "wonum": wonum,
            "description": description,
            "siteid": siteid,
        }
        if assetnum:
            payload["assetnum"] = assetnum

        response = self.session.post(
            endpoint,
            json=payload,
            params={"lean": 1}
        )
        response.raise_for_status()
        return response.json()

    def get_asset(self, assetnum, siteid=None):
        """Retrieve asset details from Maximo."""
        endpoint = f"{self.base_url}/maximo/oslc/os/mxasset"
        params = {"lean": 1}
        if siteid:
            params["oslc.where"] = f'assetnum="{assetnum}" and siteid="{siteid}"'
        else:
            params["oslc.where"] = f'assetnum="{assetnum}"'

        response = self.session.get(endpoint, params=params)
        response.raise_for_status()
        return response.json()

    def update_work_order_status(self, wonum, new_status):
        """Update a work order status using PATCH."""
        endpoint = f"{self.base_url}/maximo/oslc/os/mxwo/{wonum}"
        payload = {"status": new_status}

        response = self.session.patch(
            endpoint,
            json=payload,
            params={"lean": 1}
        )
        response.raise_for_status()
        return response.json()

# Usage example
client = MaximoRestClient(
    base_url="https://mas-prod.company.com",
    oauth_token=get_oauth_token()
)
new_wo = client.create_work_order(
    wonum="WO-2026-0042",
    description="Replace bearings on Pump P-104",
    siteid="BEDFORD",
    assetnum="P-104"
)

One of the most powerful features of the MAS REST API is support for batch operations. Instead of making 100 individual API calls to update 100 work orders, you can submit a single batch request:

def batch_update_work_orders(self, updates):
    """Batch update multiple work orders in a single request."""
    endpoint = f"{self.base_url}/maximo/oslc/os/mxwo"
    # The batch endpoint accepts an array of resources
    payload = {
        "_action": "batchUpdate",
        "resources": updates  # List of work order update objects
    }
    response = self.session.post(endpoint, json=payload, params={"lean": 1})
    response.raise_for_status()
    return response.json()

The lean=1 query parameter is critical for production integrations. It strips OSLC metadata from responses, returning clean JSON that is smaller in size and easier to parse. Without it, responses include OSLC-specific properties like _oslc:results, _oslc:responseInfo, and RDF-type annotations that add noise to your integration without adding value unless you are specifically working with OSLC clients.

MIF: When Configuration Beats Code

The Maximo Integration Framework remains valuable for scenarios where configuration-driven integration is superior to custom code. Understanding these scenarios prevents teams from over-engineering REST API solutions for problems that MIF already solves.

MIF earns its complexity in four specific scenarios. First, when maintaining a legacy integration that already uses MIF enterprise services or publish channels, and the cost of rewriting is not justified by the benefit. Second, when performing complex inbound transformations that benefit from MIF's processing classes, Java hooks, and conditional channel logic. Third, when publishing changes to multiple downstream systems through a single publish channel with routing rules. Fourth, when integrating with SAP, Oracle, or other ERP systems through the Maximo ERP Integration add-on, which is built on MIF.

Here is how a typical MIF outbound integration is configured:

<!-- Object Structure: WO_INTEGRATION -->
<!-- Defines which fields are included in the integration message -->
<maximo-object-structure>
    <name>WO_INTEGRATION</name>
    <description>Work Order integration with external ERP</description>
    <object>WORKORDER</object>
    <related-object>
        <relationship>WOACTIVITY</relationship>
        <parent>WORKORDER</parent>
    </related-object>
    <related-object>
        <relationship>WOLABOR</relationship>
        <parent>WORKORDER</parent>
    </related-object>
</maximo-object-structure>

The publish channel configuration defines when the message fires and where it goes:

<!-- Publish Channel: WO_TO_ERP -->
<publish-channel>
    <name>WO_TO_ERP</name>
    <object-structure>WO_INTEGRATION</object-structure>
    <external-system>ERP_SYSTEM</external-system>
    <event-trigger>
        <trigger-on>STATUS_CHANGE</trigger-on>
        <from-status>APPR</from-status>
        <to-status>WAPPR</to-status>
    </event-trigger>
    <endpoint>
        <type>HTTP</type>
        <url>https://erp.company.com/maximo-inbound</url>
        <format>JSON</format>
    </endpoint>
</publish-channel>

The inbound enterprise service receives data from external systems and processes it through the same transformation pipeline:

<!-- Enterprise Service: ASSET_FROM_ERP -->
<enterprise-service>
    <name>ASSET_FROM_ERP</name>
    <object-structure>ASSET_INTEGRATION</object-structure>
    <external-system>ERP_SYSTEM</external-system>
    <operation>CREATE_UPDATE</operation>
    <processing-rules>
        <rule>
            <condition>ASSETNUM not null</condition>
            <action>CREATE_OR_UPDATE</action>
        </rule>
    </processing-rules>
</enterprise-service>

The key architectural decision is whether your integration needs the transformation pipeline that MIF provides. If you are doing simple CRUD operations against Maximo business objects, the REST API is always the right choice. If you need conditional routing, XSL transforms, processing classes, or Java hooks, MIF is the appropriate tool.

Kafka: Event-Driven Integration for Real-Time Operations

Apache Kafka changes the integration paradigm from request-response to event streaming. This matters for Maximo implementations that need real-time event distribution to multiple consumers.

Kafka is required by Maximo IoT and is optional for Manage. For organizations running MAS on OpenShift, Kafka is installed via the Red Hat AMQ Streams operator. The installation process involves creating a Kafka namespace, deploying the AMQ Streams operator, and creating a Kafka cluster with appropriate storage and authentication configuration.

The decision to use Kafka should be driven by the integration pattern, not by the technology. Use Kafka when you need event-driven patterns where multiple downstream systems consume the same events independently. For example, when a work order status changes in Maximo, you might need to notify a BI dashboard, trigger an ERP update, and send a mobile notification. With Kafka, Maximo publishes the event once, and each consumer reads it independently from their own offset.

# Example: Kafka consumer for Maximo work order events
from kafka import KafkaConsumer
import json

class MaximoEventConsumer:
    def __init__(self, bootstrap_servers, topic, group_id):
        self.consumer = KafkaConsumer(
            topic,
            bootstrap_servers=bootstrap_servers,
            group_id=group_id,
            value_deserializer=lambda m: json.loads(m.decode('utf-8')),
            auto_offset_reset='latest',
            enable_auto_commit=True
        )

    def process_work_order_events(self):
        """Listen for work order events and route to downstream systems."""
        for message in self.consumer:
            event = message.value
            event_type = event.get('eventType')

            if event_type == 'STATUS_CHANGE':
                self.handle_status_change(event)
            elif event_type == 'CREATED':
                self.handle_new_work_order(event)
            elif event_type == 'COMPLETED':
                self.handle_completion(event)

    def handle_status_change(self, event):
        wonum = event.get('wonum')
        new_status = event.get('status')
        print(f"Work order {wonum} changed to {new_status}")
        # Route to ERP, BI dashboard, or notification service

Kafka also provides the backbone for IoT data ingestion in Maximo. Sensor data from industrial equipment flows through Kafka topics into Maximo Monitor, which processes the data and triggers alerts, predictions, and work order generation through the integrated MAS applications.

OSLC: When Linked Data Matters

OSLC is the layer that most integration architects overlook, but it has a specific role that the REST API does not fill. OSLC provides standardized resource linking across systems, which matters when you need to create relationships between assets in Maximo and resources in other OSLC-compliant systems like IBM Engineering Lifecycle Management or third-party PLM tools.

The REST API and OSLC share the same underlying code base in MAS, which means they are not competing layers but complementary ones. Use the REST API for standard CRUD operations. Use OSLC when you need cross-system linked data, OSLC-standard compliance, or integration with tools that specifically require OSLC resources.

A practical OSLC use case is linking a Maximo asset to a requirements specification in an engineering tool. The OSLC link creates a typed relationship that both systems can traverse, enabling traceability from the physical asset to its design requirements.

The MCP Server: AI Agent Integration

The MCP Server in MAS 9.2 is the newest integration layer and the one with the most strategic implications. It allows AI agents to interact with Maximo Manage APIs through a standardized interface without custom integration code.

The MCP Server exposes Maximo Manage APIs as MCP tools. An AI agent can discover available tools (create work order, query assets, update inventory), understand their parameters, and execute them. The agent does not need to know the Maximo REST API details. It interacts through the MCP abstraction layer.

This means an AI agent running in a compatible host (Claude Desktop, IBM Bob in VS Code, a custom agent framework) can query asset history, create work orders, update inventory levels, and perform any operation that the REST API exposes, but through a standardized protocol that the agent understands natively.

The practical impact is significant. Instead of building a custom REST client for every AI integration scenario, teams connect an MCP-compatible agent to the Maximo MCP Server and let the agent handle the interaction. This reduces integration code, enables rapid prototyping of AI-assisted maintenance workflows, and opens Maximo to the growing ecosystem of AI agent platforms.

# Example: AI agent interaction with Maximo via MCP
# The agent discovers tools and executes them through the MCP protocol

# MCP tool discovery (simplified)
mcp_tools = mcp_client.list_tools()
# Returns: [
#   {name: "create_work_order", params: {wonum, description, siteid, assetnum}},
#   {name: "query_assets", params: {assetnum, siteid, status}},
#   {name: "update_inventory", params: {itemnum, storeloc, quantity}},
#   {name: "get_asset_history", params: {assetnum, days_back}}
# ]

# Agent creates a work order based on a prediction
result = mcp_client.call_tool("create_work_order", {
    "wonum": "WO-AI-2026-001",
    "description": "AI predicted bearing failure on Pump P-104",
    "siteid": "BEDFORD",
    "assetnum": "P-104"
})

Practical Implications

The integration architecture you choose today will be maintained for years. The wrong choice creates technical debt that compounds over time. Here is the decision framework distilled from the layers above.

For new integrations, start with the REST API. It is the primary integration surface in MAS, it supports JSON natively, it uses OAuth 2.0 authentication, and it handles every standard CRUD operation. The lean=1 parameter should be your default for clean responses. Build a reusable client library that handles authentication, error handling, and pagination so that every new integration starts from the same foundation.

Keep MIF for the patterns where it genuinely earns its complexity. If you have existing MIF integrations that work, maintain them. If you need complex inbound transformations, conditional routing to multiple downstream systems, or ERP integration through the Maximo ERP Integration add-on, MIF is the right tool. Do not rewrite working MIF integrations just to use the REST API. Instead, set a deprecation target (for example, "all MIF integrations migrated by Q4 2027") and migrate incrementally when triggered by external system upgrades, operational issues, or business requirement changes.

Use Kafka for event-driven patterns, not for simple request-response. If you find yourself publishing an event and having a single consumer process it synchronously, you do not need Kafka. You need a webhook or a REST callback. Kafka earns its operational complexity when you have multiple independent consumers, high throughput requirements, or IoT data ingestion needs.

Reserve OSLC for cross-system linked-data scenarios. Do not use OSLC for internal point-to-point integrations where the REST API is sufficient. Use OSLC when you need to create typed links between Maximo assets and resources in other OSLC-compliant systems.

Pilot the MCP Server if you have AI agent use cases on your roadmap. The MCP Server is new in MAS 9.2, and production deployments are still emerging. Start with a proof of concept that connects an AI agent to Maximo through the MCP Server and evaluate whether the abstraction layer provides enough value to justify the additional infrastructure.

Maintain an integration catalog. Document every integration, including the layer used, the business objects involved, the authentication method, the error handling approach, and the owner. This catalog becomes invaluable during upgrades, troubleshooting, and onboarding new team members.

Bottom Line

The Maximo integration surface in 2026 is JSON-first, REST-native, and supplemented by Kafka for event-driven patterns and MCP for AI agent integration. The five-layer stack gives architects the tools to build the right integration for each scenario, but only if they understand the trade-offs.

Build new integrations on the JSON REST API with OAuth 2.0. Keep MIF for complex transformations, conditional routing, and ERP integrations. Reserve OSLC for cross-system linked-data scenarios. Use Kafka for event-driven patterns rather than polling. Treat the legacy /maxrest/rest API as historical. And pilot the MCP Server if AI agent integration is on your roadmap.

The integration layer you choose is not just a technical decision. It is a commitment that will shape your maintenance burden, your upgrade path, and your team's ability to extend the system for years to come. Choose deliberately.

Read more