logoSemaphor

Token Options

Options for generating an Auth Token to embed a dashboard

Overview

This section outlines the different options available for generating AuthToken.

AuthToken is a unique, time-sensitive token that secures access to your dashboard. To generate this token, you need to include DASHBOARD_ID and DASHBOARD_SECRET as required fields in the request body, as shown below:

const DASHBOARD_ID = 'd_cf007a8b-19bc-46ad-8787-2915445b7b86'; // Replace with your actual dashboard ID
const DASHBOARD_SECRET = 'ds_f32f0b30-b7e1-40f9-ba6a-9804a5b9d635'; // Replace with your actual dashboard secret
const TOKEN_URL = 'https://semaphor.cloud/api/v1/token';
 

const requestBody = {


  dashboardId: DASHBOARD_ID, 
  dashboardSecret: DASHBOARD_SECRET, 
}; 
 
async function fetchToken() {
  try {
    const response = await fetch(TOKEN_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(requestBody),
    });
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
 
    const token = await response.json();
    if (token?.accessToken) {
      setAuthToken(token);
    }
  } catch (error) {
    console.error('There was an error!', error);
  }
}

Token Expiry

By default, the AuthToken is valid for 1 hour. However, you can specify a custom expiry time in the request body. Once the token expires, it will no longer be valid, and you will see a "Session expired" message on the dashboard.

The token expiry is specified in seconds. For example, to set the expiry time to 10 minutes, you can pass tokenExpiry: 60 * 10 in the request body.

const requestBody = {
  dashboardId: DASHBOARD_ID,
  dashboardSecret: DASHBOARD_SECRET,
  tokenExpiry: 60 * 10, // 10 minutes //
};

This token will remain valid for 10 minutes. This feature is particularly useful if you want to synchronize your application's session timeout with the dashboard, ensuring a seamless and consistent user experience.

You can also explicitly invalidate the token by calling the invalidateToken function when the user logs out of your application.

import { invalidateToken } from 'semaphor';
 
async function handleLogout() {
  await invalidateToken();
}
 
<button onClick={handleLogout}>Logout</button>;

The invalidateToken function sends a POST request to https://semaphor.cloud/api/v1/invalidate-token to revoke the current session. The request includes the active accessToken in the Authorization header.


User Params

In some instances, you may want to pass user specific information to the dashboard. For example, the currency of the user's region. You can pass this information in the params field in the request body.

const requestBody = {
  dashboardId: DASHBOARD_ID,
  dashboardSecret: DASHBOARD_SECRET,
  params: {

    currencyFormat: {
      locale: 'en-US',
      currency: 'USD',
    },
  },
};

Before rendering the currency for the numbers on the dashboard, Semaphor will first check if the currencyFormat is set in the params field of the AuthToken. If it is, Semaphor will use the currency format specified in the params field. If not, Semaphor will default to the currency format specified in the dashboard settings.

The locale and the currency fields must conform to the Intl.NumberFormat format.

Security Policies

The AuthToken also controls what data user can see in the dashboard. You can set up security policies to restrict the data that a user can access. For more information, see Security & Multi-tenancy section.


Project Tokens

Project tokens provide secure, scoped access to project resources with flexible identity resolution, security policies, and UI configuration options. Unlike dashboard tokens, project tokens are designed for broader access across multiple dashboards within a project.

Project Token Overview

Project tokens are JWT-based authentication tokens that enable:

  • Access to multiple dashboards within a project
  • Flexible user identity resolution
  • Just-in-time (JIT) user provisioning
  • Semantic domain restrictions
  • Advanced security policies

To generate a project token, you need to include projectId and projectSecret as required fields, along with type: 'project' in the request body:

const PROJECT_ID = 'p_1234567890abcdef'; // Replace with your actual project ID
const PROJECT_SECRET = 'ps_abcdef1234567890'; // Replace with your actual project secret
const TOKEN_URL = 'https://semaphor.cloud/api/v1/token';
 
const requestBody = {
  type: 'project', // Required for project tokens
  projectId: PROJECT_ID,
  projectSecret: PROJECT_SECRET,
  endUserId: 'user_123', // User identification
};
 
async function fetchProjectToken() {
  try {
    const response = await fetch(TOKEN_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(requestBody),
    });
 
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
 
    const token = await response.json();
    return token;
  } catch (error) {
    console.error('Error generating token:', error);
  }
}

Identity Resolution

Project tokens support three methods for identifying users:

1. Direct User ID Lookup

When you already have the user ID stored in your system:

const requestBody = {
  type: 'project',
  projectId: PROJECT_ID,
  projectSecret: PROJECT_SECRET,
  endUserId: 'user_456', // Direct user ID
  initialDashboardId: 'dashboard_789', // Optional: specific dashboard to load
};

2. Email + Tenant Lookup

Identify users by email and tenant association:

// Option A: Using tenant ID
const requestBody = {
  type: 'project',
  projectId: PROJECT_ID,
  projectSecret: PROJECT_SECRET,
  endUserEmail: 'user@example.com',
  tenantId: 'tenant_456',
};
 
// Option B: Using tenant name
const requestBody = {
  type: 'project',
  projectId: PROJECT_ID,
  projectSecret: PROJECT_SECRET,
  endUserEmail: 'user@example.com',
  tenantName: 'Acme Corp', // Tenant name instead of ID
};

3. Just-In-Time (JIT) User Provisioning

Automatically create new users on their first access:

const requestBody = {
  type: 'project',
  projectId: PROJECT_ID,
  projectSecret: PROJECT_SECRET,
  endUserEmail: 'newuser@example.com',
  tenantName: 'Acme Corp', // Or use tenantId
  autoCreateEndUser: true, // Enable auto-creation
  role: 'VIEWER', // Optional: 'VIEWER' (default) or 'POWER_USER'
  displayName: 'John Doe', // Optional: display name
};

Important Notes about JIT Provisioning:

  • The tenant must already exist (new tenants are not created)
  • If autoCreateEndUser is false or omitted, non-existent users will cause an error
  • Default role is 'VIEWER' if not specified
  • Display name defaults to the email prefix if not provided

Semantic Domain Restrictions

Restrict token access to specific semantic domains within your project. You can use either domain UUIDs or semantic names:

// Using domain names
const requestBody = {
  type: 'project',
  projectId: PROJECT_ID,
  projectSecret: PROJECT_SECRET,
  endUserId: 'user_123',
  allowedSemanticDomains: ['sales_data', 'customer_analytics', 'inventory'],
};
 
// Using domain UUIDs
const requestBody = {
  type: 'project',
  projectId: PROJECT_ID,
  projectSecret: PROJECT_SECRET,
  endUserId: 'user_123',
  allowedSemanticDomains: [
    '550e8400-e29b-41d4-a716-446655440001',
    '550e8400-e29b-41d4-a716-446655440002',
  ],
};
 
// Mixed: Using both names and UUIDs
const requestBody = {
  type: 'project',
  projectId: PROJECT_ID,
  projectSecret: PROJECT_SECRET,
  endUserId: 'user_123',
  allowedSemanticDomains: [
    'sales_data', // Domain name
    '550e8400-e29b-41d4-a716-446655440002', // UUID
    'inventory', // Domain name
  ],
};

Organization User Authentication

For organization-level users (typically internal users with broader permissions):

const requestBody = {
  type: 'project',
  projectId: PROJECT_ID,
  projectSecret: PROJECT_SECRET,
  orgUserId: 'org_user_123',
};

Complete Examples

Example 1: Basic Project Token with User Lookup

const requestBody = {
  type: 'project',
  projectId: 'p_1234567890abcdef',
  projectSecret: 'ps_abcdef1234567890',
  endUserId: 'user_123',
  tokenExpiry: 3600, // 1 hour
};

Example 2: Auto-Provision New User with Domain Restrictions

const requestBody = {
  type: 'project',
  projectId: 'p_1234567890abcdef',
  projectSecret: 'ps_abcdef1234567890',
  endUserEmail: 'newuser@company.com',
  tenantName: 'Company Inc',
  autoCreateEndUser: true,
  role: 'POWER_USER',
  displayName: 'New User',
  allowedSemanticDomains: ['sales_data', 'marketing_analytics'],
  initialDashboardId: 'dashboard_main',
  tokenExpiry: 7200, // 2 hours
};

Example 3: Existing User with Security Policies

const requestBody = {
  type: 'project',
  projectId: 'p_1234567890abcdef',
  projectSecret: 'ps_abcdef1234567890',
  endUserEmail: 'user@example.com',
  tenantId: 'tenant_789',
  cls: {
    name: 'store_sales_primary',
    params: { tenant: 'tenant_abc_123' },
  },
  rcls: {
    name: 'region_filter',
    params: { state: ['California', 'Nevada'] },
  },
  params: {
    currencyFormat: {
      locale: 'en-US',
      currency: 'USD',
    },
  },
  config: {
    showAdvancedMode: true,
    showDashboardAssistant: false,
  },
};

Error Handling

Common error messages and their solutions:

Error MessageCauseSolution
"Project ID is required"Missing projectIdInclude projectId in request
"Project secret is required"Missing projectSecretInclude projectSecret in request
"Invalid project credentials"Wrong projectId or projectSecretVerify credentials are correct
"User 'email@example.com' not found in tenant"User doesn't existSet autoCreateEndUser: true or create user first
"Tenant 'TenantName' not found"Tenant doesn't existVerify tenant name or create tenant first
"The following semantic domains were not found"Invalid domain names/IDsCheck domain exists in project
"User identification required"No user identification providedProvide endUserId, orgUserId, or endUserEmail with tenant

Using TokenRequest

When requesting a token from Semaphor API, you can use the TokenRequest type to define the request body and customize your analytics experience.

API Endpoint

POST http://localhost:3000/api/v1/token

Request Body

The request body should match the TokenRequest structure:

/**
 * Parameters for customizing token behavior and formatting.
 */
export type TokenParams = {
  currencyFormat: {
    /**
     * Locale identifier (e.g., 'en-US', 'fr-FR').
     */
    locale: string;
 
    /**
     * Currency code compliant with ISO 4217 (e.g., 'USD', 'EUR').
     */
    currency: string;
  };
  /**
   * Timezone of the user.
   */
  timezone: string;
};
 
/**
 * Defines a security policy that can be applied at connection or row level.
 */
export type TokenSecurityPolicy = {
  /**
   * Name of the policy (e.g., 'store_sales_primary', 'region_filter').
   */
  name: string;
 
  /**
   * Arbitrary parameters associated with the policy.
   * Examples:
   *
   * // Single value
   * {
   *   tenant: 'tenant_abc_123'
   * }
   *
   * // Multiple values
   * {
   *   state: ['California', 'Nevada', 'Washington']
   * }
   */
  params: {
    [key: string]: string | number | string[] | number[];
  };
};
 
/**
 * UI and behavior configuration for the embedded dashboard.
 */
export type UIConfig = {
  /**
   * Enables self-service editing and lens creation by the end user. Legacy field. Use config.allowEdit instead.
   */
  allowEdit?: boolean;
 
  /**
   * Enables advanced mode features in the dashboard.
   * Defaults to true unless explicitly disabled.
   */
  showAdvancedMode?: boolean;
 
  /**
   * Enables the Info tab in the editor/explorer view.
   * Defaults to true unless explicitly disabled.
   */
  showInfoTab?: boolean;
 
  /**
   * Enables the AI-powered dashboard assistant.
   * Defaults to true unless explicitly disabled.
   */
  showDashboardAssistant?: boolean;
};
 
/**
 * Main payload for generating a secure access token for a dashboard.
 */
export type DashboardTokenRequest = {
  /**
   * Identifier of the dashboard to be accessed.
   */
  dashboardId: string;
 
  /**
   * Secret key used for validating access to the dashboard.
   */
  dashboardSecret: string;
 
  /**
   * Token expiry duration in seconds.
   */
  tokenExpiry?: number;
 
  /**
   * Unique identifier of the tenant.
   */
  tenantId?: string;
 
  /**
   * Unique identifier of the end user accessing the dashboard.
   */
  endUserId?: string;
 
  /**
   * Email of the end user (for personalization, audit, or identification).
   */
  endUserEmail?: string;
 
  /**
   * Enables self-service editing and lens creation by the end user.
   */
  allowEdit?: boolean;
 
  /**
   * Connection-level security policies.
   * Can be a single policy or an array of policies.
   */
  cls?: TokenSecurityPolicy[] | TokenSecurityPolicy;
 
  /**
   * Row-level security policies.
   * Can be a single policy or an array of policies.
   */
  rcls?: TokenSecurityPolicy[] | TokenSecurityPolicy;
 
  /**
   * Parameter overrides and preferences (e.g., formatting).
   */
  params?: TokenParams;
 
  /**
   * UI behavior and feature flags.
   */
  config?: UIConfig;
};
 
/**
 * Main payload for generating a project-level access token.
 */
export type ProjectTokenRequest = {
  /**
   * Must be 'project' for project tokens.
   */
  type: 'project';
 
  /**
   * Unique identifier of the project.
   */
  projectId: string;
 
  /**
   * Secret key used for validating access to the project.
   */
  projectSecret: string;
 
  /**
   * Token expiry duration in seconds.
   */
  tokenExpiry?: number;
 
  /**
   * Unique identifier of the tenant.
   */
  tenantId?: string;
 
  /**
   * Name of the tenant (alternative to tenantId).
   */
  tenantName?: string;
 
  /**
   * Unique identifier of the end user.
   */
  endUserId?: string;
 
  /**
   * Email of the end user.
   */
  endUserEmail?: string;
 
  /**
   * Unique identifier of the organization user.
   */
  orgUserId?: string;
 
  /**
   * Display name for the user.
   */
  displayName?: string;
 
  /**
   * Automatically create user if they don't exist.
   */
  autoCreateEndUser?: boolean;
 
  /**
   * Role for auto-created users ('VIEWER' or 'POWER_USER').
   */
  role?: 'VIEWER' | 'POWER_USER';
 
  /**
   * Initial dashboard to load.
   */
  initialDashboardId?: string;
 
  /**
   * Array of semantic domain IDs or names to restrict access.
   */
  allowedSemanticDomains?: string[];
 
  /**
   * Enables self-service editing.
   */
  allowEdit?: boolean;
 
  /**
   * Connection-level security policies.
   */
  cls?: TokenSecurityPolicy[] | TokenSecurityPolicy;
 
  /**
   * Row-level security policies.
   */
  rcls?: TokenSecurityPolicy[] | TokenSecurityPolicy;
 
  /**
   * Schema-level security policy.
   */
  sls?: string;
 
  /**
   * Parameter overrides and preferences.
   */
  params?: TokenParams;
 
  /**
   * UI behavior and feature flags.
   */
  config?: UIConfig;
};
 
/**
 * Combined token request type.
 */
export type TokenRequest = DashboardTokenRequest | ProjectTokenRequest;