---
# === IDENTITY ===
id: business/erp-integration/infor-cloudsuite-api-surfaces/2026
canonical_question: "How do Infor CloudSuite API surfaces differ across M3, LN, and CloudSuite Industrial?"
aliases:
  - "Infor M3 API vs LN REST API vs CSI IDO web services comparison"
  - "ION API Gateway endpoints for M3, LN, and CloudSuite Industrial"
  - "Which Infor CloudSuite API surface should I use for integration?"
  - "Infor CloudSuite M3 MIProgram REST API vs LN OData vs CSI IDO"
entity_type: erp_integration
domain: business > erp-integration > infor-cloudsuite-api-surfaces
region: global
jurisdiction: global
temporal_scope: 2024-2026

# === SYSTEM PROFILE ===
systems:
  - name: "Infor M3 (CloudSuite Distribution/Fashion/Equipment)"
    vendor: "Infor"
    version: "M3 API via ION API Gateway"
    edition: "CloudSuite Distribution, Fashion, Food & Beverage, Equipment"
    deployment: "cloud"
    api_surface: "REST (MIProgram), ION BOD, Data Lake"
  - name: "Infor LN (CloudSuite Industrial Enterprise)"
    vendor: "Infor"
    version: "LN 2025.x OData REST API"
    edition: "CloudSuite Industrial Enterprise"
    deployment: "cloud"
    api_surface: "OData REST, ION BOD, SOAP"
  - name: "Infor CloudSuite Industrial (SyteLine/CSI)"
    vendor: "Infor"
    version: "CSI 10.x/11.x"
    edition: "CloudSuite Industrial"
    deployment: "cloud"
    api_surface: "IDO REST/SOAP, ION BOD, .NET"

# === VERIFICATION ===
last_verified: 2026-03-02
confidence: 0.82
version: 1.0
first_published: 2026-03-02

# === TEMPORAL VALIDITY ===
temporal_validity:
  status: volatile
  last_breaking_change: "2024 - M3 CloudSuite migration to ION API Gateway mandatory for REST access"
  next_review: 2026-08-29
  change_sensitivity: high

# === CONSTRAINTS ===
constraints:
  - "All external API access in CloudSuite (cloud) must go through ION API Gateway - no direct M3/LN/CSI endpoints exposed"
  - "M3 has 6,000+ API transactions (MIPrograms) but each returns max ~1,000 records per call by default (maxrecs parameter)"
  - "LN OData REST APIs must be explicitly modeled and published via ttadv2570m700 session - not all LN functions have REST endpoints"
  - "CSI IDO web services expose only IDO-registered objects - custom tables require IDO registration before API access"
  - "ION API OAuth 2.0 access tokens expire in ~2 hours; refresh tokens idle-expire after 30 days"
  - "Data Lake replication interval is ~10 minutes - not true real-time for bulk data retrieval"
  - "BOD messaging is asynchronous and eventual-consistency - not suitable for synchronous request/response patterns"

# === SKIP CONDITIONS ===
skip_this_unit_if:
  - condition: "User needs Infor CloudSuite authentication setup specifically"
    use_instead: "business/erp-integration/infor-ion-api-authentication/2026"
  - condition: "User needs Salesforce or SAP API surfaces"
    use_instead: "business/erp-integration/salesforce-rest-api/2026 or business/erp-integration/sap-s4hana-api-surfaces/2026"
  - condition: "User needs iPaaS comparison for Infor integration"
    use_instead: "business/erp-integration/ipaas-infor-integration/2026"

# === AGENT HINTS ===
inputs_needed:
  - key: integration_pattern
    question: "What integration pattern do you need?"
    type: choice
    options:
      - "real-time sync (individual records, <1s latency)"
      - "batch/bulk (scheduled, high volume)"
      - "event-driven (BOD messaging, CDC)"
      - "file-based (CSV/XML import/export)"
  - key: data_volume
    question: "What's your daily data volume?"
    type: choice
    options:
      - "< 1,000 records/day"
      - "1,000-100,000 records/day"
      - "> 100,000 records/day"
  - key: direction
    question: "What's the data flow direction?"
    type: choice
    options:
      - "inbound (writing to this ERP)"
      - "outbound (reading from this ERP)"
      - "bidirectional sync"

# === DISTRIBUTION ===
canonical_source: "https://knowledgelib.io/business/erp-integration/infor-cloudsuite-api-surfaces/2026"
suggested_citation: "Source: knowledgelib.io - AI Knowledge Library (verified 2026-03-02)"

# === RELATED UNITS ===
related_kos:
  depends_on: []
  related_to:
    - id: "business/erp-integration/infor-ion-api-authentication/2026"
      label: "Infor ION API Gateway authentication and OAuth 2.0 setup"
  solves:
    - id: "business/erp-integration/infor-m3-erp-cloud-integration/2026"
      label: "Integration playbook using Infor M3 APIs"
  alternative_to:
    - id: "business/erp-integration/sap-s4hana-api-surfaces/2026"
      label: "SAP S/4HANA API surfaces (alternative ERP vendor)"
  often_confused_with:
    - id: "business/erp-integration/infor-ion-api-authentication/2026"
      label: "ION API authentication (this card covers API surfaces, not auth setup)"

# === SOURCES ===
sources:
  - id: src1
    title: "API Gateway or ION API - M3 CloudSuite Solution Overview"
    author: Infor
    url: https://docs.infor.com/m3cs/latest/en-us/m3cslib/solution_overview_m3cloudsuite/zos1659093396395.html
    type: official_docs
    published: 2025-01-15
    reliability: authoritative
  - id: src2
    title: "API Gateway - Infor OS Administration Guide"
    author: Infor
    url: https://docs.infor.com/inforos/2024.x/en-us/useradminlib_cloud/apigatewayag_cloud/vwi1489585692124.html
    type: official_docs
    published: 2024-06-01
    reliability: authoritative
  - id: src3
    title: "How to call M3 API with REST & JSON"
    author: M3 Ideas (Thibaud Lopez Schneider)
    url: https://m3ideas.org/2012/02/23/how-to-call-m3-api-with-rest-json/
    type: technical_blog
    published: 2024-03-15
    reliability: moderate_high
  - id: src4
    title: "OData REST APIs (ttadv2570m700) - LN CloudSuite"
    author: Infor
    url: https://docs.infor.com/lncs/2025.x/en-us/lncslib/lncspov/fpn1530184018755.html
    type: official_docs
    published: 2025-01-01
    reliability: authoritative
  - id: src5
    title: "Infor ION API SDK - GitHub Repository"
    author: Infor
    url: https://github.com/infor-cloud/ion-api-sdk
    type: official_docs
    published: 2024-09-01
    reliability: high
  - id: src6
    title: "CloudSuite Industrial (SyteLine) Integration Guide"
    author: Visual South
    url: https://www.visualsouth.com/blog/infor-cloudsuite-industrial-integrate-existing-systems
    type: technical_blog
    published: 2024-11-20
    reliability: moderate_high
  - id: src7
    title: "Infor ION vs Custom API Integrations"
    author: Sama Integrations
    url: https://samaintegrations.com/infor-ion-vs-custom-api-integrations-which-is-right-for-your-enterprise/
    type: technical_blog
    published: 2025-02-10
    reliability: moderate_high
  - id: src8
    title: "ION API Gateway - OAuth 2.0 Token Management"
    author: Infor
    url: https://docs.infor.com/inforos/2025.x/en-us/useradminlib_cloud/apigatewayag_cloud/fqj1489507806672.html
    type: official_docs
    published: 2025-01-01
    reliability: authoritative
---

# Infor CloudSuite API Surfaces: M3 vs LN vs CloudSuite Industrial

## TL;DR

- **Bottom line**: All three Infor CloudSuite products (M3, LN, CSI) route external API calls through the ION API Gateway with OAuth 2.0, but each exposes fundamentally different native API surfaces -- M3 uses MIProgram REST APIs (6,000+ transactions), LN uses OData REST APIs (modeled per-session), and CSI uses IDO-based REST/SOAP web services. [src1, src4, src6]
- **Key limit**: ION API Gateway access tokens expire in ~2 hours; M3 MIProgram calls default to ~1,000 records max per request; LN OData APIs must be explicitly modeled and published before they are accessible. [src3, src4, src8]
- **Watch out for**: M3 MIProgram REST APIs only support GET requests for the execute endpoint -- there is no native POST/PUT/DELETE distinction; all mutations go through transaction names like "Add", "Chg", "Dlt" in the MIProgram. [src3]
- **Best for**: Multi-product Infor environments where you need to understand which API surface to use for each CloudSuite variant before designing an integration architecture.
- **Authentication**: All three products use OAuth 2.0 via ION API Gateway. Supported flows: Authorization Code, Resource Owner Password, Client Credentials (via Service Account), and SAML Bearer. [src5, src8]

## System Profile

This card compares the API surfaces across the three major Infor CloudSuite ERP product lines: M3 (manufacturing/distribution), LN (industrial enterprise), and CloudSuite Industrial/CSI (formerly SyteLine). All three are deployed on Infor OS in the cloud and share the ION API Gateway as the external-facing API proxy, but each product has a distinct native API architecture that predates the unified gateway layer. This card does NOT cover Infor CloudSuite Financials (Lawson), Infor EAM, or Infor WMS as standalone API surfaces. [src1, src2]

| System | Role | API Surface | Direction |
|---|---|---|---|
| Infor M3 | Manufacturing/Distribution ERP | MIProgram REST (6,000+ transactions) via ION API Gateway | Bidirectional |
| Infor LN | Industrial Enterprise ERP | OData REST APIs (modeled via ttadv2570m700) via ION API Gateway | Bidirectional |
| Infor CSI (SyteLine) | Industrial Manufacturing ERP | IDO REST/SOAP web services via ION API Gateway | Bidirectional |
| ION API Gateway | Unified API proxy (Infor OS) | OAuth 2.0 + throttling + routing | Orchestrator |
| Infor Data Lake | Bulk data retrieval | Compass SQL API / Data Fabric | Outbound (read) |
| ION (Middleware) | Event-driven messaging | BOD XML documents | Bidirectional |

## API Surfaces & Capabilities

Each CloudSuite product exposes different native API surfaces, all accessible through the ION API Gateway. The gateway adds OAuth 2.0 security, throttling, and routing but does not normalize the underlying API patterns. [src1, src2, src7]

| API Surface | Product | Protocol | Best For | Max Records/Request | Rate Limit | Real-time? | Bulk? |
|---|---|---|---|---|---|---|---|
| MIProgram REST | M3 | HTTPS/JSON or XML | Individual record CRUD, business logic | ~1,000 (maxrecs param) | ION Gateway throttling | Yes | No |
| M3 BOD (via ION) | M3 | XML/BOD | Event-driven, async replication | Per-BOD (varies) | ION message throughput | Async | Yes |
| OData REST API | LN | HTTPS/JSON (OData v4) | CRUD, filtered queries, pagination | OData page size (server-set) | ION Gateway throttling | Yes | Limited |
| LN BOD (via ION) | LN | XML/BOD | Event-driven, cross-app integration | Per-BOD (varies) | ION message throughput | Async | Yes |
| LN SOAP | LN | HTTPS/XML | Legacy integrations, complex transactions | Per-operation | ION Gateway throttling | Yes | No |
| IDO REST | CSI | HTTPS/JSON | IDO object CRUD, queries | IDO-dependent | ION Gateway throttling | Yes | No |
| IDO SOAP | CSI | HTTPS/XML | Legacy .NET integrations | IDO-dependent | ION Gateway throttling | Yes | No |
| CSI BOD (via ION) | CSI | XML/BOD | Async event-driven messaging | Per-BOD (varies) | ION message throughput | Async | Yes |
| Data Lake / Compass | All | SQL API / HTTPS | Bulk data extraction, analytics, reporting | Unlimited (query-based) | Query concurrency | Near-RT (~10 min) | Yes |

[src1, src3, src4, src6]

## Rate Limits & Quotas

### Per-Request Limits

| Limit Type | Value | Applies To | Notes |
|---|---|---|---|
| M3 MIProgram max records | ~1,000 default | MIProgram REST execute | Use `maxrecs` matrix parameter to adjust; pagination via repeated calls with offset |
| LN OData page size | Server-configured | LN OData REST API | Use `$top` and `$skip` or `@odata.nextLink` for pagination |
| CSI IDO result set | IDO-configured | CSI IDO REST/SOAP | Depends on IDO definition and server memory |
| ION API Gateway request body | Varies by backend | All via Gateway | Gateway enforces backend limits transparently |
| BOD message size | ~10 MB typical | ION BOD messaging | Large payloads should be chunked into multiple BODs |

[src1, src3, src4]

### Rolling / Daily Limits

| Limit Type | Value | Window | Product Differences |
|---|---|---|---|
| ION API Gateway throttling | Configurable per-endpoint | Per time period (configurable, e.g., 60s) | Spike arrest: configurable maxRequestsPerPeriod; rate smoothing with delay factor |
| ION BOD throughput | Tenant-dependent | Per-minute/hour | Shared across all apps on tenant; varies by Infor cloud tier |
| Data Lake query concurrency | Tenant-dependent | Concurrent | Limited concurrent Compass queries per tenant |
| OAuth 2.0 token requests | Not publicly documented | Per-tenant | Token endpoint has its own rate limiting |

[src2, src8]

### ION API Gateway Throttling Configuration

The gateway supports configurable throttling policies per endpoint with these parameters: [src2]

- `timePeriodInMilliseconds`: Evaluation window (e.g., 60,000 ms = 1 minute)
- `spikeArrest.maxRequestsPerPeriod`: Hard cap per time period (e.g., 1,000)
- `rateSmoothing.delayAfterCount`: Requests before delay kicks in (e.g., 1,000)
- `rateSmoothing.delayFactorInMilliseconds`: Delay applied per excess request (e.g., 1,000 ms)

## Authentication

All three CloudSuite products authenticate external API consumers through the ION API Gateway using OAuth 2.0. The Infor Authorization Server issues tokens after validating credentials downloaded from Infor OS portal. [src5, src8]

| Flow | Use When | Token Lifetime | Refresh? | Notes |
|---|---|---|---|---|
| Authorization Code | Native mobile/desktop apps, web apps | Access: ~2h | Yes (refresh token default 30-day grant) | Requires user interaction for consent; most common for UI-driven integrations [src5] |
| Resource Owner Password | Server-to-server backend services | Access: ~2h | Yes | Requires Service Account AccessKey + SecretKey + ClientID + ClientSecret; recommended for unattended integrations [src5] |
| Client Credentials | Machine-to-machine (no user context) | Access: ~2h | No | Simpler setup but limited to app-level permissions [src5] |
| SAML Bearer | Apps plugged into Infor Ming.le | Access: ~2h | Yes | For Ming.le embedded applications only [src5] |
| Implicit | Single-page applications | Access: ~2h | No | Deprecated in OAuth 2.1; avoid for new development [src5] |

[src5, src8]

### Authentication Gotchas

- **Credentials file (.ionapi) is product-specific**: The downloaded .ionapi credentials file from Infor OS contains the authorization server URL, client ID, client secret, and service account keys. Each Infor environment (dev/test/prod) has a separate credentials file. Do not share across environments. [src5]
- **Refresh tokens idle-expire after 30 days**: Even if configured for indefinite grant lifetime, a refresh token that remains unused for 30 days is automatically invalidated. Long-idle integrations must re-authenticate from scratch. [src8]
- **Refresh token rotation is enabled by default**: Tokens rotate every 8 hours. Your integration must always store and use the latest refresh token returned. Using an old rotated token fails silently. [src8]
- **Resource Owner grant requires four credentials**: ClientID, ClientSecret, Service Account AccessKey, and Service Account SecretKey -- all four are needed. Missing any one causes authentication failure. [src5]

## Constraints

- **ION API Gateway is mandatory for cloud**: In CloudSuite (cloud deployment), there is no way to bypass the ION API Gateway for external API calls. Direct M3/LN/CSI endpoints are not exposed to the internet. [src1, src2]
- **M3 MIProgram REST uses GET for all operations**: The execute endpoint (`/m3api-rest/execute/{program}/{transaction}`) only accepts GET requests. Mutations (create, update, delete) are encoded in the transaction name (e.g., CRS610MI/AddAddress, CRS610MI/ChgBasicData, CRS610MI/DltAddress), not HTTP methods. [src3]
- **LN OData APIs must be modeled first**: Unlike M3's 6,000+ pre-built API transactions, LN REST APIs must be explicitly created in the REST API Modeler (ttadv2570m700 session) and published before they are accessible. Out-of-the-box coverage is limited to standard procurement, logistics, and financial modules. [src4]
- **CSI IDO objects require registration**: Only IDO-registered objects are accessible via REST/SOAP web services. Custom tables or extensions require IDO registration through the CSI development framework (Mongoose). [src6]
- **BOD messaging is fire-and-forget**: ION BOD document flows are asynchronous. There is no synchronous request/response pattern. If you need immediate confirmation, use REST APIs. [src7]
- **Data Lake has ~10-minute replication lag**: Data Lake replication from M3/LN/CSI is near-real-time (~10 minutes), not instant. Do not use Data Lake for transaction-level real-time queries. [src1]

## Integration Pattern Decision Tree

```
START -- Integrate with Infor CloudSuite (M3, LN, or CSI)
|-- Which CloudSuite product?
|   |-- M3 (CloudSuite Distribution/Fashion/Equipment)
|   |   |-- What operation?
|   |   |   |-- Individual record CRUD (< 1,000 records)
|   |   |   |   --> MIProgram REST via ION API Gateway
|   |   |   |   --> URL: /M3/m3api-rest/execute/{Program}/{Transaction}
|   |   |   |-- Bulk data extraction (> 10,000 records)
|   |   |   |   --> Infor Data Lake + Compass SQL API
|   |   |   |-- Event-driven (react to M3 changes)
|   |   |   |   --> ION BOD document flows (Sync/Process verbs)
|   |   |   |-- File-based import
|   |   |       --> ION Connect + file-based integration
|   |-- LN (CloudSuite Industrial Enterprise)
|   |   |-- What operation?
|   |   |   |-- Standard CRUD (procurement, logistics, finance)
|   |   |   |   --> OData REST API via ION API Gateway
|   |   |   |   --> URL: /lnapi/odata/tdapi.{resource}
|   |   |   |-- Custom entity CRUD
|   |   |   |   --> Model API in ttadv2570m700, then OData REST
|   |   |   |-- Complex transactions (multi-step)
|   |   |   |   --> SOAP web services via ION API Gateway
|   |   |   |-- Event-driven
|   |   |   |   --> ION BOD document flows
|   |   |   |-- Bulk data extraction
|   |   |       --> Data Lake + Compass
|   |-- CSI / SyteLine (CloudSuite Industrial)
|       |-- What operation?
|       |   |-- IDO object CRUD
|       |   |   --> IDO REST web service via ION API Gateway
|       |   |-- Legacy .NET integration
|       |   |   --> IDO SOAP web service or .NET extension class
|       |   |-- Event-driven
|       |   |   --> ION BOD document flows or IDO Request XML over HTTP
|       |   |-- Bulk data extraction
|       |       --> Data Lake + Compass
|-- What's the data direction?
|   |-- Inbound (write to ERP) --> Use REST APIs (M3 MIProgram / LN OData / CSI IDO)
|   |-- Outbound (read from ERP)
|   |   |-- Real-time --> REST APIs
|   |   |-- Bulk/analytics --> Data Lake + Compass
|   |-- Bidirectional --> REST for writes + BOD/Data Lake for change detection
|-- Error tolerance?
    |-- Zero-loss --> ION BOD with connection point monitoring + retry
    |-- Best-effort --> REST API with application-level retry
```

## Quick Reference

| Capability | M3 | LN | CSI (SyteLine) |
|---|---|---|---|
| **Primary REST Surface** | MIProgram REST (`/m3api-rest/execute/`) | OData v4 (`/lnapi/odata/`) | IDO REST web services |
| **API Transaction Count** | 6,000+ pre-built MIPrograms | Must be modeled (ttadv2570m700) | IDO-registered objects only |
| **Request Method** | GET only (mutations via transaction names) | GET, POST, PATCH, DELETE (OData standard) | GET, POST, PUT, DELETE |
| **Response Format** | JSON or XML (via Accept header) | JSON (OData) | JSON or XML |
| **URL Pattern** | `/M3/m3api-rest/execute/{Program}/{Transaction}` | `/lnapi/odata/tdapi.{Resource}` | `/IDORequestService/` endpoints |
| **Pagination** | `maxrecs` matrix param + offset | OData `$top`, `$skip`, `@odata.nextLink` | IDO-specific paging |
| **Filtering** | Input params as query string (`?CONO=1&ITNO=ABC`) | OData `$filter`, `$select`, `$expand` | IDO property filters |
| **Event-Driven** | ION BOD (Event Analytics + BOD Processor) | ION BOD (direct publish) | ION BOD or IDO Request XML |
| **Bulk Data** | Data Lake / Compass | Data Lake / Compass | Data Lake / Compass |
| **Auth (Cloud)** | OAuth 2.0 via ION API Gateway | OAuth 2.0 via ION API Gateway | OAuth 2.0 via ION API Gateway |
| **SOAP Support** | Limited (legacy) | Full SOAP web services | Full IDO SOAP |
| **Development Tool** | M3 API Repository | REST API Modeler (ttadv2570m700) | Mongoose / IDO Development |
| **Column Selection** | `returncols` matrix param | OData `$select` | IDO property list |

[src1, src3, src4, src6]

## Step-by-Step Integration Guide

### 1. Obtain ION API credentials from Infor OS

Navigate to Infor OS > ION API > Authorized Apps. Register your external application and download the `.ionapi` credentials file. This file contains your ClientID, ClientSecret, Service Account keys, and the Authorization Server URL. [src5]

```bash
# The .ionapi file is a JSON file with this structure:
# {
#   "ti": "TenantID",
#   "cn": "ClientName",
#   "dt": "Backend Service",
#   "ci": "ClientID_GUID",
#   "cs": "ClientSecret",
#   "iu": "https://{tenant}.ionapi.{region}.inforcloudsuite.com",
#   "pu": "https://{tenant}.ionapi.{region}.inforcloudsuite.com/{tenant}/as/token.oauth2",
#   "oa": "authorization.oauth2",
#   "ot": "token.oauth2",
#   "or": "revoke_token.oauth2",
#   "saak": "ServiceAccountAccessKey",
#   "sask": "ServiceAccountSecretKey"
# }
```

**Verify**: The `.ionapi` file downloads successfully and contains all required fields (ci, cs, pu, saak, sask).

### 2. Acquire OAuth 2.0 access token

Use the Resource Owner Password grant for server-to-server integrations. Send credentials to the token endpoint from the `.ionapi` file. [src5, src8]

```bash
# Input:  .ionapi credentials file values
# Output: OAuth 2.0 access_token + refresh_token

curl -s -X POST "https://{tenant}.ionapi.{region}.inforcloudsuite.com/{tenant}/as/token.oauth2" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "{ClientID}:{ClientSecret}" \
  -d "grant_type=password&username={ServiceAccountAccessKey}&password={ServiceAccountSecretKey}"

# Response:
# {
#   "access_token": "eyJ...",
#   "token_type": "Bearer",
#   "expires_in": 7200,
#   "refresh_token": "abc123..."
# }
```

**Verify**: Response contains `access_token` and `token_type: Bearer`. The `expires_in` should be ~7200 (2 hours).

### 3. Call M3 MIProgram REST API

Use the access token to call an M3 API transaction. All M3 API calls use the GET method through the execute endpoint. [src3]

```bash
# Input:  access_token, M3 program name, transaction name, parameters
# Output: JSON array of MIRecords

curl -s "https://{tenant}.ionapi.{region}.inforcloudsuite.com/M3/m3api-rest/execute/CRS610MI/LstByNumber;maxrecs=20;returncols=CUNO,CUNM,STAT?CONO=1" \
  -H "Authorization: Bearer {access_token}" \
  -H "Accept: application/json"

# Response:
# {
#   "Program": "CRS610MI",
#   "Transaction": "LstByNumber",
#   "MIRecord": [
#     { "NameValue": [
#       { "Name": "CUNO", "Value": "Y30000" },
#       { "Name": "CUNM", "Value": "Acme Corp" },
#       { "Name": "STAT", "Value": "20" }
#     ]}
#   ]
# }
```

**Verify**: Response contains `MIRecord` array with `NameValue` pairs. HTTP status is 200.

### 4. Call LN OData REST API

Use the same token to call an LN OData endpoint. LN supports standard OData query operators. [src4]

```bash
# Input:  access_token, OData resource path
# Output: OData JSON response

curl -s "https://{tenant}.ionapi.{region}.inforcloudsuite.com/lnapi/odata/tdapi.PurchaseOrders?\$top=10&\$select=OrderNumber,Supplier,TotalAmount&\$filter=Status eq 'Open'" \
  -H "Authorization: Bearer {access_token}" \
  -H "Accept: application/json"

# Response: Standard OData JSON with @odata.context, value array
```

**Verify**: Response contains `@odata.context` and `value` array with requested fields.

## Code Examples

### Python: Query M3 customers via MIProgram REST

```python
# Input:  .ionapi credentials file path
# Output: List of M3 customer records

import json
import requests

# Load .ionapi credentials
with open("credentials.ionapi", "r") as f:
    creds = json.load(f)

base_url = creds["iu"]
token_url = creds["pu"]

# Step 1: Acquire token (Resource Owner grant)
token_resp = requests.post(
    token_url,
    auth=(creds["ci"], creds["cs"]),
    data={
        "grant_type": "password",
        "username": creds["saak"],
        "password": creds["sask"],
    },
)
token_resp.raise_for_status()
access_token = token_resp.json()["access_token"]

# Step 2: Call M3 MIProgram
headers = {
    "Authorization": f"Bearer {access_token}",
    "Accept": "application/json",
}
api_url = (
    f"{base_url}/M3/m3api-rest/execute/"
    "CRS610MI/LstByNumber;maxrecs=100;returncols=CUNO,CUNM,STAT"
    "?CONO=1"
)
resp = requests.get(api_url, headers=headers)
resp.raise_for_status()

# Step 3: Parse M3 response (NameValue pair format)
for record in resp.json().get("MIRecord", []):
    fields = {nv["Name"]: nv["Value"] for nv in record["NameValue"]}
    print(f"Customer: {fields['CUNO']} - {fields['CUNM']} (Status: {fields['STAT']})")
```

### JavaScript/Node.js: Query LN OData API

```javascript
// Input:  .ionapi credentials JSON, LN OData resource
// Output: LN purchase orders

// npm install node-fetch@2
const fetch = require("node-fetch");
const fs = require("fs");

const creds = JSON.parse(fs.readFileSync("credentials.ionapi", "utf8"));

async function getLnData() {
  // Step 1: Acquire token
  const tokenResp = await fetch(creds.pu, {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      Authorization: `Basic ${Buffer.from(`${creds.ci}:${creds.cs}`).toString("base64")}`,
    },
    body: `grant_type=password&username=${creds.saak}&password=${creds.sask}`,
  });
  const { access_token } = await tokenResp.json();

  // Step 2: Call LN OData endpoint
  const apiUrl = `${creds.iu}/lnapi/odata/tdapi.PurchaseOrders?$top=10&$select=OrderNumber,Supplier`;
  const resp = await fetch(apiUrl, {
    headers: {
      Authorization: `Bearer ${access_token}`,
      Accept: "application/json",
    },
  });
  const data = await resp.json();
  console.log("Purchase Orders:", data.value);
}

getLnData().catch(console.error);
```

### cURL: Refresh an expired token

```bash
# Input:  refresh_token from initial auth, ClientID, ClientSecret
# Output: New access_token + rotated refresh_token

curl -s -X POST "https://{tenant}.ionapi.{region}.inforcloudsuite.com/{tenant}/as/token.oauth2" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "{ClientID}:{ClientSecret}" \
  -d "grant_type=refresh_token&refresh_token={your_refresh_token}"

# IMPORTANT: Store the NEW refresh_token from this response.
# The old refresh_token is rotated and will not work again.
```

## Data Mapping

### API Response Format Differences

| Aspect | M3 MIProgram | LN OData | CSI IDO |
|---|---|---|---|
| **Record structure** | `MIRecord[].NameValue[]` (name/value pairs) | Standard OData entities (key/value JSON) | IDO property collections |
| **Field naming** | 4-char codes (CUNO, CUNM, ITNO, WHLO) | Full names (CustomerNumber, ItemDescription) | .NET property names (CustomerNum, Description) |
| **Date format** | YYYYMMDD as string (e.g., "20260302") | ISO 8601 (e.g., "2026-03-02T00:00:00Z") | .NET DateTime format |
| **Amount fields** | Integer (smallest unit) or decimal string | Decimal | Decimal |
| **Null handling** | Empty string `""` for null | JSON `null` | JSON `null` or absent |
| **Boolean** | "1"/"0" as string | `true`/`false` | `true`/`false` |
| **Multi-value** | Separate API calls per value | OData `$expand` for navigation properties | IDO relation loading |

[src3, src4, src6]

### Data Type Gotchas

- **M3 4-character field codes are not self-documenting**: Field CUNO means "Customer Number", ITNO means "Item Number", WHLO means "Warehouse". You need the M3 API Repository to look up field meanings. The WADL endpoint (`/m3api-rest/application.wadl`) provides some metadata but is incomplete. [src3]
- **M3 dates are 8-digit strings, not ISO dates**: A date field returns "20260302" not "2026-03-02". Your integration must parse YYYYMMDD format manually. Empty dates may return "0" or "00000000". [src3]
- **LN OData uses company-scoped data**: LN is inherently multi-company. API responses include data from the company context of the authenticated user. To access another company's data, you need route authorization for that company in ttams0100m000. [src4]
- **CSI IDO property names differ from database column names**: The IDO layer abstracts the database schema. A database column `co_num` might be exposed as `CoNum` or `CompanyNumber` in the IDO layer. Always reference IDO documentation, not database schema. [src6]

## Error Handling & Failure Points

### Common Error Codes

| Code | Meaning | Cause | Resolution |
|---|---|---|---|
| 401 Unauthorized | OAuth token expired or invalid | Access token has expired (>2h) or was revoked | Acquire new token; check refresh token validity [src8] |
| 403 Forbidden | Insufficient permissions | Service account lacks required role for the API endpoint | Check ION API authorized app permissions and backend ERP user roles [src5] |
| 404 Not Found | Invalid API endpoint | Wrong MIProgram name, unpublished LN OData API, or unregistered CSI IDO | Verify program/resource exists: M3 API Repository, LN ttadv2570m700, CSI IDO registry [src3, src4] |
| 429 Too Many Requests | Throttle limit hit | ION API Gateway spike arrest or rate smoothing triggered | Implement exponential backoff; respect Retry-After header if present [src2] |
| 500 Internal Server Error | Backend ERP error | M3/LN/CSI application-level error (bad input, business rule violation) | Check response body for ERP-specific error message; M3 returns error in MIRecord with "@type":"ErrorMessage" [src3] |
| NOK (M3-specific) | Transaction rejected | M3 MIProgram business validation failed | Parse the error message from the MIRecord response; common causes: invalid field value, missing required field, locked record [src3] |

[src3, src5, src8]

### Failure Points in Production

- **Refresh token rotation causes silent auth failures**: ION API Gateway rotates refresh tokens every 8 hours by default. If your application stores and reuses an old refresh token (before rotation), the auth request fails. Fix: `Always persist the latest refresh_token returned from every token refresh call. Never cache the old one.` [src8]
- **M3 MIProgram returns 200 OK for business errors**: M3 API transactions return HTTP 200 even when the business logic rejects the operation. The error is embedded in the response body as an error record. Fix: `Always parse the response body for @type: ErrorMessage or check the nrOfFailedTransactions field.` [src3]
- **LN OData API disappears after upgrade**: LN product updates can reset the REST API Modeler configuration. Custom-modeled APIs may need to be re-published after a CloudSuite LN upgrade. Fix: `Document all custom OData API definitions and include re-publication in your upgrade runbook.` [src4]
- **ION BOD messages silently dropped**: If the receiving connection point is misconfigured or the target application is down, BOD messages queue but may eventually be discarded after the retention period. Fix: `Monitor ION Desk connection point health and configure alert notifications for failed document flows.` [src7]
- **Data Lake schema changes on ERP upgrade**: When M3/LN/CSI tables change during an upgrade, the Data Lake schema updates accordingly, potentially breaking downstream Compass queries. Fix: `Pin Compass queries to specific schema versions or validate schema compatibility before upgrading.` [src1]

## Anti-Patterns

### Wrong: Treating M3 MIProgram REST like standard REST

```python
# BAD -- M3 does not use POST/PUT/DELETE methods
# This will return 405 Method Not Allowed
requests.post(f"{base}/M3/m3api-rest/execute/CRS610MI/AddAddress",
              json={"CUNO": "Y30000", "ADRT": "1"})
```

### Correct: Use GET with transaction names for all M3 operations

```python
# GOOD -- M3 uses GET for everything; mutation is in the transaction name
requests.get(
    f"{base}/M3/m3api-rest/execute/CRS610MI/AddAddress"
    "?CONO=1&CUNO=Y30000&ADRT=1&CUA1=123+Main+St",
    headers={"Authorization": f"Bearer {token}"}
)
```

### Wrong: Assuming all LN functions have REST APIs

```python
# BAD -- calling an LN OData endpoint that hasn't been modeled
resp = requests.get(f"{base}/lnapi/odata/tdapi.CustomEntity")
# Returns 404 because the API was never published in ttadv2570m700
```

### Correct: Verify API availability in REST API Modeler first

```python
# GOOD -- check LN OData API catalog before integration design
# In LN: Session ttadv2570m700 > list published APIs
# Only use endpoints that appear in the published API list
# For custom entities: model the API first, then consume
resp = requests.get(
    f"{base}/lnapi/odata/tdapi.PurchaseOrders?$top=1",
    headers={"Authorization": f"Bearer {token}"}
)
```

### Wrong: Using REST API for bulk data extraction

```python
# BAD -- looping through 100K records via M3 MIProgram
all_items = []
offset = 0
while True:  # This will take hours and may hit throttle limits
    resp = requests.get(f"{base}/M3/m3api-rest/execute/MMS200MI/LstByNumber;maxrecs=1000?CONO=1")
    records = resp.json().get("MIRecord", [])
    if not records:
        break
    all_items.extend(records)
    offset += 1000
```

### Correct: Use Data Lake for bulk extraction

```python
# GOOD -- use Compass SQL API for large datasets
# Data Lake is optimized for analytics and bulk reads
# Near-real-time (~10 min lag) but handles millions of records
resp = requests.get(
    f"{base}/DATAFABRIC/compass/v2/schemas/M3/tables/OCUSMA",
    headers={"Authorization": f"Bearer {token}"},
    params={"$filter": "OKCONO eq 1", "$top": 100000}
)
```

## Common Pitfalls

- **Confusing ION API Gateway with ION middleware**: ION API Gateway handles REST API proxying with OAuth 2.0. ION middleware handles BOD-based asynchronous messaging. They are separate components. Using the wrong one for your pattern (e.g., BODs for synchronous reads) causes architecture failures. Fix: `Use ION API Gateway for synchronous REST calls; use ION middleware (ION Desk) for async event-driven BOD flows.` [src1, src7]
- **Not handling M3 response format quirks**: M3 returns data as NameValue pair arrays, not flat JSON objects. Developers accustomed to standard REST APIs write code that breaks on M3's nested format. Fix: `Build a response transformer that converts MIRecord[].NameValue[] to flat key-value objects before passing to business logic.` [src3]
- **Hardcoding ION API Gateway URLs**: The gateway URL varies by region and tenant (e.g., `inforcloudsuite.com` vs `inforcloud.com`). Fix: `Always read the base URL from the .ionapi credentials file (the "iu" field). Never hardcode.` [src5]
- **Ignoring M3 company/division context**: M3 APIs require CONO (company) and often DIVI (division) parameters. Omitting them may return data from an unexpected company or error out. Fix: `Always include CONO parameter in M3 MIProgram calls. Check whether DIVI is required for the specific transaction.` [src3]
- **Not testing with production-scale data volumes**: M3 maxrecs defaults are low. LN OData pagination may behave differently with large result sets. Fix: `Load-test against a sandbox with production-equivalent data volumes before go-live. Validate pagination works for your largest entities.` [src1, src4]
- **Treating BOD delivery as guaranteed**: ION BOD messaging is reliable but not guaranteed in edge cases (connection point failure, tenant maintenance). Fix: `Implement reconciliation jobs that compare source and target data periodically, independent of BOD flow.` [src7]

## Diagnostic Commands

```bash
# Test ION API Gateway authentication (acquire token)
curl -s -X POST "https://{tenant}.ionapi.{region}.inforcloudsuite.com/{tenant}/as/token.oauth2" \
  -u "{ClientID}:{ClientSecret}" \
  -d "grant_type=password&username={AccessKey}&password={SecretKey}" | jq .

# Test M3 API connectivity (list first 5 customers)
curl -s "https://{tenant}.ionapi.{region}.inforcloudsuite.com/M3/m3api-rest/execute/CRS610MI/LstByNumber;maxrecs=5?CONO=1" \
  -H "Authorization: Bearer {TOKEN}" \
  -H "Accept: application/json" | jq .

# Test LN OData API connectivity
curl -s "https://{tenant}.ionapi.{region}.inforcloudsuite.com/lnapi/odata/tdapi.PurchaseOrders?\$top=1" \
  -H "Authorization: Bearer {TOKEN}" \
  -H "Accept: application/json" | jq .

# Check M3 API program availability (WADL discovery)
curl -s "https://{tenant}.ionapi.{region}.inforcloudsuite.com/M3/m3api-rest/application.wadl" \
  -H "Authorization: Bearer {TOKEN}" | head -50

# Revoke a token (cleanup)
curl -s -X POST "https://{tenant}.ionapi.{region}.inforcloudsuite.com/{tenant}/as/revoke_token.oauth2" \
  -u "{ClientID}:{ClientSecret}" \
  -d "token={TOKEN}&token_type_hint=access_token"
```

## Version History & Compatibility

| Change | Date | Impact | Migration Notes |
|---|---|---|---|
| ION API Gateway mandatory for M3 CloudSuite | 2024 | Breaking for on-prem to cloud migrations | All direct M3 API REST calls must be rerouted through ION API Gateway with OAuth 2.0 [src1] |
| LN REST API Modeler (ttadv2570m700) | 2023 | New feature | Enables custom OData REST API creation for LN; replaces some SOAP-only scenarios [src4] |
| Data Lake / Compass SQL API | 2022-2024 | New feature | Preferred method for bulk data extraction from all CloudSuite products [src1] |
| Infor OS unified ION API Gateway | 2021-2022 | Architecture change | Single gateway layer across M3, LN, CSI; unified OAuth 2.0 [src2] |
| M3 BOD Processor replaces Media Management | 2023 | Migration required | Outbound messages from M3 now triggered by Event Analytics + BOD Processor instead of Media Management [src1] |

[src1, src2, src4]

### Deprecation Policy

Infor does not publish a formal API deprecation timeline in the same way as Salesforce or SAP. API surfaces evolve with each CloudSuite release (typically 2x/year). Legacy SOAP interfaces remain supported but are not being enhanced. Infor's strategic direction is REST via ION API Gateway + Data Lake for bulk. Always verify API availability against the current release's API catalog on the Infor Developer Portal. [src1, src2]

## When to Use / When Not to Use

| Use When | Don't Use When | Use Instead |
|---|---|---|
| Comparing API surfaces across M3, LN, and CSI for architecture decisions | Need deep-dive on a single product's API rate limits | Product-specific API capability card |
| Designing a multi-product Infor integration (e.g., M3 + LN) | Need authentication setup instructions | business/erp-integration/infor-ion-api-authentication/2026 |
| Evaluating which Infor CloudSuite product to integrate with | Need iPaaS/middleware comparison for Infor | business/erp-integration/ipaas-infor-integration/2026 |
| Understanding Infor's API landscape before a cloud migration | Need on-premise Infor integration patterns | On-prem patterns differ significantly; ION API Gateway is cloud-only |

## Cross-System Comparison

| Capability | M3 | LN | CSI (SyteLine) | Notes |
|---|---|---|---|---|
| **API Style** | MIProgram REST (GET-only) | OData v4 REST | IDO REST/SOAP | M3 is most unusual; LN is most standards-compliant |
| **Pre-built API Coverage** | 6,000+ MIProgram transactions | Limited (must model in ttadv2570m700) | IDO-registered objects only | M3 has by far the broadest out-of-the-box coverage |
| **HTTP Methods** | GET only | GET, POST, PATCH, DELETE | GET, POST, PUT, DELETE | M3 encodes mutations in transaction names |
| **Response Format** | NameValue pair arrays | Standard OData JSON | IDO property collections | M3 requires custom parsing; LN/CSI are more standard |
| **Query Filtering** | Query string parameters | OData $filter, $select, $expand, $orderby | IDO property filters | LN has the richest query language |
| **Pagination** | maxrecs matrix param | OData $top/$skip/@odata.nextLink | IDO-specific | LN follows OData standard |
| **Event-Driven** | ION BOD (Event Analytics) | ION BOD (direct) | ION BOD or IDO Request XML | All share ION BOD infrastructure |
| **Bulk Data** | Data Lake + Compass | Data Lake + Compass | Data Lake + Compass | Shared Infor OS capability |
| **Authentication** | OAuth 2.0 (ION API Gateway) | OAuth 2.0 (ION API Gateway) | OAuth 2.0 (ION API Gateway) | Identical auth layer |
| **Developer Tooling** | M3 API Repository | REST API Modeler (ttadv2570m700) | Mongoose / IDO dev framework | M3 has most mature tooling |
| **SOAP Support** | Limited / legacy | Full | Full (IDO SOAP) | M3 is REST-first; LN and CSI still actively use SOAP |
| **Standards Compliance** | Proprietary REST | OData v4 | Proprietary REST/SOAP | LN is the most standards-compliant |

[src1, src3, src4, src6]

## Important Caveats

- API surface availability and behavior can change with each CloudSuite release (typically twice per year). Always validate against the current release's documentation on docs.infor.com. [src1]
- Rate limits and throttling are tenant-specific and configurable by Infor cloud operations -- the numbers in this card reflect typical configurations, not hard guarantees. Contact your Infor TAM for tenant-specific limits. [src2]
- M3's 6,000+ MIProgram transactions are not all equally mature -- some are legacy and may behave inconsistently. Check the M3 API Repository for transaction status (GA, deprecated, restricted). [src3]
- LN OData REST APIs are a newer feature. Coverage is growing with each release, but not all LN business processes have modeled REST APIs yet. Plan for SOAP fallback in gaps. [src4]
- CSI's IDO architecture is tightly coupled to the .NET framework. If you are not in a .NET ecosystem, prefer the REST/JSON surface over the SOAP/XML surface. [src6]
- On-premise Infor deployments have fundamentally different API access patterns (no ION API Gateway, direct network access, different auth). This card covers cloud deployments only. [src1, src2]

## Related Units

- [Infor ION API Gateway authentication and OAuth 2.0 setup](/business/erp-integration/infor-ion-api-authentication/2026)
- [Integration playbook using Infor M3 APIs](/business/erp-integration/infor-m3-erp-cloud-integration/2026)
- [SAP S/4HANA API surfaces (alternative ERP vendor)](/business/erp-integration/sap-s4hana-api-surfaces/2026)
