# How to Call M3 API (MI Programs) Through ION API

> Source: https://netray.co/erp-help/m3-api-via-ion-api-how-to-call
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: ERP Help

## Short answer

Calling M3 from an external system today almost always means going through ION API rather than the older direct MvxAPI SOAP endpoint: you create an ION API authorized app or service account in the ION API portal, download its .ionapi credential file, obtain an OAuth 2.0 access token, and call the M3 MI program transaction through the m3api-rest execute endpoint with that token.

## Kind

advanced

## System

infor-m3

## Erp

Infor M3 (M3 Business Engine)

## Module

M3 API / ION API

## Query

How do I call M3 API (MI programs) through ION API

## Alternate Queries

- M3 MI program ION API REST call setup
- M3 ion api execute endpoint format
- M3 API service account ionapi file
- M3 REST API authentication OAuth setup

## Applies To

Infor M3 Business Engine 10.x-14.x on CloudSuite, ION API, m3api-rest

## Steps

### Set up and make an M3 MI call via ION API

**Items:**

In the ION API portal, create an authorized app (service account, client credentials flow, for a server-to-server integration) or an authorized app for a user-delegated flow if the caller needs to act as a specific M3 user.

Grant the authorized app access to the M3 API scope/service the integration needs, following your Infor OS administrator's grant process for that tenant.

Download the resulting .ionapi file, which contains the client ID, client secret, token endpoint and the tenant-specific ION API gateway URL the integration will use.

Request an OAuth 2.0 access token from the token endpoint in the .ionapi file using client credentials (or the appropriate grant type for your flow), and cache it until it expires rather than requesting a new token per call.

Build the M3 API request URL against the m3api-rest execute pattern for your tenant, specifying the MI program and transaction name (for example CRS610MI/Get or OIS100MI/AddHead) as path segments.

Pass required input fields as query parameters or a JSON body depending on the m3api-rest calling convention your integration uses, including the company number (CONO) where relevant.

Send the request with the OAuth bearer token in the Authorization header, and parse the response for the errorType/errorField/errorMessage attributes before assuming success just because the HTTP status code was 200.

For list-type transactions, respect maxReturnedRecords and pagination rather than assuming the first response page contains the full result set.

Log the raw response for the first several calls during integration development - error attributes on M3 API responses carry more diagnostic detail than the wrapping HTTP status alone.

## Sections

### Why ION API instead of calling M3 directly

**Body:**

Older integrations often called the MvxAPI SOAP endpoint or m3api-rest directly against the M3 server with basic authentication. On CloudSuite tenants that direct path is generally not exposed or not recommended; ION API is Infor's supported gateway layer that handles authentication (OAuth 2.0), routing to the correct M3 environment, and centralized authorization management, so new integrations should be built against ION API even though the underlying M3 API (MI program) request and response shape is unchanged.

This matters practically because an integration built against the old direct-connection pattern will not simply need a URL change to move to ION API - it needs a real OAuth token acquisition step added, and the authorized app's granted scope has to actually include the M3 API service being called, which is a common gap when a new integration is added to an existing ION API app instead of getting its own properly scoped authorization.

### Reading the response correctly

**Body:**

An M3 MI call routed through ION API can return HTTP 200 while the underlying M3 transaction still failed - the errorType, errorField and errorMessage attributes on the response body are the real success/failure signal, not the HTTP status code. Integration code that only checks the HTTP status will silently treat failed M3 transactions (a validation error, a locked record, a missing key) as successful, which is one of the most common production bugs in first-time M3-ION integrations.

For list transactions specifically, the maxReturnedRecords parameter caps how many rows come back in a single call; integrations that assume the full result set arrived in one response will silently process partial data on any list larger than that cap unless pagination is implemented.

### Client credentials versus delegated user flows

**Body:**

A server-to-server integration (a nightly batch job, a middleware sync) typically uses the client credentials grant with a dedicated M3 service account, which keeps the integration's activity auditable under its own identity rather than a real user's. A flow that needs to act as the actual logged-in user - for example a custom app showing a user their own M3 data with their own authorization - uses a delegated/authorization code flow instead, and the two require different authorized app configurations in the ION API portal, so decide which pattern fits before setting up the app rather than after building the integration.

## Pitfalls

- Reusing an authorized app's existing scope for a new integration without confirming it actually grants access to the specific M3 API service being called.
- Treating HTTP 200 as success without checking the errorType/errorField attributes in the M3 API response body.
- Requesting a new OAuth token on every single API call instead of caching it until near expiry, which needlessly loads the token endpoint.
- Assuming a list transaction's first response page is the complete result set and ignoring maxReturnedRecords and pagination.
- Using a delegated user flow for a batch integration (or vice versa), creating either unnecessary user dependency or an audit trail that does not reflect who actually triggered the transaction.
- Hardcoding the company number (CONO) instead of passing it explicitly, which breaks silently the first time the integration is pointed at a multi-company tenant.

## Ai Angle

ERPray agents that already call M3 through ION API for day-to-day Q&A can reuse the same authorized app and MI program calls that a custom integration would build from scratch, which is often the fastest way for a team to validate a proposed integration's field mapping and error handling before committing engineering time to a bespoke connector.

## Faq

### Do I still call MvxAPI SOAP directly for new M3 integrations?

**Answer:** For CloudSuite tenants, new integrations should go through ION API rather than a direct SOAP connection; the underlying MI program request and response shape is the same, but authentication, routing and authorization are handled by ION API.

### Why does my M3 API call via ION API return HTTP 200 but the record was not created?

**Answer:** HTTP 200 only confirms the ION API gateway processed the request successfully - check the errorType, errorField and errorMessage attributes in the response body, which is where M3 reports whether the underlying MI transaction actually succeeded.

### What is in the .ionapi file and can I reuse it across integrations?

**Answer:** The .ionapi file contains the client ID, client secret, token endpoint and gateway URL for one specific authorized app; it can be reused by anything that legitimately needs that app's granted scope, but a new integration with different access needs should generally get its own authorized app for cleaner auditing.

### How do I know if my authorized app has access to the M3 API I need?

**Answer:** Check the granted scopes/services on the authorized app in the ION API portal against the specific M3 API service the integration calls - a 401 or 403 response on an otherwise correctly formed request usually means the scope was never granted rather than a credentials problem.

## Search terms

M3 API ION API, M3 m3api-rest execute endpoint, M3 API OAuth 2.0 setup, ionapi file M3 integration, M3 MI program REST call, M3 API service account, ION API authorized app M3, M3 API errorType errorField

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
