---
title: Initial setup
description: Set up and manage your user management dashboard with SuperTokens integration and configuration instructions.
sidebar:
  order: 2
---

## Overview

The following page shows you how to set up the dashboard recipe and access the web interface.
You can check the next diagram to understand how the dashboard integrates with your application.


**Managed service**

<img class="docs-image-content-width" src="/docs-assets/img/architecture/managed_service_generic.png" alt="Flowchart of architecture when using SuperTokens managed service" />

**Self-hosted**

<img class="docs-image-content-width" src="/docs-assets/img/architecture/self_hosted_generic.png" alt="Flowchart of architecture when self-hosting SuperTokens" />


## Steps

### 1. Initialize the `Dashboard` recipe


To get started, initialize the Dashboard recipe in the `recipeList`.

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import Dashboard from "supertokens-node/recipe/dashboard";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    // TODO: Initialise other recipes
    Dashboard.init(),
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/dashboard"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
  supertokens.Init(supertokens.TypeInput{
      RecipeList: []supertokens.Recipe{
        // TODO: Initialise other recipes
        dashboard.Init(nil),
      },
  });
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="Partial configuration example"
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import dashboard

init(
    app_info=InputAppInfo(
        api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        # TODO: Initialise other recipes
        dashboard.init(),
    ]
)
```
</Tab>
</CodeGroup>

#### Update your content security policy (optional)

<DependentContent passive group="backend-language">
<ContentOption title="Node.js" value="nodejs">
If your backend returns a `Content-Security-Policy` header, you encounter the following UI displaying the Content Security Policy violation details. Follow the instructions provided in this UI to make necessary adjustments to your backend Content Security Policy configuration.

![Content Security Policy error handled UI](/docs-assets/img/dashboard/csp-error.png)

For example, to address the error message displayed in the above screenshot, you need to modify your `original policy`. In the given example, it appears as follows:
</ContentOption>
<ContentOption title="Go" value="go">
If you return a `Content-Security-Policy` header from your backend, you need to include the following directives for the user management dashboard to work correctly.
</ContentOption>
<ContentOption title="Python" value="python">
If you return a `Content-Security-Policy` header from your backend, you need to include the following directives for the user management dashboard to work correctly.
</ContentOption>
</DependentContent>

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```text
script-src:
  'self'
  'unsafe-inline'
  https://google.com

img-src:
  https://google.com
```
</Tab>
<Tab title="Go" value="go">
```text
script-src:
  'self'
  'unsafe-inline'
  https://cdn.jsdelivr.net/gh/supertokens/
img-src:
  https://cdn.jsdelivr.net/gh/supertokens/
  https://purecatamphetamine.github.io/
```
</Tab>
<Tab title="Python" value="python">
```text
script-src:
  'self'
  'unsafe-inline'
  https://cdn.jsdelivr.net/gh/supertokens/
img-src:
  https://cdn.jsdelivr.net/gh/supertokens/
  https://purecatamphetamine.github.io/
```
</Tab>
</CodeGroup>

<DependentContent passive group="backend-language">
<ContentOption title="Node.js" value="nodejs">
To resolve this issue, make the following adjustments:
</ContentOption>
</DependentContent>

<CodeGroup passive group="backend-language">
<Tab title="Node.js" value="nodejs">
```text
script-src:
  'self'
  'unsafe-inline'
  https://google.com

img-src:
  https://google.com
  https://cdn.jsdelivr.net/gh/supertokens/

```
</Tab>
</CodeGroup>

<DependentContent passive group="backend-language">
<ContentOption title="Node.js" value="nodejs">
Essentially, you need to include the domain listed as the  `Blocked URI` in your violated directive block within your original policy.
</ContentOption>
</DependentContent>

### 2. Access the dashboard

:::note[The backend SDK serves the user management dashboard, and you have to use your API domain when trying to visit the dashboard.]
:::

Navigate to `<YOUR_API_DOMAIN>/auth/dashboard` to view the dashboard.

:::note[If you are using Next.js, upon integrating the backend SDK into your Next.js API folder, the dashboard becomes accessible by default at `<YOUR_API_DOMAIN>/api/auth/dashboard`. For frameworks other than Next.js, access it at `<YOUR_API_DOMAIN>/auth/dashboard`. Should you have customized the `apiBasePath` configuration property, navigate to `<YOUR_API_DOMAIN>/auth/dashboard` to access the dashboard.]
:::

<img src="/docs-assets/img/dashboard/login.png" alt="Dashboard login screen UI" />

### 3. Create dashboard credentials

:::info[Paid Feature]
You can create 3 dashboard users* for free.

If you need to create additional users:

- For self hosted users, please [sign up](https://supertokens.com/auth) to generate a license key and follow the instructions sent to you by email.
- For managed service users, open the [SaaS Dashboard](https://supertokens.com/dashboard), select the relevant **Managed** deployment, and enable **Additional Dashboard Users** from **Features**.

*: A dashboard user is a user that can log into and view the user management dashboard. These users are independent to the users of your application
:::

When you first set up SuperTokens, there are no credentials created for the dashboard. If you click the "Add a new user" button in the dashboard login screen you can see the command you need to execute to create credentials.

<img src="/docs-assets/img/dashboard/signup.png" alt="Dashboard sign up screen UI" />

To create credentials you need to make a request to SuperTokens core.

- The example above uses the demo core `https://try.supertokens.com`, replace this with the connection URI you pass to the backend SDK when initialising SuperTokens.
- Replace `<YOUR-API-KEY>` with your API key. If you are using a self hosted SuperTokens core there is no API key by default. In that case you can either skip or ignore the `api-key` header.
- Replace `<YOUR_EMAIL>` and `<YOUR_PASSWORD>` with the appropriate values.

:::warning[If using self-hosted SuperTokens core, you need to make sure that you add an API key to the core in case it's exposed to the internet. Otherwise, anyone can create or modify dashboard users.]

You can add an API key to the core by following the instructions "Auth flow customizations" > "SuperTokens core settings" > "Adding API keys" page.
:::

### 4. Update dashboard credentials

You can update the email or password of existing credentials by using the "Forgot Password" button on the dashboard login page.

<img src="/docs-assets/img/dashboard/forgot-password.png" alt="Reset your password screen UI" />

To update credentials you need to make a request to SuperTokens core.

- The example above uses the demo core `https://try.supertokens.com`, replace this with the connection URI you pass to the backend SDK when initialising SuperTokens.
- Replace `<YOUR-API-KEY>` with your API key. If you are using a self hosted SuperTokens core there is no API key by default. In that case you can either skip or ignore the `api-key` header.
- Replace `<YOUR_EMAIL>` and `<YOUR_NEW_PASSWORD>` with the appropriate values. You can use `newEmail` instead of `newPassword` if you want to update the email

### 5. Restrict access to dashboard users

When using the dashboard recipe, you can restrict access to certain features by providing a list of emails considered as "admins." If a dashboard user logs in with an email not present in this list, they can only perform read operations. All write operations result in the backend SDKs failing the request.

You can provide an array of emails to the backend SDK when initialising the dashboard recipe:

:::note[- Not providing an admins array results in all dashboard users having both read and write operations.]
- Providing an empty array as admins results in all dashboard users having only read access.
:::

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import Dashboard from "supertokens-node/recipe/dashboard";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    // TODO: Initialise other recipes
    Dashboard.init({
      admins: ["johndoe@gmail.com"],
    }),
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"github.com/supertokens/supertokens-golang/recipe/dashboard"
	"github.com/supertokens/supertokens-golang/supertokens"
  "github.com/supertokens/supertokens-golang/recipe/dashboard/dashboardmodels"
)

func main() {
  supertokens.Init(supertokens.TypeInput{
      RecipeList: []supertokens.Recipe{
        // TODO: Initialise other recipes
        dashboard.Init(&dashboardmodels.TypeInput{
          Admins: &[]string{
            "johndoe@gmail.com",
          },
        }),
      },
  });
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="Partial configuration example"
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import dashboard

init(
    app_info=InputAppInfo(
        api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        # TODO: Initialise other recipes
        dashboard.init(
          admins=[
            "johndoe@gmail.com",
          ],
        ),
    ]
)
```
</Tab>
</CodeGroup>
