> For the complete documentation index, see [llms.txt](https://docs.countercyclical.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.countercyclical.io/~/changes/ZwrMx5xpgOpgFGNOVADb/developers/authentication.md).

# Authentication

## Overview

All calls to the Countercyclical API require authorization using a `Bearer` token in the request header:

```
Authorization: Bearer {token}
```

{% hint style="info" %}
Each token is associated to a member with in workspace. As such, users can only work with items within that workspace (along with what's available on their plan).
{% endhint %}

### Generating an API Key

Users can find their API tokens by going to [Settings -> Workspace -> Advanced -> Developers -> API Keys](https://dashboard.countercyclical.io/settings/workspace/advanced).

Each key you generate should look something like the following:

```
ck_prod_dxjgVIbY...
```

{% hint style="warning" %}
Be sure to take note of what your generated token is before closing the dialog as you will not be able to view it afterwards.&#x20;

We recommend storing this value as an environment variable.
{% endhint %}

### Best Practice: Rolling your API Keys

It's a good practice to roll your API keys once in a while for security purposes.

While we do not currently support "rerolling" the same API key, we recommend users generate a new API key with the same permissions they might otherwise have.&#x20;

To make this easier, you can select from the dropdown menu on the right-hand side of any one of your API keys and select the "Roll as New Key" option.

## Example

Here's an example of what a call to get a member's Investments might look like:

{% tabs %}
{% tab title="Express.js (API)" %}

```typescript
import axios, { AxiosResponse } from 'axios';
import { NextFunction, Request, Response, Router } from 'express';

const router = Router();

const apiKey = process.env.COUNTERCYCLICAL_API_KEY;

const countercyclicalAxiosInstance = axios.create({
    baseURL: 'https://api.countercyclical.io',
    headers: {
        Authentication: `Bearer ${apiKey}`,
    },
});

router.get('/v1/investments', async (req: Request, res: Response, next: NextFunction) => {
    try {
        await countercyclicalAxiosInstance
            .get('/v1/investments', { params: { limit: 6 } })
            .then((apiResponse: AxiosResponse) => {
                if (apiResponse.status === 200) {
                    return res.send(apiResponse.data);
                }
            });
    } catch (error) {
        console.error(error);
    }
});
```

{% endtab %}

{% tab title="Express.js (TypeScript SDK)" %}
{% hint style="info" %}
Learn more about our TypeScript SDK in our [dedicated section of the docs](/~/changes/ZwrMx5xpgOpgFGNOVADb/developers/sdks/node.js-typescript.md).
{% endhint %}

```typescript
import axios from 'axios';
import { Router, Request, Response, NextFunction } from 'express';
import { Client, ClientResponse } from '@countercyclical/node-sdk';

const router = Router();

const apiKey = process.env.COUNTERCYCLICAL_API_KEY;

const sdkClient = new Client({
    version: 'v1',
    token: apiKey,
});

router.get('/investments', async (req: Request, res: Response, next: NextFunction) => {
    try {
        await sdkClient.getInvestments({ limit: 6 }).then((sdkResponse: ClientResponse) => {
            if (sdkResponse.status === 200) {
                return res.send(sdkResponse.data);
            }
        });
    } catch (error) {
        console.error(error);
    }
});
```

{% endtab %}
{% endtabs %}
