> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flinks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication Reference

> Credentials, headers, and authentication flow for all Flinks API endpoints.

## Credentials

Flinks uses four credentials. Each serves a different purpose in the authentication flow.

| Credential          | What it is                                                                        | How you get it                                                                                                                 | Lifetime                                        |
| :------------------ | :-------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------- |
| **Secret key**      | A key that identifies your integration and grants access to Flinks APIs.          | Provided by Flinks during integration setup.                                                                                   | Does not expire.                                |
| **Authorize token** | A one-time token that authenticates a single session.                             | Generated by calling [`/GenerateAuthorizeToken`](../../api/authorize/endpoints/generate-authorize-token) with your secret key. | Single-use. Expires after 30 minutes if unused. |
| **`x-api-key`**     | A security header required on data endpoints.                                     | Provided by Flinks during integration setup.                                                                                   | Does not expire.                                |
| **HMAC secret**     | A shared secret used to verify the authenticity of webhook callbacks from Flinks. | Provided by Flinks during integration setup.                                                                                   | Does not expire.                                |

## Toolbox sandbox credentials

Use these credentials to test in the toolbox sandbox environment (`toolbox-api.private.fin.ag`):

| Credential                                                          | Value                                  |
| :------------------------------------------------------------------ | :------------------------------------- |
| **Instance**                                                        | `toolbox`                              |
| **customerId**                                                      | `43387ca6-0391-4c82-857d-70d95f087ecb` |
| **Secret key** (for `flinks-auth-key` on `/GenerateAuthorizeToken`) | `c4569c54-e167-4d34-8de6-f4113bc82414` |
| **x-api-key** (for data endpoints)                                  | `3d5266a8-b697-48d4-8de6-52e2e2662acc` |

<Note>
  These are shared public sandbox credentials for testing. Your production credentials are unique and provided by Flinks during integration setup.
</Note>

### Sandbox iframe setup

When using the sandbox environment with Flinks Connect, you must include `demo=true` in the iframe URL. This parameter enables the **Flinks Capital** test institution, which is the only institution available in sandbox.

```
https://toolbox-iframe.private.fin.ag/v2/?demo=true&authorizeToken={token}
```

Without `demo=true`, the Flinks Capital test institution will not appear and you won't be able to complete the connection flow in sandbox. The `demo` parameter should only be used in sandbox — remove it for production.

For the full list of iframe parameters, see [Flinks Connect Widget Parameters](./flinks-connect/widget#enter-demo-mode-for-testing-purposes). For sandbox login credentials and test scenarios (MFA, errors, edge cases), see [Test Users](./flinks-connect/test-users).

## Headers by endpoint

The `flinks-auth-key` header is used on two endpoints but carries a different value on each.

| Endpoint                                                                                           | Header            | Value                    | Required |
| :------------------------------------------------------------------------------------------------- | :---------------- | :----------------------- | :------- |
| [`/GenerateAuthorizeToken`](../../api/authorize/endpoints/generate-authorize-token)                | `flinks-auth-key` | Your **secret key**      | Yes      |
| [`/Authorize`](../../api/authorize/endpoints/authorize)                                            | `flinks-auth-key` | Your **authorize token** | Yes      |
| [Flinks Connect iframe](./flinks-connect/widget#pass-an-authorize-token)                           | URL parameter     | `authorizeToken={token}` | Yes      |
| [`/GetAccountsDetail`](../../api/connect/endpoints/account-linking/get-accounts-detail)            | `x-api-key`       | Your **x-api-key**       | Yes      |
| [`/GetAccountsDetailAsync`](../../api/connect/endpoints/account-linking/get-accounts-detail-async) | `x-api-key`       | Your **x-api-key**       | Yes      |
| [`/GetAccountsSummary`](../../api/connect/endpoints/account-linking/get-accounts-summary)          | `x-api-key`       | Your **x-api-key**       | Yes      |

Data endpoints (`/GetAccountsDetail`, `/GetAccountsDetailAsync`, `/GetAccountsSummary`, etc.) authenticate using the `RequestId` returned by `/Authorize` and the `x-api-key` header. They do not require the `flinks-auth-key` header.

<Warning>
  Do not confuse the secret key with the authorize token. The secret key generates tokens. The authorize token authenticates sessions. Using the wrong value in the `flinks-auth-key` header causes `401` errors.
</Warning>

## Verify webhook callbacks

When Flinks sends a webhook callback to your endpoint, the request includes an HMAC-SHA256 signature in the `flinks-authenticity-key` header. Use your **HMAC secret** to verify that the payload came from Flinks and hasn't been tampered with.

For implementation details and code samples (Python, Node.js), see [HMAC Signature Validation](../webhooks/hmac-validation).

## Authentication flow

### Step 1: Generate an authorize token

Call [`/GenerateAuthorizeToken`](../../api/authorize/endpoints/generate-authorize-token) with your secret key in the `flinks-auth-key` header. The response contains a one-time authorize token.

### Step 2: Authenticate with the authorize token

How you pass the authorize token depends on your integration type:

* **Flinks Connect**: Add `authorizeToken={token}` as a URL parameter on the iframe URL.
* **Direct API**: Pass the authorize token in the `flinks-auth-key` header when calling [`/Authorize`](../../api/authorize/endpoints/authorize).

`/Authorize` returns a `RequestId` that you use to call data endpoints.

### Step 3: Call data endpoints

Pass the `RequestId` to data endpoints such as [`/GetAccountsDetail`](../../api/connect/endpoints/account-linking/get-accounts-detail). No `flinks-auth-key` header is needed on data endpoints.

For the full data retrieval flow after authentication, see [Retrieve Account Data](./retrieve-account-data).

## Handle token expiry in Flinks Connect

The authorize token expires after 30 minutes. The `/GenerateAuthorizeToken` endpoint does not return a TTL, so your application must handle expiry reactively.

If the user does not complete the connection flow within 30 minutes, Flinks Connect emits a JavaScript event:

```json theme={null}
{ "step": "TOKEN_INVALID" }
```

When you receive this event, generate a new authorize token and reload the iframe with the updated `authorizeToken` parameter.

### Implementation

Listen for `TOKEN_INVALID` alongside your other Flinks Connect events:

```javascript theme={null}
window.addEventListener("message", function (e) {
  if (e.data && e.data.step === "TOKEN_INVALID") {
    // 1. Call your backend to generate a new authorize token
    //    (your backend calls /GenerateAuthorizeToken with the secret key)
    // 2. Reload the iframe with the new token
    const iframe = document.getElementById("flinks-connect");
    const newUrl = iframe.src.replace(/authorizeToken=[^&]+/, "authorizeToken=" + newToken);
    iframe.src = newUrl;
  }
});
```

<Warning>
  Generate the authorize token from your backend. Do not expose your secret key in frontend code.
</Warning>

## Common authentication errors

| Error | Flinks Code       | Cause                                                                                          |
| :---- | :---------------- | :--------------------------------------------------------------------------------------------- |
| `401` | `ACCESS_DENIED`   | Invalid or missing credentials on `/Authorize`.                                                |
| `401` | `UNAUTHORIZED`    | `/GetAccountsDetail` called before completing authorization or MFA.                            |
| `401` | `SESSION_EXPIRED` | `RequestId` expired after 8 minutes of inactivity or 30 minutes of data processing.            |
| `401` | `INVALID_REQUEST` | Malformed request body, missing headers, or URL formatting errors (e.g., double slash `//v3`). |
| `401` | `INVALID_LOGIN`   | The `LoginId` passed to `/Authorize` does not exist or is invalid.                             |

For the full error code list, see [Error Codes](../../api/authorize/error-codes). For step-by-step debugging, see [Authentication Troubleshooting](../../api/authorize/troubleshooting).
