---
updatedAt: 2026-07-08T10:02:39.000Z
agentTools:
  projectIndex: https://doc.fintecture.com/llms.txt
---

# Request an AIS access token

An AIS access token authenticates your calls to Fintecture's account information (AIS) endpoints. Because account data belongs to the end user, AIS uses the OAuth 2.0 **authorization code** flow: the user first authenticates with their bank, you receive a `code`, and you exchange it for an access token — plus a refresh token to renew access without sending the user through the flow again.

## How it works

1. [Create a Fintecture account](/docs/console-create-an-account)
2. [Register a client application](/docs/console-register-a-client-application) and get the credentials (i.e. the `app_id` and `app_secret`) associated to it
3. [Request the AIS Connect URL](https://doc.fintecture.com/reference/getaisv2connect) and redirect the user to it
4. On redirection back to your app, extract the `code` query parameter
5. Exchange the `code` for an [access token](https://doc.fintecture.com/reference/createaccesstoken) with the `AIS` scope
6. Use the returned `access_token` as a `Bearer` token on every bank account endpoint
7. Before it expires, get a new access token with the [refresh token](https://doc.fintecture.com/reference/createrefreshtoken)

> ❗️ **Keep your `app_secret` secret**
>
> Exchange codes and refresh tokens from your backend only. Never embed the `app_secret` (or a valid token) in a browser, mobile app, or public repository.

## 1. Get an authorization code

[Request the AIS Connect URL](https://doc.fintecture.com/reference/getaisv2connect) and redirect the user to it. The user authenticates with their bank and consents to share their account data. When they are redirected back to your `redirect_uri`, read the `code` query parameter — this is the value you exchange in the next step.

## 2. Exchange the code for a token

Call [`POST /oauth/accesstoken`](https://doc.fintecture.com/reference/createaccesstoken) with your Base64-encoded credentials in the `Authorization` header (`base64({app_id}:{app_secret})`) and a form-encoded body:

```curl cURL
curl -X POST "https://api.sandbox.fintecture.com/oauth/accesstoken" \
  -H "Authorization: Basic $(echo -n "$APP_ID:$APP_SECRET" | base64 | tr -d '\n')" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=$CODE" \
  -d "scope=AIS"
```
```javascript Node.js
const basic = Buffer.from(`${APP_ID}:${APP_SECRET}`).toString('base64');

const response = await fetch('https://api.sandbox.fintecture.com/oauth/accesstoken', {
  method: 'POST',
  headers: {
    'Authorization': `Basic ${basic}`,
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    code,               // the code received on redirection
    scope: 'AIS',
  }),
});

const { access_token, refresh_token, expires_in } = await response.json();
```
```python Python
import base64

import requests

basic = base64.b64encode(f"{app_id}:{app_secret}".encode()).decode()

response = requests.post(
    "https://api.sandbox.fintecture.com/oauth/accesstoken",
    headers={"Authorization": f"Basic {basic}"},
    data={"grant_type": "authorization_code", "code": code, "scope": "AIS"},
)
response.raise_for_status()
tokens = response.json()
```

> 📘 **Sandbox vs production**
>
> The examples above target the sandbox. For production, use `https://api.fintecture.com` — and remember that each environment has its own `app_id` / `app_secret`.

## 3. Read the response

```json
{
  "token_type": "Bearer",
  "access_token": "eyJhbGciOiJub25lIn0.eyJleHAiOjE1MTQwODA0MjQsI",
  "expires_in": 599,
  "refresh_token": "4n7WgFIi1Pq5texGOza4tMGBZbnIfd5vrQXPs7E7hg3L"
}
```

| Field           | Description                                                                |
| :-------------- | :------------------------------------------------------------------------- |
| `token_type`    | Always `Bearer`                                                            |
| `access_token`  | The token to send on every AIS call                                        |
| `expires_in`    | Remaining validity, in **seconds**                                         |
| `refresh_token` | Store it securely — used to get new access tokens without user interaction |

## 4. Use the token

Send the token in the `Authorization` header of every bank account endpoint:

```http
Authorization: Bearer eyJhbGciOiJub25lIn0.eyJleHAiOjE1MTQwODA0MjQsI
```

> 📘 Most AIS endpoints also require a request **signature** on top of the Bearer token. See [HTTP Signature](/docs/api-http-signature).

## 5. Renew with the refresh token

Track `expires_in` and, before the access token expires, call [`POST /oauth/refreshtoken`](https://doc.fintecture.com/reference/createrefreshtoken) — same `Authorization: Basic` header, no user interaction needed:

```curl cURL
curl -X POST "https://api.sandbox.fintecture.com/oauth/refreshtoken" \
  -H "Authorization: Basic $(echo -n "$APP_ID:$APP_SECRET" | base64 | tr -d '\n')" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=$REFRESH_TOKEN"
```

The response contains a fresh `access_token`. Keep using your stored `refresh_token` for subsequent renewals.

## Troubleshooting

| Status             | Most likely cause                                                                                 | Fix                                                                                |
| :----------------- | :------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------- |
| `400 bad_request`  | Missing/invalid `grant_type`, `code` or `scope`, or body not form-encoded                         | Send `Content-Type: application/x-www-form-urlencoded` with the three fields above |
| `401 unauthorized` | Wrong `app_id:app_secret`, expired/already-used `code`, or credentials from the other environment | Re-encode the header; restart the connect flow to get a fresh `code`               |
| `403 forbidden`    | Application not allowed to use the `AIS` scope                                                    | Check your application's products in the Console, or contact support               |

Every error response contains a `log_id` — include it when you contact support so we can trace the exact call.

<a href="/recipes/request-an-ais-access-token" target="_blank" class="thirdbutton">Recipe<i class="fa-solid fa-arrow-up-right-from-square" style={{ margin: "16px", marginRight: "-15px" }}></i></a>