# Fix a 401 Unauthorized error from Infor ION API

> Source: https://netray.co/erp-help/infor-ion-api-oauth-401-unauthorized-fix
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: ERP Help

## Short answer

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.

## Kind

error

## System

infor-os

## Erp

Infor OS / ION API

## Module

ION API / Security

## Query

infor ion api 401 unauthorized

## Alternate Queries

- ionapi file 401 error
- infor ion api oauth token invalid
- service account saak sask 401
- ion api gateway unauthorized app

## Applies To

Infor OS Portal, ION API Gateway, CloudSuite tenants using .ionapi service account or authorized app credentials

## Steps

### Fix a 401 Unauthorized error from Infor ION API

**Items:**

Confirm which .ionapi file the calling application is using and open it in a text editor to check the ti (tenant), ci (client id), and iu (IFS URL) values.

Test the credentials directly against the identity provider with a client_credentials grant to the ot (OAuth token) endpoint listed in the .ionapi file, using ci and cs as client id and secret.

If the .ionapi file is a service account type (it contains saak and sask), confirm the service account is still Enabled in Infor OS Portal > Security > Authorization > Service Accounts and has not passed its expiration date.

In ION API Gateway (Infor OS Portal > Administration > ION API), open the Authorized App entry the .ionapi file was generated from and check it has not been Revoked or Regenerated - regenerating credentials invalidates every .ionapi file issued before it.

Decode the JWT returned (or the one you expect to receive) with any JWT decoder and compare the exp and iat claims against real server time - clock skew of even a few minutes on the calling server produces a silent 401.

Verify the scopes/APIs assigned to the Authorized App actually include the target API (for example IONSERVICES, M3, or LN) - a valid token for the wrong scope also returns 401 on that endpoint.

If the call is from a script or middleware, download a fresh .ionapi file rather than reusing an old copy, since it can go stale silently after an IFS tenant migration, an SSO change, or a Data Lake / ION rebuild.

Re-test the same call from Postman using a plain client_credentials request to isolate whether the fault is the credentials themselves or a bug in the calling code.

## Sections

### Why ION API returns 401 instead of a clearer message

**Body:**

The .ionapi file is a configuration bundle, not a credential on its own. It packages the tenant id, the OAuth authorization and token endpoints, the client id/secret pair, and (for service accounts) an saak/sask key pair used in a client_credentials style exchange against the Infor Federated Services (IFS) identity provider. ION API Gateway only trusts a token if every part of that chain still matches what is registered for the Authorized App.

There are two distinct .ionapi shapes in most tenants: an Authorized App credential set up for interactive or server-to-server API calls, and a Backend service account credential set up for scheduled or unattended jobs. They authenticate through the same token endpoint but are managed, expired, and revoked independently in ION API Gateway, which is why one integration can keep working while a sibling job suddenly starts failing.

### The most common real-world causes

**Body:**

In practice the majority of 401s trace back to one of a handful of causes: someone regenerated the Authorized App's client secret in ION API Gateway (often while cleaning up unused apps) and the old .ionapi is still deployed somewhere; a service account passed its configured expiration or rotation date; or the .ionapi file being used in production is actually a test/dev download pointed at the wrong tenant.

A less obvious cause is an IFS tenant rename or migration - after a CloudSuite tenant is moved or renamed, previously issued .ionapi files can stop authenticating even though nothing changed in the calling code, because the ti value no longer resolves the way it did.

### Decoding the token to see the real problem

**Body:**

Do not guess - get the actual token exchange in front of you. A direct call against the token endpoint from the .ionapi file, with the client id and secret as form parameters, will either return a token (proving the credentials are valid and the problem is in the calling app) or return the identity provider's own error, which is usually far more specific than the generic 401 the downstream API shows.

**Code:**

- curl -X POST "<ot-value-from-ionapi>" \
-   -d "grant_type=client_credentials" \
-   -d "client_id=<ci-value>" \
-   -d "client_secret=<cs-value>"

### When it is not the credentials at all

**Body:**

If the direct token call succeeds but the actual API call still fails with 401, look one layer up: a reverse proxy or middleware stripping the Authorization header before it reaches ION API Gateway, an IP allowlist configured on the Authorized App that blocks the calling server's egress IP, or a scope mismatch where the token is valid but not authorized for the specific API path being called.

## Pitfalls

- Reusing a .ionapi file after someone regenerates the Authorized App's credentials in ION API Gateway - the old file keeps failing with no warning that it was invalidated.
- Confusing a Backend service account .ionapi with an Authorized App .ionapi - they look similar but are managed and expired independently.
- Letting a dev/test .ionapi file end up deployed to production, or vice versa, because the filenames look interchangeable.
- Assuming 401 always means a bad secret, when it is equally often an expired or disabled service account, or a revoked grant.
- Not checking system clock drift on the calling server before spending time on credential rotation.
- Storing .ionapi files in source control past the point they were valid for, so old, dead credentials keep getting redeployed.

## Ai Angle

ERPray, grounded on a tenant's ION API and IFS configuration rather than free text, can run this same checklist automatically: it reads which .ionapi file a failing integration is using, checks the linked Authorized App or service account status through the ION API Gateway configuration, decodes the token's exp/iat claims, and reports back exactly which check failed instead of leaving an admin to click through each one by hand. It does not gain access to secrets it should not see, and an admin still has to actually revoke or regenerate credentials in ION API Gateway.

## Faq

### What is actually inside a .ionapi file?

**Answer:** A JSON bundle with the tenant id, IFS and API URLs, the OAuth authorization and token endpoints, and either a client id/secret pair or an saak/sask service account key pair. It is a configuration bundle, not a single password, so a 401 can come from any one of several fields going stale.

### Do .ionapi credentials expire on their own?

**Answer:** Service account (saak/sask) credentials follow an expiration or rotation policy set by the tenant admin in Infor OS Portal. Authorized App client secrets do not expire on a timer by default, but they can be revoked or regenerated at any time, which has the same effect on old .ionapi files.

### Can I use the same .ionapi file for test and production?

**Answer:** No. Each .ionapi file is tied to a specific tenant and Authorized App or service account. Using a test tenant's file against production, or vice versa, will either fail outright or silently call the wrong environment, which is worse than a 401.

### How do I tell if the problem is credentials or my code?

**Answer:** Make a direct client_credentials call to the token endpoint (ot value) in the .ionapi file, outside your application. If that succeeds and your app still gets 401 on the actual API call, the problem is in the app, a proxy, or the scope, not the credentials.

## Search terms

infor ion api 401 unauthorized, ionapi file expired, infor ion api oauth error, service account saak sask expired, ion api gateway authorized app revoked, infor os oauth token endpoint, ionapi file structure, infor ion api postman 401, regenerate ionapi file, infor ion client credentials grant

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