AdvancedInfor M3 (M3 Business Engine)M3 API / ION API

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

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

Also searched as

  • 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

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.

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

Set up and make an M3 MI call via ION API

  1. 1In 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.
  2. 2Grant the authorized app access to the M3 API scope/service the integration needs, following your Infor OS administrator's grant process for that tenant.
  3. 3Download 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.
  4. 4Request 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.
  5. 5Build 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.
  6. 6Pass 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.
  7. 7Send 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.
  8. 8For list-type transactions, respect maxReturnedRecords and pagination rather than assuming the first response page contains the full result set.
  9. 9Log 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.

Why ION API instead of calling M3 directly

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

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

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.

Common 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.

How an ERP-grounded AI assistant handles this

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.

Frequently asked questions

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

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?

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?

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?

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.

Related

Advanced

Paging M3 API MI List Transactions Past the Default Record Limit

M3 List transactions (the read/browse transaction most MI programs expose, such as CRS610MI.LstByNumber or OIS100MI.LstOrderHead) cap the rows returned per call using the MaxReturnedRecords input field, and by default many clients leave it low or unset, which looks like the API silently truncating results. Set MaxReturnedRecords explicitly, then loop the call using the last key values from the previous page as the starting position until fewer rows than the limit come back.

Error fix

M3 API Error: Not Authorized to Program

Not authorized to program (or the equivalent transaction-level authorization error) means the M3 user ID the integration authenticates as can log in fine but has not been granted access to that specific MI program, transaction, or company/division through its authority group. Fixing it means adding the program/transaction to the integration user's authority group in M3, not changing anything in the calling code.

Error fix

Fix a 401 Unauthorized error from Infor ION API

A 401 from ION API almost always means the credentials in the .ionapi file no longer match what ION API Gateway expects - not that the password is simply wrong. Check whether the Authorized App or service account behind the file was revoked, regenerated, expired, or issued for a different tenant, then re-test with a direct OAuth2 client_credentials call before touching any calling code.

Error fix

M3 API Error: Record already exist

Record already exist means the MI Add transaction you called is trying to insert a key that is already present in the target M3 table, most often because a prior call succeeded and was retried, or because the key fields you built do not match what you think they match. Read the errorField and errorFieldGroup attributes on the response to see exactly which key field M3 flagged, then either switch to the matching Chg (change) transaction or fix the key construction in the caller.

How-to

How to Build a Grid Mapping in M3 Enterprise Collaborator (MEC)

M3 Enterprise Collaborator (MEC) moves data between an external format (EDI, flat file, XML) and M3's own API by chaining a collection step (getting the document in), a grid mapping step (field-level transformation from source structure to M3 API call structure), and a delivery step (executing the mapped MI transaction). Building a new mapping means defining the source document structure, building the grid that maps each source field to its M3 API field, and testing with representative sample documents before going live.

How-to

How to Add a Personalization Script to an M3 H5 Panel

M3 H5 lets an administrator attach a JavaScript personalization script to a specific panel of a specific program, using the MForms client API to read fields, react to panel and field events, and adjust the UI (hide fields, set defaults, validate input) without modifying the underlying M3 program. Scripts are written and attached through Personalization mode in H5, saved against the panel/program combination, and deployed to the users or roles who should see the behavior.

AI for ERP

AI Agents Over Infor ION API, BODs, and the Infor Data Lake

Build AI agents on Infor ION API Gateway, BODs, and Data Lake, alongside or instead of Infor's own GenAI features, with your choice of model and hosting.

AI for ERP

AI for Infor M3: A Practical Path from MI Programs to a Private Assistant

Add grounded AI to Infor M3: natural-language answers over MI programs and MEC, agents for distribution and manufacturing, on-prem or private cloud in Europe.

Stuck on Infor M3 (M3 Business Engine)?

Talk to engineers who work inside Infor M3 (M3 Business Engine) every week, and who build private AI that answers these questions from your own ERP data.