# Token Exchange

> Exchange API keys for short-lived bearer tokens for Infuse Platform and Infuse-IoT Cloud API integrations.

Personal and service-account API keys can be exchanged for short-lived bearer tokens through the IAM auth endpoint.

Use token exchange when your integration should keep the long-lived API key in secret storage and call downstream APIs with a short-lived token.

## Exchange an API Key

```http
POST https://api.infuse-cloud.io/iam/auth/token
Content-Type: application/json
```

```json
{
  "apiKey": "ik_<keyId>.<keySecret>",
  "audience": "infuse-platform"
}
```

The `apiKey` value must be the complete `ik_<keyId>.<keySecret>` key exactly as issued. Do not add a `Bearer` or `ApiKey` prefix.

`audience` selects which API the token is for:

<table>
<thead>
  <tr>
    <th>
      <code>
        audience
      </code>
    </th>
    
    <th>
      Use the token with
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        infuse-platform
      </code>
      
       (default)
    </td>
    
    <td>
      Infuse Platform APIs, such as IAM, organisation, and Infuse-Marketplace APIs.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        infuse-iot
      </code>
    </td>
    
    <td>
      The Infuse-IoT Cloud API at <code>
        https://api.infuse-iot.com
      </code>
      
      .
    </td>
  </tr>
</tbody>
</table>

The response includes:

- `accessToken`
- `tokenType`
- `expiresAt`

Use the returned token as a bearer token until it expires:

```http
Authorization: Bearer <accessToken>
```

A token is accepted only by the API it was issued for. A Platform token is rejected by the Infuse-IoT Cloud API, and an Infuse IoT token is rejected by Platform APIs. If one integration calls both, exchange the same API key once for each audience.

## Call the Infuse-IoT Cloud API

Personal and service-account API keys can call the Infuse-IoT Cloud API directly:

1. Exchange the key with `"audience": "infuse-iot"`.
2. Send the returned token to the Infuse-IoT Cloud API as `Authorization: Bearer <accessToken>`.
3. Exchange the key again before `expiresAt`.

```http
GET https://api.infuse-iot.com/board?organisationId={organisationId}
Authorization: Bearer <accessToken>
```

The token is bound to the organisation that owns the API key. Use that organisation's ID in IoT requests; it is the same value in Infuse Platform and Infuse-IoT Cloud and is shown under **Organisation settings** > **Developer tools**. To work in another organisation, use a key issued in that organisation.

IoT requests are authorised using the key owner's current IoT permissions, such as those from the **IoT Viewer**, **Device Operator**, **Device Controller**, or **IoT Admin** templates. See [Permissions and Resource Limits](/docs/iam-and-access/permissions#infuse-iot-api-access) for how resource limits apply to IoT permissions.

Only tokens exchanged from an API key are accepted by the Infuse-IoT Cloud API. Portal sign-in sessions and temporary developer tokens from **Organisation settings** > **Developer tools** cannot be used for direct IoT API calls.

<note>

Legacy Infuse IoT admin keys are deprecated and being retired. Migrate integrations that use them to a personal or service-account API key. See [Legacy Infuse IoT Admin Keys](/docs/iam-and-access/api-tokens#legacy-infuse-iot-admin-keys).

</note>

## Token Lifetime

Exchanged tokens are short-lived. Use `expiresAt` rather than assuming a fixed lifetime:

1. Exchange the key again shortly before `expiresAt`, for example when two minutes remain.
2. If a call returns `401`, exchange the key once more and retry the call once.
3. If the exchange itself fails, treat it as a credential problem: the key may be revoked or expired, or its owner may no longer be eligible.

Do not cache a token beyond its `expiresAt`.

## Direct API-Key Auth

Some Infuse Platform APIs can accept the API key directly:

```http
Authorization: ApiKey ik_<keyId>.<keySecret>
```

Direct API-key auth only works when it is enabled for the organisation and supported by the API being called. If direct auth is not enabled, exchange the API key for a bearer token first. The Infuse-IoT Cloud API requires an exchanged `infuse-iot` token.

Token exchange is the recommended default because the long-lived API key stays in secret storage while normal API calls use a short-lived bearer token.

## Requirements

The credential must not be revoked or expired. Its owning user must still be a member of the organisation, or its owning service account must be active and unexpired.

Authorization uses the owning identity's current roles, group memberships, direct grants, status, and organisation membership. The API key does not carry a separate copy of that access.
