# Infor ION API OAuth Token Request Generator from an .ionapi File

> Source: https://netray.co/tools/infor-ion-api-oauth-token-request-generator
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: Free Tools

## Short answer

Turn the values in a downloaded .ionapi file into code that requests a token from the Infor authorization server, calls the ION API Gateway and revokes the token.

## Category

developer

## Erp

Infor ION

## Audience

- Integration developer
- Infor OS administrator
- ERP developer

## Tool

**Kind:** template

**Output:** code

**Language:** python

**Fields:**

#### ti (tenant)

**Key:** ti

**Type:** text

**Default:** TENANT_TST

#### ci (client ID)

**Key:** ci

**Type:** text

**Default:** TENANT_TST~clientid

#### cs (client secret)

**Key:** cs

**Type:** text

**Default:** client-secret

#### pu (authorization server base URL)

**Key:** pu

**Type:** text

**Default:** https://mingle-sso.example.com:443/TENANT_TST/as/

**Help:** Ends with /as/ in the .ionapi file

#### ot (token path)

**Key:** ot

**Type:** text

**Default:** token.oauth2

#### or (revoke path)

**Key:** or

**Type:** text

**Default:** revoke_token.oauth2

#### iu (ION API Gateway base URL)

**Key:** iu

**Type:** text

**Default:** https://mingle-ionapi.example.com

#### saak (service account access key)

**Key:** saak

**Type:** text

**Default:** TENANT_TST#access-key

#### sask (service account secret key)

**Key:** sask

**Type:** text

**Default:** secret-key

#### API path after the tenant

**Key:** path

**Type:** text

**Default:** /<SUITE>/<path>

**Help:** The part after {iu}/{ti}, starting with a slash, as shown in the API Gateway documentation for your suite

**Blocks:**

#### 1. Python (requests): token, call, revoke

**Body:** import requests

TI = '{{ti}}'
CI = '{{ci}}'
CS = '{{cs}}'
PU = '{{pu}}'
OT = '{{ot}}'
OR_PATH = '{{or}}'
IU = '{{iu}}'
SAAK = '{{saak}}'
SASK = '{{sask}}'
API_PATH = '{{path}}'

# 1. Resource owner password grant with the service account keys
token_resp = requests.post(
    PU + OT,
    data={
        'grant_type': 'password',
        'username': SAAK,
        'password': SASK,
        'client_id': CI,
        'client_secret': CS,
    },
    timeout=60,
)
token_resp.raise_for_status()
token = token_resp.json()
access_token = token['access_token']
print('Token expires in (seconds):', token.get('expires_in'))

# 2. Call the API through the ION API Gateway
api_url = IU.rstrip('/') + '/' + TI + API_PATH
resp = requests.get(
    api_url,
    headers={'Authorization': 'Bearer ' + access_token, 'Accept': 'application/json'},
    timeout=120,
)
print(resp.status_code)
print(resp.text[:2000])

# 3. Revoke the token when finished
revoke = requests.post(
    PU + OR_PATH,
    data={
        'token': access_token,
        'token_type_hint': 'access_token',
        'client_id': CI,
        'client_secret': CS,
    },
    timeout=60,
)
print('Revoke status:', revoke.status_code)

#### 2. curl

**Body:** # Get a token
curl -s -X POST '{{pu}}{{ot}}' \
  --data-urlencode 'grant_type=password' \
  --data-urlencode 'username={{saak}}' \
  --data-urlencode 'password={{sask}}' \
  --data-urlencode 'client_id={{ci}}' \
  --data-urlencode 'client_secret={{cs}}'

# Call the API (paste access_token from the response)
curl -s '{{iu}}/{{ti}}{{path}}' \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Accept: application/json'

# Revoke
curl -s -X POST '{{pu}}{{or}}' \
  --data-urlencode 'token=ACCESS_TOKEN' \
  --data-urlencode 'token_type_hint=access_token' \
  --data-urlencode 'client_id={{ci}}' \
  --data-urlencode 'client_secret={{cs}}'

#### 3. PowerShell (Invoke-RestMethod)

**Body:** $body = @{
  grant_type    = 'password'
  username      = '{{saak}}'
  password      = '{{sask}}'
  client_id     = '{{ci}}'
  client_secret = '{{cs}}'
}
$token = Invoke-RestMethod -Method Post -Uri '{{pu}}{{ot}}' -Body $body -ContentType 'application/x-www-form-urlencoded'
Write-Output ('Expires in: ' + $token.expires_in)

$headers = @{ Authorization = 'Bearer ' + $token.access_token; Accept = 'application/json' }
$result = Invoke-RestMethod -Method Get -Uri '{{iu}}/{{ti}}{{path}}' -Headers $headers
$result | ConvertTo-Json -Depth 6

$revoke = @{
  token           = $token.access_token
  token_type_hint = 'access_token'
  client_id       = '{{ci}}'
  client_secret   = '{{cs}}'
}
Invoke-RestMethod -Method Post -Uri '{{pu}}{{or}}' -Body $revoke -ContentType 'application/x-www-form-urlencoded'

#### 4. Postman OAuth 2.0 settings

**Table:**

**Columns:**

- Postman setting
- Value

**Rows:**

**0:** Auth type

**1:** OAuth 2.0

**0:** Grant type

**1:** Password Credentials

**0:** Access Token URL

**1:** {{pu}}{{ot}}

**0:** Username

**1:** {{saak}}

**0:** Password

**1:** {{sask}}

**0:** Client ID

**1:** {{ci}}

**0:** Client Secret

**1:** {{cs}}

**0:** Client Authentication

**1:** Send client credentials in body

**0:** Request URL

**1:** {{iu}}/{{ti}}{{path}}

**Notes:** Service account keys (saak, sask) appear only in .ionapi files downloaded for a backend service authorized app with a service account. Never commit the file or these values to source control; load them from a vault or environment variables in real code. Confirm the API path for your suite in the API Gateway documentation. The same file format and calls apply to on-premises Infor OS, with the authorization server on your own servers.

## Content

**Intro:** This generator turns the properties of a downloaded .ionapi file into working Python, curl and PowerShell code that gets an OAuth 2.0 token, calls an API through the Infor ION API Gateway and revokes the token. It also lists the matching Postman settings for quick testing.

**Sections:**

#### What is in the .ionapi file

**Body:** When an administrator registers an authorized app in ION API and downloads its credentials, Infor produces a JSON file with short property names. Open it in a text editor and copy each value into the matching field above; the property name is shown in each field label. The file also holds values this generator does not need, such as the authorize path used by web apps. The same structure applies on premises and in the cloud; only the host names differ. The properties used here are documented by Infor as follows.

**Bullets:**

- ti: tenant identifier; cn: application name
- ci and cs: client ID and client secret passed to the authorization server
- iu: base URL of the ION API Gateway for the tenant
- pu: base URL of the authorization server; oa, ot and or are paths appended to it for authorize, token and revoke (samples: authorization.oauth2, token.oauth2, revoke_token.oauth2)
- saak and sask: service account access key and secret key, used as username and password in the password grant

#### How the calls work

**Body:** A backend service app authenticates with the resource owner password grant: POST to pu + ot with grant_type=password, username set to saak, password set to sask, plus client_id and client_secret, as a form-encoded body. The response contains access_token and expires_in. Every API call then goes to iu, the tenant and the product path, with the header Authorization: Bearer and the token. When the job finishes, POST the token to pu + or to revoke it so it cannot be reused. Read expires_in rather than hard-coding a lifetime, and request a new token when a call returns 401.

#### Worked example

**Body:** Suppose the file has ti TENANT_TST, pu ending in /TENANT_TST/as/, ot token.oauth2 and iu of your ION API host. The token URL becomes the pu value followed by token.oauth2. To call an API whose documented path is /SUITE/resource, the full URL is iu + /TENANT_TST/SUITE/resource. The Python block prints the HTTP status and the first 2,000 characters of the response so you can confirm access before writing the real integration. If the token call fails with invalid_grant, the service account keys are wrong or were regenerated; if it fails with invalid_client, the ci or cs value is wrong.

#### Common mistakes

**Body:** Using a web or desktop app type and expecting saak and sask: those only exist for a backend service app with a service account, which an administrator must create. Building the URL without the tenant segment after iu. Sending client credentials as Basic auth when Postman is set to body, or the reverse; pick one and keep it consistent. Committing the .ionapi file to git, which hands anyone with repository access a working service account. Holding one token for a long batch run instead of refreshing when it expires. On premises, forgetting to trust the internal certificate of the authorization server in Python or PowerShell.

**Cta:** If you want to call Infor APIs from a private AI assistant on your own infrastructure, with read-only scopes and an audit log, we can build that integration.

**Faq:**

#### Where do I get Infor ION API credentials?

**Answer:** In Infor OS, an administrator opens ION API, goes to Authorized Apps, creates an app of the right type (backend service for server-to-server) and downloads the credentials, which produces the .ionapi file. For backend service apps a service account must be created to get saak and sask.

#### What is an Infor ION API service account?

**Answer:** It is a non-interactive identity tied to an Infor OS user, represented by the access key (saak) and secret key (sask) in the .ionapi file. The API runs with that user's security roles, so give it only the roles the integration needs.

#### How do I use the ION API in Postman?

**Answer:** Set Authorization to OAuth 2.0, grant type Password Credentials, Access Token URL to pu plus ot, username saak, password sask, client ID and secret from ci and cs, and client authentication to send credentials in body. Then call iu, tenant and path.

#### How long does an ION API token last?

**Answer:** Read the expires_in value in the token response; it is given in seconds and depends on the tenant configuration. Cache the token, track its expiry and request a new one before it lapses or when a call returns 401.

## Search terms

infor ion api, infor ion api gateway, infor ion api credentials, infor ion api authentication, infor ion api postman, infor ion api service account, ionapi file, ion api token python

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