Deployment
Tokens API

Tokens API

Whenever a user accesses an Embeddable dashboard in your app, you should fetch a security token from our Tokens API. This token applies row-level security (and more) to their dashboard session.

Open APIs In Bruno

Example: Fetch a Token

Important: Always call this server-side—never from client code, to avoid exposing your API key.

fetch('https://api.<region>.embeddable.com/api/v1/security-token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': `Bearer ${apiKey}` // Keep your API key secure
  },
  body: JSON.stringify({
    embeddableId: '<dashboard-id>', // the id of the dashboard you want to load
    savedVersion: 'production', // or 'development' or 'staging', etc.
    expiryInSeconds: 60 * 60 * 24 * 7, // token expiry (e.g. 1 week)
    securityContext: { // any context (key-value pairs) you want to provide to the SQL data models
      userId: '9sZSJ9LHsiYXR0cmlidXRlIjoiZ2VvaXBf',
      regions: ['us-east', 'eu-west']
    },
    user: 'example@domain.com', // unique key (e.g. email or user_id) representing current user
    //
    // for more fields, see "Comprehensive example" below
    //
  })
})
.then((resp) => resp.json())
.then(({ token }) => {
  // 'token' is the security token your `<em-beddable token={token}.../>` web component needs
  console.log(token);
});

Response:

{
  "token": "eyJhbGciOiJIUzI1NiJ9.eyJzZWN1cml0eVRva2VuSWQiOiI1OGE1NGYwMi0xNTJmLTQxMjgtYWZmZC0zMDhhYzI0NTE5ZGQiLCJpYXQiOjE3MDczMTU1NDUsImV4cCI6MTcwNzkyMDM0NX0.lnovN0xTMCjLcxGTIfzFD9cYRIAZjn6S7sew-ih11lM"
}

You would then use this token in your <em-beddable> element, as explained in Embedding an Embeddable.

Learn more about region here.

Comprehensive example

fetch('https://api.<region>.embeddable.com/api/v1/security-token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': `Bearer ${apiKey}` // Keep your API key secure
  },
  body: JSON.stringify({
    //
    // required fields
    //
    embeddableId: '<dashboard-id>', //the id of the dashboard you want to load
    savedVersion: 'production', // or 'development' or 'staging', etc.
    expiryInSeconds: 60 * 60 * 24 * 7, // token expiry (e.g. 1 week)
    securityContext: { // any context (key-value pairs) you want to provide to the SQL data models
      userId: '9sZSJ9LHsiYXR0cmlidXRlIjoiZ2VvaXBf',
      regions: ['us-east', 'eu-west']
    },
    user: 'example@domain.com', // unique key (e.g. email or user_id) representing current user
 
    //
    // optional fields
    //
    customCanvasState: 'user-1-dashboard-7', // optional key used by "custom canvas" functionality to store end-user custom dashboard state
    customCanvasReadOnly: false, // turns off custom dashboard editing for your end-user (if "custom canvas" is enabled)
 
    //
    // managed Cube (default)
    //
    environment: 'default', // optional, tells Embeddable which set of databases to retrieve data from
    roles: ['manager'], // optional, tells Embeddable which access-policy roles to grant this user e.g. manager, admin etc.
 
    //
    // external Cube (e.g. Cube Cloud)
    //
    dataProvider: 'my-cube-deployment' // tells Embeddable which external Cube deployment to connect to
  })
})
.then((resp) => resp.json())
.then(({ token }) => {
  // 'token' is the security token your `<em-beddable token={token}.../>` web component needs
  console.log(token);
});

Parameters

  • embeddableId is the id of the Embeddable dashboard that you want to load. Click 'save version' or 'publish' on your Embeddable dashboard to get the id.

  • savedVersion this is the saved version of the Embeddable dashboard that you want to load. Available options include:

    • 'production' (default) - the saved version published with the 'Production' tag. This will be used by default if savedVersion is omitted.
    • 'staging' - the saved version published with the 'Staging' tag
    • 'development' - the saved version published with the 'Development' tag
    • 'v3' (or v11, etc.) - the saved version with the given version number.
  • securityContext is an arbitrary JSON object included in your token request. Embeddable passes it to your data models, allowing you to enforce row/table/schema-level security. For example:

    name: Orders
    sql: >
        SELECT user_id, created_at
        FROM public.orders
        WHERE user_id = '{ COMPILE_CONTEXT.securityContext.userId }'
        
        {% if COMPILE_CONTEXT.securityContext.regions %}
            AND region IN {{ list(COMPILE_CONTEXT.securityContext.regions) }}
        {% endif %}
  • roles optional field, only needed if you're using Access Policies. Grants the user one or more access policy roles. The roles you include determine which cube models, views, and rows the user can see across dashboards and data playground. If you don’t pass any roles, Embeddable assigns the "default" role. Refer to Access Policies for details on how roles drive visibility.

  • user is a unique identifier for the current user. It enables Embeddable to store (anonymous) session metadata against each user automatically so that customisations / preferences applied by the user to their Embeddable dashboard will automatically be remembered for their next session.

  • environment optional field, only needed if you're using Environments. Specifies which environment to retrieve data from. If omitted, the "default" environment is used. Environments let you achieve things like:

    • single-tenancy (AKA database-level security), where each of your customers has their data in a different database.
    • different database connections for prod, qa, testing, etc.
    • micro service architecture, where your data is spread across multiple databases.
  • dataProvider is required if (and only if) you are bringing your own Cube deployment. Specifies which external Cube deployment Embeddable should connect to. This must match a data provider you have created using the Data Provider API (for example, my-cube-deployment).

  • expiryInSeconds is the number of seconds until the token expires. The default is 7 days (60 * 60 * 24 * 7). Tokens are standard JWTs, and contain iat and exp when decoded. On your front-end, you can keep track of the token expiry and refresh it as needed with a call to the Embeddable Tokens API, without needing to reload the page.

  • customCanvasState is only needed if you are using Custom Canvas. Embeddable stores a custom canvas layout (per embeddableId) for each unique value of customCanvasState that you pass to the Tokens API. Learn how to use this field here.

  • customCanvasReadOnly is also only needed if you are using Custom Canvas. If true the end-user will only be able to view (and interact with) the dashboard, but not edit it (add/remove/move/resize charts). It defaults to false. Learn more here.

Testing Security Contexts

If you’re relying on securityContext in your data models, you’ll want to test them in Embeddable’s no-code builder. You can easily do this by creating presets.