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

# JWT authentication

> Validates a JWT signed by the embedding application and creates a Basedash session for the user specified in the JWT claims. On success, redirects to the organization dashboard.

## When to use

This endpoint is used for **full app embedding** - embedding the entire Basedash application within your own product via an iframe. This allows your users to access Basedash dashboards without leaving your application or managing separate Basedash credentials.

## How it works

1. Your server generates a JWT containing user information, signed with your organization's embed JWT secret
2. You set the iframe `src` to this endpoint with the JWT as a query parameter
3. Basedash validates the JWT signature against your organization's secret
4. If valid, Basedash creates or updates the user account and establishes a session restricted to that organization
5. The user is redirected to your organization's dashboard inside the iframe

## Setup requirements

Before using this endpoint, you must:

1. **Enable embedding** for your organization via the API or Basedash settings
2. **Store the embed JWT secret** returned when creating/updating your organization - this is used to sign your JWTs
3. **Configure allowed origins** (recommended) to restrict which domains can embed your Basedash organization

## JWT structure

Sign your JWT using the HS256 algorithm with your organization's `jwtSecret`. The JWT payload should contain:

```json
{
  "email": "user@example.com",
  "orgId": "org_abc123",
  "firstName": "Jane",
  "lastName": "Doe",
  "role": "MEMBER",
  "groups": ["Billing", "Program A"],
  "exp": 1234567890,
  "iat": 1234567800
}
```

The optional `role` claim accepts `ADMIN`, `MEMBER`, or `VIEWER`.
When supplied, it is the source of truth for the active membership on every
login. Omit it to preserve an active membership's role; new or reactivated
memberships without a role claim default to `MEMBER`. `VIEWER` is read-only.

## Groups

The optional `groups` claim lists the names of existing Basedash groups the
user belongs to. Use it to scope dashboards, chats, data sources and row-level
security to groups you manage from your application. When supplied, it is
applied on every login:

| Situation | Result |
| - | - |
| A name matches a group the user isn't in | The user is added to the group |
| The claim no longer names a group this claim added the user to | The user is removed from that group |
| The user was added to a group in Basedash, through the API or by SCIM | Never removed by the claim |
| `groups` is `[]` | Removes every membership the claim added |
| `groups` is omitted | Group memberships are left unchanged |

* Names match case-insensitively, ignoring leading and trailing spaces.
* Groups are never created. Create them first with `POST /organizations/{orgId}/groups`,
  and give them access before users log in.
* A name that matches no group, matches more than one group, or names a
  SCIM-managed group is skipped. So is the whole claim when it lists more than
  100 distinct names. The login still succeeds. Each login that changes
  memberships or skips a name records a `group.login_token_synced` audit event
  listing the groups added and removed and every skipped name with its reason
  (`unknown`, `ambiguous`, `scim_managed` or `invalid_name`).
* Audit logs require the Enterprise plan. On Enterprise, find these events
  under **Settings → Audit logs**, or query them with an administrator API key:
  `GET /organizations/{orgId}/audit-logs?action=group.login_token_synced`.
  On other plans, compare the names you send with
  `GET /organizations/{orgId}/groups`.
* If an admin removes a membership the claim added, the next login adds it back.
  To revoke access, remove the group from the claim. To revoke it immediately
  as well, also remove the membership in Basedash or through the API.
* On data sources with row-level security, group names are passed to your
  policies, so adding a group can widen the data a user sees.

## Example implementation

```html
<iframe 
  src="https://charts.basedash.com/api/sso/jwt?jwt=YOUR_JWT_TOKEN"
  width="100%"
  height="600"
  frameborder="0"
/>
```

```javascript
// Server-side JWT generation (Node.js example)
import jwt from 'jsonwebtoken';

const token = jwt.sign(
  {
    email: user.email,
    orgId: 'org_abc123',
    firstName: user.firstName,
    lastName: user.lastName,
    role: 'MEMBER',
    groups: ['Billing', 'Program A'],
  },
  process.env.BASEDASH_EMBED_JWT_SECRET,
  { expiresIn: '10m' }
);
```

## Customizing the embed

Append any of these query parameters to the iframe URL. They are forwarded through the redirect.

**Appearance and features** apply for the rest of the iframe session, so later in-app navigation keeps them:

| Parameter | Values | Effect |
| - | - | - |
| `theme` | `light`, `dark`, `auto` | Override the theme |
| `hide_org_name` | `true`, `false` | Hide the organization name in the sidebar |
| `hide_chat` | `true`, `false` | Hide the Chat page and chat panel |
| `hide_dashboards` | `true`, `false` | Hide dashboards |
| `hide_insights` | `true`, `false` | Hide insights |
| `hide_automations` | `true`, `false` | Hide automations |
| `hide_models` | `true`, `false` | Hide models |
| `hide_suggested_prompts` | `true`, `false` | Hide suggested prompts in the chat input |
| `hide_sidebar` | `true`, `false` | Don't render the left sidebar at all, with no way to reopen it |

At least one of chat, dashboards, insights, automations, or models stays visible; Basedash falls back to chat if all are hidden.

With `hide_sidebar=true` your application owns navigation. Breadcrumbs and search remain, but lists that only live in the sidebar (all dashboards and folders, chat history) are not shown, so pair it with a single visible feature and, for dashboards, an initial page. Hiding the sidebar is presentation only, not access control: use Basedash permissions to restrict what a user can open.

**Initial page** parameters choose the page the embed opens on. Set at most one:

| Parameter | Opens |
| - | - |
| `dashboard_id` | A dashboard (combine with `tab` to open a dashboard tab) |
| `automation_id` | An automation |
| `insight_id` | An insight |
| `model_id` | A model |
| `chat_id` | A chat |

The initial page is only where the embed opens; users can still navigate elsewhere. It is ignored when its feature is hidden or disabled, and the embed opens on the default page instead. An unknown or inaccessible ID shows a not-found page.

```html
<iframe
  src="https://charts.basedash.com/api/sso/jwt?jwt=YOUR_JWT_TOKEN&hide_chat=true&hide_insights=true&hide_automations=true&hide_models=true&hide_sidebar=true&dashboard_id=DASHBOARD_ID"
/>
```

## Security considerations

* **Keep your JWT secret secure** - Never expose it in client-side code
* **Use short expiration times** - JWTs should expire within minutes
* **Configure allowed origins** - Restrict embedding to your domains only
* **Organization-scoped access** - JWT sessions cannot access the user's other Basedash organizations
* **Generate JWTs server-side** - Never generate JWTs in the browser


## OpenAPI

````yaml https://charts.basedash.com/api/public/openapi get /api/sso/jwt
openapi: 3.1.0
info:
  title: Basedash Public API
  version: 0.0.0
  description: >-
    API for programmatic access to Basedash features. Use API keys for
    authentication.
  contact:
    name: Basedash Support
    url: https://basedash.com
    email: support@basedash.com
servers:
  - url: https://charts.basedash.com
    description: Production
security: []
tags:
  - name: Organizations
    description: Manage organizations
  - name: Groups
    description: Manage organization groups and memberships
  - name: Data Sources
    description: Manage database connections and data sources
  - name: MCP servers
    description: Manage MCP server data sources
  - name: Insights
    description: Manage generated insights
  - name: Automations
    description: Manage automations and automation runs
  - name: Skills
    description: Manage organization skills
  - name: Models
    description: Manage reusable SQL models
  - name: Dashboards
    description: Manage dashboards and their tabs
  - name: Charts
    description: Manage charts and their SQL queries
  - name: Chats
    description: >-
      Chat with the Basedash AI agent about your data. Start a chat by sending a
      message, then continue the conversation with follow-up messages. The
      assistant responds asynchronously: pass the `wait` query parameter to
      receive the finished response in the same request, or poll the assistant
      message (or stream its events) after an HTTP 202. Chats created through
      the API are not shown in the Basedash app.
paths:
  /api/sso/jwt:
    get:
      tags:
        - Embedding
      summary: JWT authentication
      description: >-
        Validates a JWT signed by the embedding application and creates a
        Basedash session for the user specified in the JWT claims. On success,
        redirects to the organization dashboard.
      parameters:
        - schema:
            type: string
            description: JWT token signed with your organization embed secret (HS256)
          required: true
          description: JWT token signed with your organization embed secret (HS256)
          name: jwt
          in: query
        - schema:
            type: string
            enum:
              - light
              - dark
              - auto
            description: Override the theme
          required: false
          description: Override the theme
          name: theme
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            description: >-
              Hide the organization name in the sidebar. Persists for the iframe
              session.
          required: false
          description: >-
            Hide the organization name in the sidebar. Persists for the iframe
            session.
          name: hide_org_name
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            description: >-
              Hide the Chat page and chat panel. Persists for the iframe
              session.
          required: false
          description: Hide the Chat page and chat panel. Persists for the iframe session.
          name: hide_chat
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            description: Hide dashboards. Persists for the iframe session.
          required: false
          description: Hide dashboards. Persists for the iframe session.
          name: hide_dashboards
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            description: Hide insights. Persists for the iframe session.
          required: false
          description: Hide insights. Persists for the iframe session.
          name: hide_insights
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            description: Hide automations. Persists for the iframe session.
          required: false
          description: Hide automations. Persists for the iframe session.
          name: hide_automations
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            description: Hide models. Persists for the iframe session.
          required: false
          description: Hide models. Persists for the iframe session.
          name: hide_models
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            description: >-
              Hide suggested prompts in the chat input. Persists for the iframe
              session.
          required: false
          description: >-
            Hide suggested prompts in the chat input. Persists for the iframe
            session.
          name: hide_suggested_prompts
          in: query
        - schema:
            type: string
            enum:
              - 'true'
              - 'false'
            description: >-
              Do not render the left sidebar, with no way to reopen it. Persists
              for the iframe session.
          required: false
          description: >-
            Do not render the left sidebar, with no way to reopen it. Persists
            for the iframe session.
          name: hide_sidebar
          in: query
        - schema:
            type: string
            description: Open the embed on this dashboard
          required: false
          description: Open the embed on this dashboard
          name: dashboard_id
          in: query
        - schema:
            type: string
            description: With dashboard_id, the dashboard tab to open
          required: false
          description: With dashboard_id, the dashboard tab to open
          name: tab
          in: query
        - schema:
            type: string
            description: Open the embed on this automation
          required: false
          description: Open the embed on this automation
          name: automation_id
          in: query
        - schema:
            type: string
            description: Open the embed on this insight
          required: false
          description: Open the embed on this insight
          name: insight_id
          in: query
        - schema:
            type: string
            description: Open the embed on this model
          required: false
          description: Open the embed on this model
          name: model_id
          in: query
        - schema:
            type: string
            description: Open the embed on this chat
          required: false
          description: Open the embed on this chat
          name: chat_id
          in: query
      responses:
        '302':
          description: Redirect to organization dashboard on successful authentication
          headers:
            Location:
              schema:
                type: string
                description: URL to the organization dashboard
              required: true
              description: URL to the organization dashboard
            Set-Cookie:
              schema:
                type: string
                description: Session cookie
              required: true
              description: Session cookie
        '400':
          description: Bad request - Missing JWT, invalid format, or invalid claims
          content:
            text/html:
              schema:
                type: string
                description: HTML error page
        '401':
          description: Unauthorized - JWT signature verification failed or expired
          content:
            text/html:
              schema:
                type: string
                description: HTML error page
        '403':
          description: Forbidden - Embedding not enabled or request from disallowed origin
          content:
            text/html:
              schema:
                type: string
                description: HTML error page
        '404':
          description: Not found - Organization not found
          content:
            text/html:
              schema:
                type: string
                description: HTML error page
        '429':
          description: Too many requests - per-IP rate limit exceeded
          headers:
            Retry-After:
              schema:
                type: string
                description: Seconds to wait before retrying
              required: true
              description: Seconds to wait before retrying
          content:
            text/html:
              schema:
                type: string
                description: HTML error page
        '500':
          description: Internal server error, including a failure to apply the groups claim
          content:
            text/html:
              schema:
                type: string
                description: HTML error page
      security: []

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.