> ## 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.

# Set Up Attributes

> This page will walk you through the steps required to set up Attributes in your integration.

## Choose an Attributes package

Flinks offers the following attribute packages for you to choose from:

* Income Attributes
* Lending Attributes
* Credit Risk Attributes
* User Analysis Attributes
* Business Analysis Attributes
* All Consumer Attributes

[Read more on what Attributes package(s) we offer](./attributes-packages) so you can choose what is best for your configuration.

## Environments you'll need

Flinks provides two environments to you when you start the integration process:

* **Sandbox:** a testing space that you use to set up your Flinks integration and test that it's working correctly.
* **Production:** a live production space that allows you to connect real accounts and start using your Flinks product.

## Set up the sandbox environment

Flinks provides you with a Sandbox environment that you can use to try out our products. Use it to test your integration and confirm everything is working as expected.

<Note>
  <p class="h4">Flinks Pay is currently only available in Canada.</p>
</Note>

Here's what to do with it:

1. When you're ready to get started, contact your Flinks Representative and ask them to set you up with a test environment.
2. Flinks provides you with a test institution, Flinks Capital, that you can use for testing purposes. For security and privacy reasons, you can't make live connections to real financial institutions in this environment.
3. Build your integration and connect to our APIs using the Sandbox environment.
4. When you're ready, move over to the Production environment.

## Set up the production environment

Ask your Flinks Representative to set you up with a private Production environment in advance, so that you're ready to go-live when testing is complete.

When the development and testing process in the Sandbox environment is complete, it's time to move your Flinks configuration over to the Production environment. Make sure that all of your API calls and iframe URLs are pointing to your private Production environment and not the Sandbox environment.

Once you go live, you can start connecting to real accounts and experience the full Flinks service.

You can still make requests to Flinks Capital in the Production environment at no cost, but you'll receive an invoice for all successful live requests.

## Set Up Your API Connection

To set up your API Connection with Flinks, you will have to make your first API call before receiving data. The following sections will walk you through this process.

### Make your first API call

This is the first API request that needs to be executed whenever you want to retrieve data from a connected account.

Flinks API needs to confirm the validity of the request and to know which account you want to retrieve data from. To do so, you will exchange your `loginId` for a new `requestId`.

For that, the [`/Authorize`](../../api/authorize/endpoints/authorize) endpoint needs to be called using a POST method, and it requires a loginId and the parameter `MostRecentCached:true`.

To make it more concrete, let's suppose that you are opening a new session to retrieve the data for the `loginId: 5e115eac-1209-4f19-641c-08d6d484e2fe`:

```curl curl theme={null}
curl -X POST \
  https://toolbox-api.private.fin.ag/v3/43387ca6-0391-4c82-857d-70d95f087ecb/BankingServices/Authorize \
  -H 'Content-Type: application/json' \
  -d '{
	"LoginId":"5e115eac-1209-4f19-641c-08d6d484e2fe",
	"MostRecentCached":true
}'
```

This is how your response will look like:

```json Json theme={null}
{
    "Links": [...],
    "HttpStatusCode": 200,
    "Login": {
        "Username": "Greatday",
        "IsScheduledRefresh": false,
        "LastRefresh": "2019-05-09T13:47:46.5227901",
        "Type": "Personal",
        "Id": "5e115eac-1209-4f19-641c-08d6d484e2fe"
    },
    "Institution": "FlinksCapital",
    "RequestId": "1243c283-e0ca-4fda-a5e4-343068430190"
}
```

The `loginId` (`5e115eac-1209-4f19-641c-08d6d484e2fe`) was successfully exchanged for a `requestid` (`1243c283-e0ca-4fda-a5e4-343068430190`). Now that the session is active, we have everything we need to place a call to retrieve financial data.

### Receive data from us

The next step is for your server to send a request for data. This request uses the [`/GetAccountsDetail`](../../api/connect/endpoints/account-linking/get-accounts-detail) endpoint, which also needs to be made using a POST method, and only requires the acquired `requestId`.

Continuing our example using our `requestId` (`1243c283-e0ca-4fda-a5e4-343068430190`), it looks like this:

```curl curl theme={null}
curl -X POST \
  https://toolbox-api.private.fin.ag/v3/43387ca6-0391-4c82-857d-70d95f087ecb/BankingServices/GetAccountsDetail \
  -H 'Content-Type: application/json' \
  -d '{
	"RequestId":"1243c283-e0ca-4fda-a5e4-343068430190"
}'
```

The most common first response to get in a request for data returns an `HTTP 202 FlinksCode:OPERATION_PENDING`, meaning that the data you are requesting is still being processed.

Here's an example of a typical API response for data pending processing:

```json Json theme={null}
{
    "FlinksCode": "OPERATION_PENDING",
    "Links": [...],
    "HttpStatusCode": 202,
    "Message": "Your operation is still processing",
    "RequestId": "1243c283-e0ca-4fda-a5e4-343068430190"
}
```

Because of this, your server needs to expect and be able to handle this response and proceed to poll the request (link to async poll code samples) to receive the data, which is described in the next step.

<Warning>
  <p class="h4">When sending requests for data...</p>

  Your integration must handle the 202 OPERATION\_PENDING response.
</Warning>

### Receive pending data

For requests that are still pending for data processing, only the `requestId` is needed, but the parameter goes directly into the API URL as it's a `GET` request.

While you receive the response `HTTP 202 FlinksCode:OPERATION_PENDING`, you need to keep calling this endpoint every 10 seconds for a maximum of 30 minutes.

```curl curl theme={null}
curl -X GET \
  https://toolbox-api.private.fin.ag/v3/43387ca6-0391-4c82-857d-70d95f087ecb/BankingServices/GetAccountsDetailAsync/1243c283-e0ca-4fda-a5e4-343068430190 \
  -H 'Content-Type: application/json'
```

<Warning>
  <p class="h4">If you're still receiving 202 OPERATION PENDING...</p>

  In case your data is still pending, you need to call this endpoint every 10 seconds for maximum of 30 minutes. This doesn't mean that your request is going to take that long, but this global timeout is required to avoid infinite loops.
</Warning>

Once your data is done being processed, the API will respond with an `HTTP 200` and a JSON payload containing all the data we collected from the financial institution in a standard format. Your app server will be ready to start handling it according to your use-case.

```json Json theme={null}
{
    "HttpStatusCode": 200,
    "Accounts": [
        {
            "Transactions": [
                {
                    "Date": "2019-04-22",
                    "Code": null,
                    "Description": "national money",
                    "Debit": 12.08,
                    "Credit": null,
                    "Balance": 49993.96,
                    "Id": "633b976e-c713-4b59-9717-3ec407bdde8b"
                },
                {
                    "Date": "2019-04-21",
                    "Code": null,
                    "Description": "TrxChe@Cr12.07",
                    "Debit": null,
                    "Credit": 12.07,
                    "Balance": 50006.04,
                    "Id": "ac25ab22-2828-4174-9653-23bb8918b7c4"
                }
            ],
            "TransitNumber": "77777",
            "InstitutionNumber": "777",
            "OverdraftLimit": 0,
            "Title": "Chequing CAD",
            "AccountNumber": "1111000",
            "Balance": {
                "Available": null,
                "Current": 49993.96,
                "Limit": null
            },
            "Category": "Operations",
            "Type": "Chequing",
            "Currency": "CAD",
            "Holder": {
                "Name": "John Doe",
                "Address": {
                    "CivicAddress": "1275 avenue des Canadiens-de-Montréal",
                    "City": "Montréal",
                    "Province": "QC",
                    "PostalCode": "H3B 5E8",
                    "POBox": null,
                    "Country": "CA"
                },
                "Email": "johndoe@flinks.com",
                "PhoneNumber": "(514) 333-7777"
            },
            "Id": "ae1dac72-70da-4626-fed8-08d682e1ff4a"
        },
        {...}
    ],
    "Login": {
        "Username": "Greatday",
        "IsScheduledRefresh": false,
        "LastRefresh": "2019-05-09T13:47:46.5227901",
        "Type": "Personal",
        "Id": "5e115eac-1209-4f19-641c-08d6d484e2fe"
    },
    "Institution": "FlinksCapital",
    "RequestId": "1243c283-e0ca-4fda-a5e4-343068430190"
}
```

## Connect to our mandatory Flinks Connect endpoints

When completing the authorization process for **both Flinks Connect and direct API connections**, you must pass a valid authorize token to access account data. This adds an extra layer of security by ensuring that only the intended person is accessing the account.

Complete the steps below to pass us an authorize token each time you authenticate:

### Receive a secret key from Flinks

Flinks provides a secret key during the integration process. This is a unique key that identifies you within the system and grants you access to our APIs.

Use your secret key to generate an authorize token. This allows us to confirm your identity and ensure that the correct person is accessing the data.

### Generate an authorize token

Call the [`/GenerateAuthorizeToken`](../../api/authorize/endpoints//generate-authorize-token) endpoint and pass your secret key.

This token can only be used **once** and is active for **30 minutes**. This token expires if it is not used within 30 minutes, and you must generate a new one.

### Send us an authorize token to successfully authenticate

Those using Flinks Connect will pass the authorize token using a [customization parameter](../connect/flinks-connect/widget).

Add the [authorizeToken customization parameter](../connect/flinks-connect/widget#pass-an-authorize-token) to your Flinks Connect iframe URL, then pass your authorize token using the format `authorizeToken=123-456-789`. Replace `123-456-789` with your valid token.

For example:

```url Url theme={null}
https://yourinstance-iframe.private.fin.ag/?redirectUrl=flinks.com&authorizeToken=d65f1adb-8ebc-48dc-be8b-20c773ba1565
```

## Connect to your Attributes API endpoints

So everything is nearly set up, you. only have a couple more API calls to make before you are fully ready to go to production! This section will guide you through the process of obtaining a new `requestId`, retrieving the most recent transactions at that time ([/GetAccountsDetail](/api/connect/endpoints/account-linking/get-accounts-detail)), and using that `requestId` to call the 'Attributes' service.

### Overview

In order to take advantage of enhanced data, there are a couple of steps that need to happen. To pull back data attributes, Flinks needs to analyze the most recent transactional data for the end user and convert this into easily ingestible insights.

Here is a step-by-step overview of this process:

1. Receive a new `requestId`—using the loginId stored for the end user, call the [`/Authorize`](../../api/authorize/endpoints/authorize) endpoint with the parameter `MostRecentCached:true`.
2. Using the `requestId` that is generated from this new `/Authorize` call, make a call to the[`/GetAccountsDetail`](../../api/connect/endpoints/account-linking/get-accounts-detail)\` endpoint to retrieve the most recent transaction history.
3. Using this `requestId`, call the specific [`/Attributes`](../../api/enrich/endpoints/consumer-attributes/attributes) endpoint to retrieve the required data.

<Note>
  <p class="h4">Note on steps 1 and 2</p>

  These have been covered previously in the Make API Calls section—please refer to that for more information.
</Note>

Assuming that you have the new session open and you have your end user's most recent transaction history, you're ready to call for Attributes.

Within your integration, you have a choice of 5 endpoint variations. We have Four (4) Use-Case Specific Endpoints and one (1) Custom Endpoint for `Attributes`. Please find information on each of the Endpoints below.

### /GetIncomeAttributes

This endpoint returns a set of `Income Verification` Attributes, and should be used by clients that have the Income Verification Use-Case Package. The Attributes contained within this request cannot be customized.

Required Parameters:

* `instance`
* `customerId`
* `loginId`
* `requestId`

```curl curl theme={null}
curl -X GET \
  https://{instance}-api.private.fin.ag/v3/{customerId}/insight/login/{loginId}/attributes/{requestId}/GetIncomeAttributes \
```

### /GetCreditRiskAttributes

This endpoint returns a set of `Credit Risk` Attributes and should be used by clients who have the Credit Risk Use-Case Package. The Attributes contained within this request cannot be customized.

Required Parameters:

* `instance`
* `customerId`
* `loginId`
* `requestId`

```curl curl theme={null}
curl -X GET \
  https://{instance}-api.private.fin.ag/v3/{customerId}/insight/login/{loginId}/attributes/{requestId}/GetCreditRiskAttributes \
```

### /GetUserAnalysisAtributes

The endpoint returns a set of User Analysis Attributes and should be used by clients that have the User Analysis Use-Case Package. The Attributes contained within this request cannot be customized.

Required Parameters:

* `instance`
* `customerId`
* `loginId`
* `requestId`

```curl curl theme={null}
curl -X GET \
  https://{instance}-api.private.fin.ag/v3/{customerId}/insight/login/{loginId}/attributes/{requestId}/GetUserAnalysisAttributes \
```

### /GetLendingAttributes

This endpoint returns a set of Lending Attributes and should be used by clients that have the `Lending` Use-Case Package. The Attributes contained within this request cannot be customized.

Required Parameters:

* `instance`
* `customerId`
* `loginId`
* `requestId`

```curl curl theme={null}
curl -X GET \
  https://{instance}-api.private.fin.ag/v3/{customerId}/insight/login/{loginId}/attributes/{requestId}/GetLendingAttributes \
```

### /GetAllAttributes

This endpoint returns all available Attributes that Flinks currently has available. This endpoint is restricted to only clients that have a Tier 2 package and above. The attributes contained within this request cannot be customized.

Required Parameters:

* `instance`
* `customerId`
* `loginId`
* `requestId`

```curl curl theme={null}
curl -X GET \
  https://{instance}-api.private.fin.ag/v3/{customerId}/insight/login/{loginId}/attributes/{requestId}/GetAllAttributes \
```

### /Attributes

This endpoint is the most customizable `Attributes` Endpoint. In order to call this Endpoint, you will need to know and include the names of Attributes within your request. This endpoint is used primarily by clients who have specific needs that fall outside of our Use-Case Endpoints.

Required Parameters:

* `instance`
* `customerId`
* `loginId`
* `requestId`

Required Fields:

* `MostRecentCached`
* `Attributes`
  You can also include these additional, optional fields (Please refer to our [API reference](../../api/enrich/endpoints) for further details):

<Note>
  <p class="h4">Operations accounts only</p>

  Operations is the only supported value.
</Note>

* `Filters`
* `AccountFilter`
* `Options`
* `AttributesDetail`

<Warning>
  <p class="h4">Note on Attributes Field\*</p>

  If you are on a Tier 2 Package and need to create a custom Attribute request, please reach out to our team for the full list of Attribute Names that you can include here as needed for your custom use-case.
</Warning>

```curl curl theme={null}
curl -X POST \
  https://toolbox-api.private.fin.ag/v3/{customerId}/insight/login/{loginId}/attributes/{requestId} \
  -H 'Content-Type: application/json' \
  -d '{
    "Attributes": {
        "Card": [
            "account_age_days",
            "balance_current",
            "balance_max",
            "balance_min",
            "count_nsf",
            "avg_monthly_deposit",
            "sum_employer_income"
        ]
    },
    "Filters": {
        "AccountCategory": [
            "Operations"
        ]
    },
    "Options": {
        "AttributesDetail": [
            "count_nsf",
            "sum_employer_income"
        ],
        "AccountFilter": [
      		"472c349a-3aed-4358-3563-08d7ccf7c1f7"
        ]
    },
    "MostRecentCached": true
}
```

```json Json theme={null}
{
  "Card": {
    "Id": "347fafd7-0aa6-4e2f-90b6-08d7750bf480",
    "account_age_days": 195,
    "balance_current": -86200.82,
    "balance_max": -65148.62,
    "balance_min": -91212.27,
    "count_nsf": 0,
    "avg_monthly_deposit": 30322.74,
    "sum_employer_income": 48700.74,
    "AttributesDetail": [
      {
        "Attribute": "sum_employer_income",
        "Transactions": [
          {
            "TransactionId": "31ca0d0e-4ce5-4e49-82d3-9a5698d86a7b",
            "AccountId": "911807a7-72b6-431d-381a-08d792dc3bfc",
            "Date": "2020/02/13",
            "Description": "PAYROLL deposit - Flinks Technologies",
            "Debit": 0.0,
            "Credit": 9338.32
          }
        ]
      }
    ]
  },
  "Login": {
    "Username": "Attributes_1",
    "IsScheduledRefresh": false,
    "LastRefresh": "2020-03-12T16:54:51.7558369",
    "Type": "Personal",
    "Id": "347fafd7-0aa6-4e2f-90b6-08d7750bf480"
  },
  "RequestId": "fb4f2c83-b4c0-43e4-82f5-844a3594a9cb"
}
```

Once the `Attributes` engine is done processing the transactional data, the API will respond with a `HTTP 200` and a JSON payload containing all the requested data attributes (per the requested use-case) in a standard format; Your app server should be ready to start handling them according to your use-case.

<Check>
  #### Before moving on, let's review what we just did:

  * Received a new `requestId` with incoming `loginId` by calling [/Authorize](../../api/authorize/endpoints/authorize) with `MostRecentCached:true.`
  * Requested ready-to-deliver data with [/GetAccountsDetail](../../api/connect/endpoints/account-linking/get-accounts-detail) and handled `202 OPERATION_PENDING` responses.
  * Set up the call to the required [/Attributes](../../api/enrich/endpoints/consumer-attributes/attributes) endpoint and started receiving data attributes.
</Check>

## Connect to optional API endpoints to enhance your integration

<Note>
  <p class="h4">Custom integrations only</p>

  This page explains how to set up custom integrations that use a direct API connection. If you are using Flinks Connect, see [`Set Up Flinks Connect`](../connect/getting-started#getting-started-with-connect).
</Note>

Complete the following steps to connect with us using a custom API integration that uses OAuth 2.0:

1. Ask your Flinks Representative to whitelist the URLs that your endpoints will be calling, including the redirect URL in step 2A.

2. Call the [`/OAuth/Authorize`](../../api/authorize/custom/oauth-authorize) endpoint and perform the following tasks:

   * Redirect the end-user to their bank's login screen using the `institution` parameter. Here, they'll enter their login credentials and complete multi-factor authentication (MFA) if required.
   * Provide a URL to direct the end-users' screen back to your website or app using the `redirect_url` field. If the login is successful, you'll receive a redirect response that contains the redirect URL, a `loginId: https://{redirect}?loginId={loginId}&state={state}`. If unsuccessful, you'll receive a redirect response that contains a redirect URL and an error message: `https://{redirect}?state={state}&error={error}&error_description={error_description}`. For more information about how to make this call, see our [API documentation](../../api/authorize/custom).

3. Call the [`/Authorize`](../../api/authorize/endpoints/authorize) endpoint and apply the following settings to initiate the authorization flow:

   * Pass the `loginId` that you received in step 2.
   * Make the call in live mode by setting the `MostRecentCached` parameter to `FALSE`. For more information about how to make this call, see our [API documentation](../../api/authorize/endpoints/authorize).
   * Set the `save` parameter to `TRUE` to maintain communication with the database (to do nightly refreshes, receive insights, and more). For more information on how to make this call, see our [API documentation](../../api/authorize/endpoints/authorize).

If you receive a 200 response, the end-user is successfully authenticated, and you can now use the Flinks API to retrieve data.

## Flinks enables your package

To complete this step, ask your Flinks Representative to enable Attributes in your Flinks Connect configuration.

## Save your loginIds

Flinks issues a unique `loginId` for each customer who successfully authenticates through Flinks Connect. It's used in combination with a `requestId` to access the financial data for that particular customer. The `loginId` for an account doesn't expire and it never changes unless it's deleted. If you need to delete a `loginId`, use the [/DeleteCard](../../api/connect/endpoints/account-linking/delete-card) endpoint.

Store each customer's `loginId` in a secure location in your servers and **never share it publicly**.

1. Retrieve the loginId that Flinks sends you using one of the following methods:

   * (Recommended) Use a JavaScript event listener that contains `step:REDIRECT`

   ```json Json theme={null}
   {
     "step": "REDIRECT",
     "institution": "FlinksCapital",
     "url": "https://example.com/thank-you?loginId=8b35f6c8-e7b6-41d3-98f8-08d68b7f8d31&institution=FlinksCapital"
   }
   ```

   * Flinks adds the `loginId` and `institution` to the URL after a successful connection. Retrieve it from here:

   ```url Url theme={null}
   https://example.com/thank-you?loginId=8b35f6c8-e7b6-41d3-98f8-08d68b7f8d31&institution=FlinksCapital
   ```

2. Send the `loginId` to your server app for storage.
