curl Node.js PHP Java .NET Python Web Component Angular React React Native Vue
  • Introduction
  • Guides
  • Core API
  • Embedding
  • Plugin API
  • Introduction

    Welcome to the Luzmo API! You can use our API to integrate dashboards within your own applications, create or update datasets, open up new data sources or automate just about anything about your Luzmo experience.

    We offer 3 main APIs that are documented in detail:

    You can start reading our guides that cover common use cases or dive right into the API specifications or Component API specifications for further detail.

    In case of questions, you can reach our team at api@luzmo.com or support@luzmo.com.

    Good luck, and have fun!

    Guides

    Embedding with embed tokens

    Embedding a dashboard in your own application/platform is a simple process.

    1. Generate an embed authorization token (server-side)

    2. Embed the dashboard in your own application/platform (client-side)

    Embed into your application

    1. Generate an Embed token

       Replace with your API key & token and fill in the user's details 
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "properties":{
        "type": "embed",
        "expiry": "2024-02-13T10:38:08.493Z",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "role": "viewer",
        "access": {
          "dashboards":[
            {
              "id": "<a dashboard id>",
              "rights": "use"
            }
          ],
          "datasets":[
            {
              "id": "<a dataset id>",
              "rights": "use"
            }
          ],
          "collections": [
            {
              "id": "<a collection id>",
              "inheritRights": "use"
            }
          ]
        }
      }
    }
    EOF
    
       Replace with your API key & token and fill in the user's details 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: "< Your API key >",
        api_token: "< Your API token >",
        host: "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >"
    });
    
    let promise = client.create("authorization", {
      type: "embed",
      expiry: "2024-02-13T10:38:08.493Z",
      username: "< A unique and immutable identifier for your user >",
      name: "< user name >",
      email: "< user email >",
      suborganization: "< a suborganization name >",
      role: "viewer",
      access: {
          dashboards:[
            {
              id: "<a dashboard id>",
              rights: "use"
            }
          ],
          datasets:[
            {
              id: "<a dataset id>",
              rights: "use"
            }
          ],
          collections: [
            {
              id: "<a collection id>",
              inheritRights: "use"
            }
          ]
        }
    });
    
    promise.then(function(result){
      // return the result to the client
    })
    
    
       Replace with your API key & token and fill in the user's details 
    <?php
    $client = Luzmo::initialize("< your API key >", "< your API token >",
     "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    
    $authorization = $client->create("authorization", array(
      "type" => "embed",
      "expiry" => "2024-02-13T10:38:08.493Z",
      "username" => "< A unique and immutable identifier for your user >",
      "name" => "< user name >",
      "email" => "< user email >",
      "suborganization" => "< a suborganization name >",
      "role" => "viewer",
      "access" => array(
        "dashboards" => array(
          array(
            "id" => "<a dashboard id>",
            "rights" => "use"
          )
        ),
        "datasets" => array(
          array(
            "id" => "<a dataset id>",
            "rights" => "use"
          )
        ),
        "collections" => array(
          array(
            "id" => "<a collection id>",
            "inheritRights" => "use"
          )
        )
      )
    ));
    ?>
    
       Replace with your API key & token and fill in the user's details 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >",
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","embed")
      .put("expiry", "2024-02-13T10:38:08.493Z")
      .put("username", "< A unique and immutable identifier for your user >")
      .put("name", "< user name >")
      .put("email", "< user email >")
      .put("suborganization", "< a suborganization name >")
      .put("role", "viewer")
      .put("access", ImmutableMap.builder()
          .put("dashboards", ImmutableList.of(
              ImmutableMap.of(
                "id", "dashboard id",
                "rights", "use"
              )
            )
          )
          .put("datasets", ImmutableList.of(
              ImmutableMap.of(
                "id", "dataset id",
                "rights", "use"
              )
            )
          )
          .put("collections", ImmutableList.of(
              ImmutableMap.of(
                "id", "collection id",
                "inheritRights", "use"
              )
            )
          )
          .build()
      )
      .build()
    );
    
       Replace with your API key & token and fill in the user's details 
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "embed";
    properties.expiry = "2024-02-13T10:38:08.493Z";
    properties.username = "< A unique and immutable identifier for your user >";
    properties.name = "< user name >";
    properties.email = "< user email >";
    properties.suborganization = "< a suborganization name >";
    properties.role = "viewer";
    properties.access =  new {
        dashboards =  new List<dynamic> {
           new { 
                id = "dashboard Id",
                rights = "use"
            }
        },
        datasets =  new List<dynamic> {
           new { 
                id = "dataset id",
                rights = "use"
            }
        }
        collections =  new List<dynamic> {
           new { 
                id = "collection id",
                inheritRights = "use"
            }
        }
    };
    
    dynamic authorization = client.create("authorization", properties);
    Console.WriteLine("Success!", authorization);
    
       Replace with your API key & token and fill in the user's details 
    from luzmo.luzmo import Luzmo
    
    key = "Your Luzmo key"
    token = "Your Luzmo token"
    
    client = Luzmo(key, token,
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    
    authorization = client.create("authorization", {
        "type": "embed",
        "expiry": "2024-02-13T10:38:08.493Z",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "role": "viewer",
        "access": {
          "dashboards":[
            {
              "id": "<a dashboard id>",
              "rights": "use"
            }
          ],
          "datasets":[
            {
              "id": "<a dataset id>",
              "rights": "use"
            }
          ],
          "collections": [
            {
              "id": "<a collection id>",
              "inheritRights": "use"
            }
          ]
        }
    });
    
    
       This returns a JSON object with an id/token combination that we will use to embed: 
    {
      "type": "embed",
      "id": "< the embed authorization key >",
      "token": "< the embed authorization token >",
      "user_id": "< a uuid used on our end to identify the embed user >"
      // ...
    }
    

    In this step, your server-side code makes an API request to retrieve an authorization token of type embed. The result of this request is a key/token combination that will be used to in step 2 to securely embed the dashboard in your application/platform.

    The API request is a 'create' request for an authorization.

    Property Description
    type
    string REQUIRED
    embed Use the value 'embed' for embedding a dashboard.
    expiry
    date (RFC 3339)
    RFC3339 timestamp when this authorization will cease working. Defaults to 24 hours from creation default, with a maximum of 1 year.
    This is the hard (maximum) expiry time of the token, after which it will *always* be invalid. We advise using short expiry time, eg. 24 hours from now.
    inactivity_interval
    integer
    Duration of inactivity (in seconds) after which the token is prematurely invalidated. Defaults to 0.
    You can use this to prematurely invalidate tokens when the user session in your application has ended (eg. all open dashboards are closed). A value of 0 means no premature invalidation due to inactivity (the token will only expire on the datetime specified in the expiry property of the Authorization request).

    We advise not to set the interval to a value smaller than 120 seconds, to avoid accidental invalidation for a dashboard that is still open, eg. when a heartbeat signal sent to the server is missed.
    username
    string REQUIRED
    Identifies the user uniquely and immutably. This should correspond to eg. the primary key for the user on your end. If it changes, the user will not have access to their previously created content anymore. So don't use eg. an e-mail address if those can change in your platform! This will also be used to uniquely identify a Monthly Active Viewer (MAV) for your Organization.
    name
    string REQUIRED
    The full name of the user (i.e. First name and Last name). This will be used in our UI.
    email
    string REQUIRED
    The email address of the user. This will be used in our UI.
    suborganization
    string
    Each embed token should be in a suborganization. The suborganization determines which other users they can see & interact with. it defaults to username to have total isolation, set to null if you want all users to see each other.
    access
    object REQUIRED
    Specifies which datasets, dashboards or collections the token will have access to. When providing direct access to a dashboard, make sure to also provide access to the underlying dataset(s) to avoid 'No access' errors!
    collections
    array
    List of Collections that contain one or more securables (dashboards and/or datasets), to which the token should have access to. The token will not have access to the Collection itself, but rather uses the Collection to access the underlying resources.
    If a securable is added or removed from a collection, you must generate a new token (i.e the token gets access to securables inside the collection at the time of creation).
    If you specify a dashboard and/or dataset in the dashboards / datasets property, which is also accessible to the token through a Collection which include this dashboard / dataset, the more specific right is applied (i.e the right specified in the dashboards / datasets property overrides the rights from the Collection).
    inheritRights
    string
    One of read,use, modify or own.
    Note that the API token used to generate the embed token must have similar or more access to the securables in the collection! If not, a warning message will be returned in the response to indicate that the embed token doesn't have access to one or more collection securables.
    id
    string
    Collection id you wish to give access to items inside
    datasets
    array
    List of datasets the token should have access to, with their individual access rights. If dataset(s) are specified which are also accessible through a specified Collection, the explicit dataset access rights specified in this datasets property will override the inherited access right from the Collection.
    rights
    string
    One of read,use, modify or own.
    Note that the API token used to generate the embed token must have similar or more access to the dataset!
    id
    string
    Dateset id to give access to
    dashboards
    array
    List of dashboards the token should have access to, with their individual access rights. If dashboard(s) are specified which are also accessible through a specified Collection, the explicit dashboard access rights specified in this dashboards property will override the inherited access right from the Collection.
    rights
    string
    One of read,use, modify or own.
    Note that the API token used to generate the embed token must have similar or more access to the dashboard!
    id
    string
    Dashboard id to give access to
    role
    string
    The role of the user for who you are making the authorization request defaults to viewer. More information on the different roles:
    • "viewer"
      embed users that should only be able to view and interact with one or more dashboards, variants, and duplicates.
    • "designer"
      embed users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates.
    • "owner"
      embed users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates, and next to that they should be able to favorite dashboard variants for other embed users within their suborganization.
    More info under Embedded Dashboard Editor.
    parameter_overrides
    object
    Parameter name and value. The value should be a number, string or array depending on the parameter type set when creating the parameter. {"id": "1234"} The parameter can be cleared using the special value {clear: true}

    For a list of all properties that you can use in the request, check Authorization in the Core API.

    The request returns a JSON object that contains an authorization id & token. This is the key/token combination that will be used in our next step (client-side) to embed the dashboard in a secure way.

    2. Embed the dashboard using embed token

    1 Install the web component via npm package manager by running the following command in your command line interface. It's recommended to use npm to ensure you can easily get the latest version of our component when available!
    npm i @luzmo/embed
    
     If you're not able to use npm, you can import the minified javascript file in any HTML file using the following code.
    <!--
    You can (programmatically) retrieve the latest version via this link:
    https://cdn.luzmo.com/js/luzmo-embed/latest-version.json
    It is recommended to reference a static version in your application (e.g. "<WEB_COMPONENT_VERSION>"), 
    and periodically verify and upgrade your application's implementation to
    benefit from any improvements in the latest version of the web component.
    -->
    <script
      defer
      src="https://cdn.luzmo.com/js/luzmo-embed/<WEB_COMPONENT_VERSION>/luzmo-embed.min.js"
      charset="utf-8"
    ></script>
    
    2 Import the component in a JavaScript module.
    import '@luzmo/embed';
    
     You can also import the component in an HTML page.
    <script type="module">
      import './node_modules/@luzmo/embed/index.js';
    </script>
    <!-- OR -->
    <script
      type="module"
      src="./node_modules/@luzmo/embed/index.js">
    </script>
    
    3 Add the Luzmo component to your HTML page.
    <!--
    Clients on our US multi-tenant application environment,
    or a dedicated instance on a specific VPC, should specify:
    - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
    - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
    -->
    <luzmo-dashboard
      appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
      apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
      authKey="< embed authorization key >"
      authToken="< embed authorization token >"
      dashboardId="< dashboard id you want to embed >"
    ></luzmo-dashboard>
    
    1 Install the Angular component via npm package manager by running the following command in your command line interface.
    npm i @luzmo/ngx-embed
    
    2 Import the NgxLuzmoDashboardModule in your NgModule
    import {
      NgxLuzmoDashboardModule
    } from '@luzmo/ngx-embed';
    
    @NgModule({
      ...
      imports: [
        ...,
        NgxLuzmoDashboardModule,
        ...
      ],
      ...
    })
    
    3 Add the Luzmo component in your Angular page
    /*
    Clients on our US multi-tenant application environment,
    or a dedicated instance on a specific VPC, should specify:
    - [appServer]="'https://app.us.luzmo.com/'" (or your VPC-specific address)
    - [apiHost]="'https://api.us.luzmo.com/'" (or your VPC-specific address)
    */
    <luzmo-dashboard
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< embed authorization key >'"
      [authToken]="'< embed authorization token >'"
      [dashboardId]="'< dashboard id you want to embed >'"
    ></luzmo-dashboard>
    
    1 Install the React component via npm package manager by running the following command in your command line interface.
    npm i @luzmo/react-embed
    
    2 Minimal required parameters to securely embed a dashboard in a React application
    import { LuzmoDashboardComponent } from '@luzmo/react-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        /*
        Clients on our US multi-tenant application environment,
        or a dedicated instance on a specific VPC, should specify:
        - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
        - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
        */
        return (
          <LuzmoDashboardComponent
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< embed authorization key >"
            authToken="< embed authorization token >"
            dashboardId="< dashboard id you want to embed >"
          ></LuzmoDashboardComponent>
        );
      }
    
    1 Install the React Native component via npm package manager by running the following command in your command line interface.
    npm i @luzmo/react-native-embed
    
    2 Minimal required parameters to securely embed a dashboard in a React Native application
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        /*
        Clients on our US multi-tenant application environment,
        or a dedicated instance on a specific VPC, should specify:
        - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
        - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
        */
        return (
          <LuzmoDashboardComponent
            ref={ref}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< embed authorization key >"
            authToken="< embed authorization token >"
            dashboardId="< dashboard id you want to embed >"
          ></LuzmoDashboardComponent>
        );
      }
    
    1 Install the Vue component via npm package manager by running the following command in your command line interface.
    npm i @luzmo/vue-embed
    
    2 Minimal required parameters to securely embed a dashboard in a Vue 3 application
    import { createApp } from 'vue';
    import App from './App.vue';
    import VueLuzmoDashboard from '@luzmo/vue-embed';
    ...
    
    const app = createApp(App);
    ...
    
    // Defines the component at app level
    app.use(VueLuzmoDashboard);
    ...
    
    app.mount('#app');
    
     You can also use our Vue component in your Vue 2 application
    import Vue from 'vue';
    import App from './App.vue';
    import VueLuzmoDashboard from '@luzmo/vue-embed/vue2';
    ...
    
    Vue.use(VueLuzmoDashboard);
    ...
    
    new Vue({
      render: (h) => h(App),
    }).$mount('#app');
    
    3 In your HTML template of your Vue application
    <template>
      ...
      <!--
      Clients on our US multi-tenant application environment,
      or a dedicated instance on a specific VPC, should specify:
      - :appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
      - :apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
       -->
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< embed authorization key >"
        authToken="< embed authorization token >"
        dashboardId="< dashboard id you want to embed >"
      ></luzmo-dashboard>
    </template>
    

    To embed a dashboard in your webpage, we use the Embed Libraries.

    First you should install the appropriate component library in your frontend. We have a Web component, React component, React Native component, Angular component and Vue.js component which are available via npm package manager.

    In this step we'll use the embed key and token from step 1 to securely embed a dashboard in your frontend by referencing it with its id or slug.

    You can optionally retrieve a list of accessible dashboards to dynamically provide them to your users in e.g. a sidebar in your application's frontend.

    Parameter Description
    appServer
    string
    Tenancy of Luzmo app to connect to. Defaults to 'https://app.luzmo.com/'.
    For US multi-tenant application, set appServer to 'https://app.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    apiHost
    string
    Tenancy of Luzmo API to connect to. Defaults to 'https://api.luzmo.com/'.
    For US multi-tenant application, set apiHost to 'https://api.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    authKey
    uuid
    The authorization key (i.e. "id") from the response of the authorization request in your backend.
    authToken
    string
    The authorization token from the response of the authorization request in your backend.
    dashboardId
    uuid
    This is the id of the dashboard that you want to embed.

    There are additional properties that can be specified to e.g. choose which screenmode or language will be loaded and/or to style the dashboard loader. This to ensure a perfect fit with the style of your page. Check the Embedding chapter for all documentation related to our frontend components.

    That's it, with these steps you securely embed a dashboard in your application/platform!

    Handling multi-tenant data

    Depending on your current data setup and use case, it might be necessary to dynamically:

    No worries if you're specific data setup is not covered by these options, we are sure we are able to support it via e.g. a plugin.
    Don't hesitate to reach out to support@luzmo.com if you'd like to have some assistance on this topic!

    Add a Parameter filter

    You can add Parameters to your authorization requests to dynamically filter the data in your embedded dashboards.

    First you need to create and define the Parameter, after which you can override the Parameter to a value of your choice when creating the authorization request.

    1. Define and set a Parameter

    This can be achieved on the dataset level or when building a dashboard in our dashboard editor. For multi-tenant row-level security, you should set up the parameterized filter on the dataset level to ensure the token cannot alter or remove this filter in e.g. the embedded dashboard editor!

    On the dataset level with embed filter group
       Link a dataset to embed filter group,  apply some parameter filters. The parameter specified can be overridden when requesting an embed token to apply dynamic row-level security! 
    client.associate("embedfiltergroup", "<your embed filter group id >", "Securables", "< your dataset id >",
      ImmutableMap.of(
        "filters", ImmutableList.of(
          ImmutableMap.of(
            "clause", "where",
            "origin", "global",
            "securable_id", "< dataset id >",
            "column_id", "< column id of a column in the dataset >",
            "expression", "? in ?",
            "value", ImmutableMap.of(
              parameter: "metadata.< parameter name >",
              type: "array[hierarchy]",
              value: ImmutableList.of(
                "< default parameter value >"
              )
            )
          )
        )
      )
    );
    
        Link a dataset to embed filter group,  apply some parameter filters. The parameter specified can be overridden when requesting an embed token to apply dynamic row-level security! 
    dynamic properties = new ExpandoObject();
    
    properties.filters = new List<dynamic> {
      new {  
        clause = "where";
        origin = "global";
        securable_id = "< dataset id >";
        column_id = "< column id of a column in the dataset >";
        expression = "? in ?";
        value = new {
          parameter: "metadata.< parameter name >",
          type: "array[hierarchy]",
          value: new List<String> {
            "< default parameter value >"
          }
        };
      }
    };
    
    client.associate("embedfiltergroup", "< your embedfiltergroup id >", "Securables", "< your dataset id >",   properties );
    
       Link a dataset to embed filter group,  apply some parameter filters. The parameter specified can be overridden when requesting an embed token to apply dynamic row-level security! 
    let promise = client.associate("embedfiltergroup", "< your embedfiltergroup id >", {
      role: "Securables",
      id: "< your dataset id >"
    },
    {
      filters: [
        {
          clause: "where",
          origin: "global",
          securable_id: "< dataset id >",
          column_id: "< column id of a column used in the dataset >",  
          expression: "? in ?",
          value: {
            parameter: "metadata.< parameter name >",
            type: "array[hierarchy]",
            value: ["< default parameter value >"]
          }
        }  
      ]
    });
    
       Link a dataset to embed filter group,  apply some parameter filters. The parameter specified can be overridden when requesting an embed token to apply dynamic row-level security! 
    <?php
    $client->associate("embedfiltergroup", "< your embedfiltergroup id >", "Securables", "< your dataset id >", ,
      array (
        "filters" => array(
          array(
            "clause"       => "where",
            "origin"       => "global",
            "securable_id" => "< dataset id >",
            "column_id"    => "< column id of a column used in the dataset >",
            "expression"   => "? in ?",
            "value"        => array(
              "parameter" => "metadata.< parameter name >",
              "type" => "array[hierarchy]",
              "value" => array("< default parameter value >")
            )
          )
        )
      ) );
    ?>
    
       Link a dataset to embed filter group,  apply some parameter filters. The parameter specified can be overridden when requesting an embed token to apply dynamic row-level security! 
    curl https://api.luzmo.com/0.1.0/embedfiltergroup  \
    -H "Content-Type: application/json"  \
    -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "< your embedfiltergroup id >",
      "resource": {
        "role": "Securables",
        "id": "< your dataset id >"
      },
      "properties": {
        "filters": [
            {
              "clause": "where",
              "origin": "global",
              "securable_id": "< dataset id >",
              "column_id": "< column id of a column used in the dataset >",  
              "expression": "? in ?",
              "value": {
                "parameter": "metadata.< parameter name >",
                "type": "array[hierarchy]",
                "value": ["< default parameter value >"]
              }
            }
          ]
      }
    }
    EOF
    
       Link a dataset to embed filter group,  apply some parameter filters. The parameter specified can be overridden when requesting an embed token to apply dynamic row-level security! 
    client.associate("embedfiltergroup", "< your embedfiltergroup id >", {
      "role": "Securables",
      "id": "< your dataset id >"
    },
    {
      "filters": [
        {
          "clause": "where",
          "origin": "global",
          "securable_id": "< dataset id >",
          "column_id": "< column id of a column used in the dataset >",  
          "expression": "? in ?",
          "value": {
            "parameter": "metadata.< parameter name >",
            "type": "array[hierarchy]",
            "value": ["< default parameter value >"]
          }
        }  
      ]
    });
    

    You can optionally specify static & parameter filters on each dataset. Parameter filters ensure that you can dynamically fill in a parameter value in the authorization request based on the user logged in in your application! See embedfiltergroup requests for details about the embedfiltergroup resource

    In the dashboard editor

    Instead of defining the parameter on the dataset embed filters association, you can also do this in the dashboard editor itself. This makes it easy to get a preview of how the dashboard would look like for your end user. Because the dashboard(s)/chart(s) are prefiltered they can also give a good indication of the embedded dashboard's loading performance!

    You can create a parameterized filter when setting up a filter on the dashboard or widget level, and clicking on the parameter icon instead of using a static value. This will automatically create and use this parameter in the filter, as well as allowing you to also reference the same parameter in any other widget/dashboard filter. Alternatively, you can also use the "Create parameter" button to create a new parameter with a suitable type, and use it in one or more filters!

    2. Override the parameter in the authorization request
       In the authorization request you should specify the parameter name together with the value to override the default value! 
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "properties":{
        "type": "embed",
        "username": "< A unique and immutable identifier for your end user >",
        "name": "< end-user name >",
        "email": "< end-user email >",
        "suborganization": "< a suborganization name >",
        "parameter_overrides": {
          "< parameter name >": ["< value to apply >"]
        },
        "access": {
          "dashboards":[
            {
              "id": "<a dashboard id>",
              "rights": "use"
            }
          ],
          "datasets":[
            {
              "id": "<a dataset id>",
              "rights": "use"
            }
          ],
          "collections": [
            {
              "id": "<a collection id>",
              "inheritRights": "use"
            }
          ]
        }
      }
    }
    EOF
    
       In the authorization request you should specify the parameter name together with the value to override the default value! 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: "< Your API key >",
        api_token: "< Your API token >",
        host: "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >"
    });
    
    let promise = client.create("authorization", {
      type: "embed",
      username: "< A unique and immutable identifier for your end user >",
      name: "< end-user name >",
      email: "< end-user email >",
      suborganization: "< a suborganization name >",
      parameter_overrides: {
        "< parameter name >": ["< value to apply >"]
      },
      access: {
        dashboards:[
          {
            id: "<a dashboard id>",
            rights: "use"
          }
        ],
        datasets:[
          {
            id: "<a dataset id>",
            rights: "use"
          }
        ],
        collections: [
          {
            id: "<a collection id>",
            inheritRights: "use"
          }
        ]
        }
    });
    
    promise.then(function(result){
      // return the result to the client
    })
    
    
       In the authorization request you should specify the parameter name together with the value to override the default value! 
    <?php
    $client = Luzmo::initialize("< your API key >", "< your API token >",
     "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    $authorization = $client->create("authorization", array(
      "type" => "embed",
      "username" => "< A unique and immutable identifier for your end user >",
      "name" => "< end-user name >",
      "email" => "< end-user email >",
      "suborganization" => "< a suborganization name >",
      "parameter_overrides" => array(
        "< parameter name >" => array(
          "< value to apply >"
        )
      ),
      "access" => array(
        "dashboards" => array(
          array(
            "id" => "<a dashboard id>",
            "rights" => "use"
          )
        ),
        "datasets" => array(
          array(
            "id" => "<a dataset id>",
            "rights" => "use"
          )
        ),
        "collections" => array(
          array(
            "id" => "<a collection id>",
            "inheritRights" => "use"
          )
        )
      )
    ));
    ?>
    
       In the authorization request you should specify the parameter name together with the value to override the default value! 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >", "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","embed")
      .put("username", "< A unique and immutable identifier for your end user >")
      .put("name", "< end-user name >")
      .put("email", "< end-user email >")
      .put("suborganization", "< a suborganization name >")
      .put("parameter_overrides", ImmutableMap.builder()
        .put("< parameter name >" = ImmutableList.of(
          "< value to apply >"
        ))
        .build()
      )
        .put("access", ImmutableMap.builder()
          .put("dashboards", ImmutableList.of(
              ImmutableMap.of(
                "id", "dashboard id",
                "rights", "use"
              )
            )
          )
          .put("datasets", ImmutableList.of(
              ImmutableMap.of(
                "id", "dataset id",
                "rights", "use"
              )
            )
          )
          .put("collections", ImmutableList.of(
              ImmutableMap.of(
                "id", "collection id",
                "inheritRights", "use"
              )
            )
          )
          .build()
      )
      .build()
    );
    
       In the authorization request you should specify the parameter name together with the value to override the default value! 
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    
    dynamic properties = new ExpandoObject();
    properties.type = "embed";
    properties.username = "< A unique and immutable identifier for your end user >";
    properties.name = "< end-user name >";
    properties.email = "< end-user email >";
    properties.suborganization = "< a suborganization name >";
    properties.parameter_overrides = new{
      parameter_name = new List<String>{
        "< value to apply >"
      }
    };
    properties.access =  new {
        dashboards =  new List<dynamic> {
           new { 
                id = "dashboard Id",
                rights = "use"
            }
        },
        datasets =  new List<dynamic> {
           new { 
                id = "dataset id",
                rights = "use"
            }
        }
        collections =  new List<dynamic> {
           new { 
                id = "collection id",
                inheritRights = "use"
            }
        }
    };
    
    dynamic authorization = client.create("authorization", properties);
    Console.WriteLine("Success!", authorization);
    
       In the authorization request you should specify the parameter name together with the value to override the default value! 
    from luzmo.luzmo import Luzmo
    
    key = "Your Luzmo key"
    token = "Your Luzmo token"
    
    client = Luzmo(key, token,
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    
    authorization = client.create("authorization", {
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your end user >",
        "name": "< end-user name >",
        "email": "< end-user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "viewer",
        "metadata": {
          "< parameter-name>": "< value to filter to >"
        }
    });
    
    

    Whether you've defined a default parameter filter in the dashboard editor or when associating the dataset with the integration, you want to override this parameter value in the SSO authorization request to dynamically filter the dashboard based on the end user logged in in your application. This is as easy as extending the code snippet used in step 1 by adding a parameter_overrides property to the request in which you specify the Parameter name and override its value.

    Property Description
    type
    string REQUIRED
    embed Use the value 'embed' for embedding a dashboard.
    expiry
    date (RFC 3339)
    RFC3339 timestamp when this authorization will cease working. Defaults to 24 hours from creation default, with a maximum of 1 year.
    This is the hard (maximum) expiry time of the token, after which it will *always* be invalid. We advise using short expiry time, eg. 24 hours from now.
    inactivity_interval
    integer
    Duration of inactivity (in seconds) after which the token is prematurely invalidated. Defaults to 0.
    You can use this to prematurely invalidate tokens when the user session in your application has ended (eg. all open dashboards are closed). A value of 0 means no premature invalidation due to inactivity (the token will only expire on the datetime specified in the expiry property of the Authorization request).

    We advise not to set the interval to a value smaller than 120 seconds, to avoid accidental invalidation for a dashboard that is still open, eg. when a heartbeat signal sent to the server is missed.
    username
    string REQUIRED
    Identifies the user uniquely and immutably. This should correspond to eg. the primary key for the user on your end. If it changes, the user will not have access to their previously created content anymore. So don't use eg. an e-mail address if those can change in your platform! This will also be used to uniquely identify a Monthly Active Viewer (MAV) for your Organization.
    name
    string REQUIRED
    The full name of the user (i.e. First name and Last name). This will be used in our UI.
    email
    string REQUIRED
    The email address of the user. This will be used in our UI.
    suborganization
    string
    Each embed token should be in a suborganization. The suborganization determines which other users they can see & interact with. it defaults to username to have total isolation, set to null if you want all users to see each other.
    access
    object REQUIRED
    Specifies which datasets, dashboards or collections the token will have access to. When providing direct access to a dashboard, make sure to also provide access to the underlying dataset(s) to avoid 'No access' errors!
    collections
    array
    List of Collections that contain one or more securables (dashboards and/or datasets), to which the token should have access to. The token will not have access to the Collection itself, but rather uses the Collection to access the underlying resources.
    If a securable is added or removed from a collection, you must generate a new token (i.e the token gets access to securables inside the collection at the time of creation).
    If you specify a dashboard and/or dataset in the dashboards / datasets property, which is also accessible to the token through a Collection which include this dashboard / dataset, the more specific right is applied (i.e the right specified in the dashboards / datasets property overrides the rights from the Collection).
    inheritRights
    string
    One of read,use, modify or own.
    Note that the API token used to generate the embed token must have similar or more access to the securables in the collection! If not, a warning message will be returned in the response to indicate that the embed token doesn't have access to one or more collection securables.
    id
    string
    Collection id you wish to give access to items inside
    datasets
    array
    List of datasets the token should have access to, with their individual access rights. If dataset(s) are specified which are also accessible through a specified Collection, the explicit dataset access rights specified in this datasets property will override the inherited access right from the Collection.
    rights
    string
    One of read,use, modify or own.
    Note that the API token used to generate the embed token must have similar or more access to the dataset!
    id
    string
    Dateset id to give access to
    dashboards
    array
    List of dashboards the token should have access to, with their individual access rights. If dashboard(s) are specified which are also accessible through a specified Collection, the explicit dashboard access rights specified in this dashboards property will override the inherited access right from the Collection.
    rights
    string
    One of read,use, modify or own.
    Note that the API token used to generate the embed token must have similar or more access to the dashboard!
    id
    string
    Dashboard id to give access to
    role
    string
    The role of the user for who you are making the authorization request defaults to viewer. More information on the different roles:
    • "viewer"
      embed users that should only be able to view and interact with one or more dashboards, variants, and duplicates.
    • "designer"
      embed users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates.
    • "owner"
      embed users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates, and next to that they should be able to favorite dashboard variants for other embed users within their suborganization.
    More info under Embedded Dashboard Editor.
    parameter_overrides
    object
    Parameter name and value. The value should be a number, string or array depending on the parameter type set when creating the parameter. {"id": "1234"} The parameter can be cleared using the special value {clear: true}

    Embedding with SSO tokens

    Set up an Integration in Luzmo

    1. Create an Integration

    2. Associate dashboards with Integration

    3. Associate datasets with Integration

    Embed into your application

    1. Generate a SSO authorization token (server-side)

    2. Embed the dashboard in your own application/platform (client-side)

    Set up an Integration

    The first step to embed dashboards in your application is setting up an Integration. This can be easily created and maintained from within our application as well as through our API!

    Create an Integration

       Creating an Integration via API (replace with your API key & token) 
    JSONObject integration = client.create("integration",
    
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "< Integration name in English ›",
          "fr" , "< Integration name in French >"
        )
      ));
    System.out.println("Success! %s%n", integration);
    
       Creating an Integration via API (replace with your API key & token) 
    dynamic properties = new ExpandoObject();
    properties.name = new {
          en = "< Integration name in English ›",
          fr = "< Integration name in French >"
        };
    
    dynamic integration = client.create("integration",    properties);
    Console.WriteLine("Success!", integration);
    
       Creating an Integration via API (replace with your API key & token) 
    client.create("integration",
      {
        name: {
            en: "< Integration name in English ›",
            fr: "< Integration name in French >"
        }
    }
    
    )
      .then(function(integration) {
        console.log("Success!", integration);
      });
    
       Creating an Integration via API (replace with your API key & token) 
    <?php
    $integration = $client->create("integration",
    
      array (
        "name" => array (
          "en" => "< Integration name in English ›",
          "fr" => "< Integration name in French >"
        )
      )
    
    );
    print("Success! { $integration }");
    ?>
    
       Creating an Integration via API (replace with your API key & token) 
    curl https://api.luzmo.com/0.1.0/integration  \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "name": {
        "en": "< Integration name in English ›",
        "fr": "< Integration name in French >"
      }
    }
    }
    EOF
    
    
       Creating an Integration via API (replace with your API key & token) 
    integration = client.create("integration",
      {
        "name": {
            "en": "< Integration name in English ›",
            "fr": "< Integration name in French >"
        }
      }
    )
    

    If you're an Organization owner, you can login to Luzmo and on top of the page you will find the Integrations tab. From there you can start the process of creating an Integration by clicking on the New Integration button.

    Associate dashboards

       Link an Integration to a dashboard in order to make that dashboard readable by SSO tokens with access to the integration 
    client.associate("integration", "< your Integration id >", "Securables", "< your dashboard id >",
      ImmutableMap.of(
        "flagRead" , true,
        "slug", "< lowercase alphanumeric slug name >"
      ) );
    
       Link an Integration to a dashboard in order to make that dashboard readable by SSO tokens with access to the integration 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.slug = "< lowercase alphanumeric slug name >";
    
    client.associate("integration", "< your Integration id >", "Securables", "< your dashboard id >",     properties );
    
       Link an Integration to a dashboard in order to make that dashboard readable by SSO tokens with access to the integration 
    let promise = client.associate("integration", "< your Integration id >", {
        role: "Securables",
        id: "< your dashboard id >"
    },
    {
        flagRead: true,
        slug: "< lowercase alphanumeric slug name >"
    });
    
       Link an Integration to a dashboard in order to make that dashboard readable by SSO tokens with access to the integration 
    <?php
    $client->associate("integration", "< your Integration id >", "Securables", "< your dashboard id >", ,
      array (
        "flagRead" => true,
        "slug => "< lowercase alphanumeric slug name >"
      ) );
    ?>
    
       Link an Integration to a dashboard in order to make that dashboard readable by SSO tokens with access to the integration 
    curl https://api.luzmo.com/0.1.0/integration  \
    -H "Content-Type: application/json"  \
    -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "< your Integration id >",
      "resource": {
        "role": "Securables",
        "id": "< your dashboard id >"
      },
      "properties": {
        "flagRead": true,
        "slug": "< lowercase alphanumeric slug name >"
      }
    }
    EOF
    
       Link an Integration to a dashboard in order to make that dashboard readable by SSO tokens with access to the integration 
    client.associate("integration", "< your Integration id >", {
        "role": "Securables",
        "id": "< your dashboard id >"
    },
    {
        "flagRead": true,
        "slug": "< lowercase alphanumeric slug name >"
    });
    

    After starting the creation of the Integration, you can select dashboards that should be associated with the Integration together with their access rights. In order to start associating dashboards with an Integration, you already need to be an owner of the dashboard and the Integration. That means that you either created the dashboard or received access from someone that gave you owner access. That way it is possible to set multiple owners for a dashboard.

    The association has flag properties to define what kind of access the Integration will receive. If no flag properties are specified the Integration will receive "view" access by default. The available flags are:

    Warning! If you give 'can use' or 'can edit' rights on a dashboard, you must ensure that all multi-tenant (parameter) filters are defined on the dataset level (i.e. when associating the dataset(s) with the Integration/Suborganization/Group/User) and not on the dashboard level. Designer users are able to modify the dashboard content (either in a variant, in a duplicate or in the dashboard itself) and thus remove these (parameter) filters!

    Next to the flag properties, you can also specify a unique slug that can be used to target the specific dashboard in your frontend (see Step 2: Embed the dashboard). This is particularly useful if you'd like to replace an embedded dashboard in your application without having to change anything in your application's code!
    The gif below shows how you can replace a dashboard for a certain slug in our UI.

    Associate datasets

       Link an Integration to a dataset in order to make that complete dataset readable by SSO tokens granted access to the integration 
    client.associate("integration", "< your Integration id >", "Securables", "< your dataset id >",
      ImmutableMap.of(
        "flagRead" , true
      ));
    
       Link an Integration to a dataset in order to make that complete dataset readable by SSO tokens granted access to the integration 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    
    client.associate("integration", "< your Integration id >", "Securables", "< your dataset id >",     properties );
    
       Link an Integration to a dataset in order to make that complete dataset readable by SSO tokens granted access to the integration 
    let promise = client.associate("integration", "< your Integration id >", {
        role: "Securables",
        id: "< your dataset id >"
    },
    {
        flagRead: true
    });
    
       Link an Integration to a dataset in order to make that complete dataset readable by SSO tokens granted access to the integration 
    <?php
    $client->associate("integration", "< your Integration id >", "Securables", "< your dataset id >", ,
      array (
        "flagRead" => true
      ));
    ?>
    
       Link an Integration to a dataset in order to make that complete dataset readable by SSO tokens granted access to the integration 
    curl https://api.luzmo.com/0.1.0/integration  \
    -H "Content-Type: application/json"  \
    -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your Integration id >",
      "resource": {
        "role": "Securables",
        "id": "< your dataset id >"
      },
      "properties": {
        "flagRead": true
      }
    }
    EOF
    
       Link an Integration to a dataset in order to make that complete dataset readable by SSO tokens granted access to the integration 
    client.associate("integration", "< your Integration id >", {
        "role": "Securables",
        "id": "< your dataset id >"
    },
    {
        flagRead: true
    });
    
       Link an Integration to a dataset, give it read rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    client.associate("integration", "<your Integration id >", "Securables", "< your dataset id >",
      ImmutableMap.of(
        "flagRead", true,
        "filters", ImmutableList.of(
          ImmutableMap.of(
            "clause", "where",
            "origin", "global",
            "securable_id", "< dataset id >",
            "column_id", "< column id of a column in the dataset >",
            "expression", "? in ?",
            "value", ImmutableMap.of(
              parameter: "metadata.< parameter name >",
              type: "array[hierarchy]",
              value: ImmutableList.of(
                "< default parameter value >"
              )
            )
          )
        )
      )
    );
    
       Link an Integration to a dataset, give it read rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    
    properties.filters = new List<dynamic> {
      new {  
        clause = "where";
        origin = "global";
        securable_id = "< dataset id >";
        column_id = "< column id of a column in the dataset >";
        expression = "? in ?";
        value = new {
          parameter: "metadata.< parameter name >",
          type: "array[hierarchy]",
          value: new List<String> {
            "< default parameter value >"
          }
        };
      }
    };
    
    client.associate("integration", "< your Integration id >", "Securables", "< your dataset id >",   properties );
    
       Link an Integration to a dataset, give it read rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    let promise = client.associate("integration", "< your Integration id >", {
      role: "Securables",
      id: "< your dataset id >"
    },
    {
      flagRead: true,
      filters: [
        {
          clause: "where",
          origin: "global",
          securable_id: "< dataset id >",
          column_id: "< column id of a column used in the dataset >",  
          expression: "? in ?",
          value: {
            parameter: "metadata.< parameter name >",
            type: "array[hierarchy]",
            value: ["< default parameter value >"]
          }
        }  
      ]
    });
    
       Link an Integration to a dataset, give it read rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    <?php
    $client->associate("integration", "< your Integration id >", "Securables", "< your dataset id >", ,
      array (
        "flagRead" => true,
        "filters" => array(
          array(
            "clause"       => "where",
            "origin"       => "global",
            "securable_id" => "< dataset id >",
            "column_id"    => "< column id of a column used in the dataset >",
            "expression"   => "? in ?",
            "value"        => array(
              "parameter" => "metadata.< parameter name >",
              "type" => "array[hierarchy]",
              "value" => array("< default parameter value >")
            )
          )
        )
      ) );
    ?>
    
       Link an Integration to a dataset, give it read rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    curl https://api.luzmo.com/0.1.0/integration  \
    -H "Content-Type: application/json"  \
    -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "< your Integration id >",
      "resource": {
        "role": "Securables",
        "id": "< your dataset id >"
      },
      "properties": {
        "flagRead": true,
        "filters": [
            {
              "clause": "where",
              "origin": "global",
              "securable_id": "< dataset id >",
              "column_id": "< column id of a column used in the dataset >",  
              "expression": "? in ?",
              "value": {
                "parameter": "metadata.< parameter name >",
                "type": "array[hierarchy]",
                "value": ["< default parameter value >"]
              }
            }
          ]
      }
    }
    EOF
    
       Link an Integration to a dataset, give it read rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    client.associate("integration", "< your Integration id >", {
      "role": "Securables",
      "id": "< your dataset id >"
    },
    {
      "flagRead": true,
      "filters": [
        {
          "clause": "where",
          "origin": "global",
          "securable_id": "< dataset id >",
          "column_id": "< column id of a column used in the dataset >",  
          "expression": "? in ?",
          "value": {
            "parameter": "metadata.< parameter name >",
            "type": "array[hierarchy]",
            "value": ["< default parameter value >"]
          }
        }  
      ]
    });
    
       Link an Integration to a dataset, give it read rights and apply a static filter for e.g. row-level security. 
    client.associate("integration", "< your Integration id >", "Securables", "< your dataset id >",
      ImmutableMap.of(
        "flagRead", true,
        "filters", ImmutableList.of(
          ImmutableMap.of(
            "clause", "where",
            "origin", "global",
            "securable_id", "< dataset id >",
            "column_id", "< column id of a column in the dataset >",
            "expression", "? = ?",
            "value", "< value to be applied to the expression >"
          )
        )
      )
    );
    
       Link an Integration to a dataset, give it read rights and apply a static filter for e.g. row-level security. 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    
    properties.filters = new List<dynamic> {
      new {  
        clause = "where";
        origin = "global";
        securable_id = "< dataset id >";
        column_id = "< column id of a column in the dataset >";
        expression = "? = ?";
        value = "< value to be applied to the expression >";
      }
    };
    
    client.associate("integration", "< your Integration id >", "Securables", "< your dataset id >",   properties );
    
       Link an Integration to a dataset, give it read rights and apply a static filter for e.g. row-level security. 
    let promise = client.associate("integration", "< your Integration id >", {
      role: "Securables",
      id: "< your dataset id >"
    },
    {
      flagRead: true,
      filters: [
        {
          clause: "where",
          origin: "global",
          securable_id: "< dataset id >",
          column_id: "< column id of a column used in the dataset >",  
          expression: "? = ?",
          value: "< value to be applied to the expression >"
        }  
      ]
    });
    
       Link an Integration to a dataset, give it read rights and apply a static filter for e.g. row-level security. 
    <?php
    $client->associate("integration", "< your Integration id >", "Securables", "< your dataset id >", ,
      array (
        "flagRead" => true,
        "filters" => array(
          "clause"       => "where",
          "origin"       => "global",
          "securable_id" => "< dataset id >",
          "column_id"    => "< column id of a column used in the dataset >",
          "expression"   => "? = ?",
          "value"        => "< value to be applied to the expression >"
        )
      ) );
    ?>
    
       Link an Integration to a dataset, give it read rights and apply a static filter for e.g. row-level security. 
    curl https://api.luzmo.com/0.1.0/integration  \
    -H "Content-Type: application/json"  \
    -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your Integration id >",
      "resource": {
        "role": "Securables",
        "id": "< your dataset id >"
      },
      "properties": {
        "flagRead": true,
        "filters": [
            {
              "clause": "where",
              "origin": "global",
              "securable_id": "< dataset id >",
              "column_id": "< column id of a column used in the dataset >",  
              "expression": "? = ?",
              "value": "< value to be applied to the expression >"
            }
          ]
      }
    }
    EOF
    
       Link an Integration to a dataset, give it read rights and apply a static filter for e.g. row-level security. 
    let promise = client.associate("integration", "< your Integration id >", {
      "role": "Securables",
        "id": "< your dataset id >"
      },
      {
        "flagRead": true,
        "filters": [
            {
              "clause": "where",
              "origin": "global",
              "securable_id": "< dataset id >",
              "column_id": "< column id of a column used in the dataset >",  
              "expression": "? = ?",
              "value": "< value to be applied to the expression >"
            }
          ]
      }
    });
    

    When associating a dataset with an Integration you can specify some flag properties to define what kind of access the Integration will receive. If no flag properties are specified the Integration will receive viewing access by default. The available flags are:

    Important! For security reasons it’s of uttermost importance that multi-tenant (parameter) filters are specified on the dataset level, this ensures that they are always applied when the user queries the dataset directly or via a (new) dashboard. Parameterizable filters can be used to dynamically apply these filters by overriding the parameter value(s) when requesting a SSO token for your user. Instead of using parameterizable filters, you could also specify static filters when associating a dataset with an Integration or when requesting SSO authorization tokens.

    As shown in the gif below, you can additionally specify filters when defining the dataset-Integration association. In case you want to dynamically filter a dataset based on the user logged in in your application, parameter filters are the easiest way of setting this up!

    Embed into your application

    1. Generate a SSO token

       Replace with your API key & token and integration_id and fill in the user's details 
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "properties":{
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "viewer"
      }
    }
    EOF
    
       Replace with your API key & token and integration_id and fill in the user's details 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: "< Your API key >",
        api_token: "< Your API token >",
        host: "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >"
    });
    
    let promise = client.create("authorization", {
      type: "sso",
      expiry: "24 hours",
      inactivity_interval: "10 minutes",
      username: "< A unique and immutable identifier for your user >",
      name: "< user name >",
      email: "< user email >",
      suborganization: "< a suborganization name >",
      integration_id: "< integration id >",
      role: "viewer"
    });
    
    promise.then(function(result){
      // return the result to the client
    })
    
    
       Replace with your API key & token and integration_id and fill in the user's details 
    <?php
    $client = Luzmo::initialize("< your API key >", "< your API token >",
     "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    
    $authorization = $client->create("authorization", array(
      "type" => "sso",
      "expiry" => "24 hours",
      "inactivity_interval" => "10 minutes",
      "username" => "< A unique and immutable identifier for your user >",
      "name" => "< user name >",
      "email" => "< user email >",
      "suborganization" => "< a suborganization name >",
      "integration_id" => "< integration id >",
      "role" => "viewer"
    ));
    ?>
    
       Replace with your API key & token and integration_id and fill in the user's details 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >",
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","sso")
      .put("expiry", "24 hours")
      .put("inactivity_interval", "10 minutes")
      .put("username", "< A unique and immutable identifier for your user >")
      .put("name", "< user name >")
      .put("email", "< user email >")
      .put("suborganization", "< a suborganization name >")
      .put("integration_id", "< integration id >")
      .put("role", "viewer")
      .build()
    );
    
       Replace with your API key & token and integration_id and fill in the user's details 
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "sso";
    properties.expiry = "24 hours";
    properties.inactivity_interval = "10 minutes";
    properties.username = "< A unique and immutable identifier for your user >";
    properties.name = "< user name >";
    properties.email = "< user email >";
    properties.suborganization = "< a suborganization name >";
    properties.integration_id = "< integration id >";
    properties.role = "viewer";
    
    dynamic authorization = client.create("authorization", properties);
    Console.WriteLine("Success!", authorization);
    
       Replace with your API key & token and integration_id and fill in the user's details 
    from luzmo.luzmo import Luzmo
    
    key = "Your Luzmo key"
    token = "Your Luzmo token"
    
    client = Luzmo(key, token,
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    
    authorization = client.create("authorization", {
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "viewer"
    });
    
    
       This returns a JSON object with an id/token combination that we will use to embed: 
    {
      "type": "sso",
      "id": "< the SSO authorization key >",
      "token": "< the SSO authorization token >",
      "user_id": "< a uuid used on our end to identify the SSO user >"
      // ...
    }
    

    In this step, your server-side code makes an API request to retrieve an authorization token of type SSO. The result of this request is a key/token combination that will be used to in step 2 to securely embed the dashboard in your application/platform.

    The API request is a 'create' request for an authorization. In this API call we use the Integration id that we created before (see Set up an Integration).

    Property Description
    type
    string REQUIRED
    sso Use the value 'sso' for embedding a dashboard.
    expiry
    date (RFC 3339) or string REQUIRED
    Date/time when this authorization will cease working. To promote better security practices this property is required and enforced with a maximum expiry date of 1 year. It is advised to only use short-living tokens (max. 24 hours) for maximum security.
    inactivity_interval
    integer or string
    Duration of inactivity after which the token is prematurely invalidated. You can use this to invalidate tokens quickly when the session is ended (eg. all open dashboards are closed). If specified, a minimum value of 2 minutes is enforced to avoid undesired invalidation of a token due to e.g. missing a heartbeat signal sent by our server.
    Defaults to 0 (i.e. no inactivity_interval).
    username
    string REQUIRED
    Identifies the user uniquely and immutably. This should correspond to eg. the primary key for the user on your end. If it changes, the user will not have access to their previously created content anymore. So don't use eg. an e-mail address if those can change in your platform! This will also be used to uniquely identify a Monthly Active Viewer (MAV) for your Organization.
    name
    string REQUIRED
    The full name of the user (i.e. First name and Last name). This will be used in our UI.
    email
    string REQUIRED
    The email address of the user. This will be used in our UI.
    suborganization
    string REQUIRED
    Each SSO token should be in a suborganization. The suborganization determines which other users they can see & interact with. It is required to avoid accidentally forgetting to set it which would cause all users to see each other! If you want totally isolated users, set it to the unique username.
    integration_id
    uuid REQUIRED
    The UUID of the integration that the SSO token should have access to.
    role
    string REQUIRED
    The role of the user for who you are making the authorization request. More information on the different roles:
    • "viewer"
      SSO users that should only be able to view and interact with one or more dashboards, variants, and duplicates.
    • "designer"
      SSO users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates.
    • "owner"
      SSO users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates, and next to that they should be able to favorite dashboard variants for other SSO users within their suborganization.
    More info under Embedded Dashboard Editor.

    For a list of all properties that you can use in the request, check Authorization in the Core API.

    The request returns a JSON object that contains an authorization id & token. This is the key/token combination that will be used in our next step (client-side) to embed the dashboard in a secure way.

    2. Embed the dashboard

    1 Install the web component via npm package manager by running the following command in your command line interface. It's recommended to use npm to ensure you can easily get the latest version of our component when available!
    npm i @luzmo/embed
    
     If you're not able to use npm, you can import the minified javascript file in any HTML file using the following code.
    <!--
    You can (programmatically) retrieve the latest version via this link:
    https://cdn.luzmo.com/js/luzmo-embed/latest-version.json
    It is recommended to reference a static version in your application (e.g. "<WEB_COMPONENT_VERSION>"), 
    and periodically verify and upgrade your application's implementation to
    benefit from any improvements in the latest version of the web component.
    -->
    <script
      defer
      src="https://cdn.luzmo.com/js/luzmo-embed/<WEB_COMPONENT_VERSION>/luzmo-embed.min.js"
      charset="utf-8"
    ></script>
    
    2 Import the component in a JavaScript module.
    import '@luzmo/embed';
    
     You can also import the component in an HTML page.
    <script type="module">
      import './node_modules/@luzmo/embed/index.js';
    </script>
    <!-- OR -->
    <script
      type="module"
      src="./node_modules/@luzmo/embed/index.js">
    </script>
    
    3 Add the Luzmo component to your HTML page.
    <!--
    Clients on our US multi-tenant application environment,
    or a dedicated instance on a specific VPC, should specify:
    - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
    - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
    -->
    <luzmo-dashboard
      appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
      apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
      authKey="< SSO authorization key >"
      authToken="< SSO authorization token >"
      dashboardId="< dashboard id you want to embed >"
      dashboardSlug="< instead of dashboardId: a dashboard slug as specified in the Integration. >"
    ></luzmo-dashboard>
    
    1 Install the Angular component via npm package manager by running the following command in your command line interface.
    npm i @luzmo/ngx-embed
    
    2 Import the NgxLuzmoDashboardModule in your NgModule
    import {
      NgxLuzmoDashboardModule
    } from '@luzmo/ngx-embed';
    
    @NgModule({
      ...
      imports: [
        ...,
        NgxLuzmoDashboardModule,
        ...
      ],
      ...
    })
    
    3 Add the Luzmo component in your Angular page
    /*
    Clients on our US multi-tenant application environment,
    or a dedicated instance on a specific VPC, should specify:
    - [appServer]="'https://app.us.luzmo.com/'" (or your VPC-specific address)
    - [apiHost]="'https://api.us.luzmo.com/'" (or your VPC-specific address)
    */
    <luzmo-dashboard
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< SSO authorization key >'"
      [authToken]="'< SSO authorization token >'"
      [dashboardId]="'< dashboard id you want to embed >'"
      [dashboardSlug]="'< instead of dashboardId: a dashboard slug as specified in the Integration. >'"
    ></luzmo-dashboard>
    
    1 Install the React component via npm package manager by running the following command in your command line interface.
    npm i @luzmo/react-embed
    
    2 Minimal required parameters to securely embed a dashboard in a React application
    import { LuzmoDashboardComponent } from '@luzmo/react-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        /*
        Clients on our US multi-tenant application environment,
        or a dedicated instance on a specific VPC, should specify:
        - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
        - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
        */
        return (
          <LuzmoDashboardComponent
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< SSO authorization key >"
            authToken="< SSO authorization token >"
            dashboardId="< dashboard id you want to embed >"
            dashboardSlug="< instead of dashboardId: a dashboard slug as specified in the Integration. >"
          ></LuzmoDashboardComponent>
        );
      }
    
    1 Install the React Native component via npm package manager by running the following command in your command line interface.
    npm i @luzmo/react-native-embed
    
    2 Minimal required parameters to securely embed a dashboard in a React Native application
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        /*
        Clients on our US multi-tenant application environment,
        or a dedicated instance on a specific VPC, should specify:
        - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
        - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
        */
        return (
          <LuzmoDashboardComponent
            ref={ref}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< SSO authorization key >"
            authToken="< SSO authorization token >"
            dashboardId="< dashboard id you want to embed >"
            dashboardSlug="< instead of dashboardId: a dashboard slug as specified in the Integration. >"
          ></LuzmoDashboardComponent>
        );
      }
    
    1 Install the Vue component via npm package manager by running the following command in your command line interface.
    npm i @luzmo/vue-embed
    
    2 Minimal required parameters to securely embed a dashboard in a Vue 3 application
    import { createApp } from 'vue';
    import App from './App.vue';
    import VueLuzmoDashboard from '@luzmo/vue-embed';
    ...
    
    const app = createApp(App);
    ...
    
    // Defines the component at app level
    app.use(VueLuzmoDashboard);
    ...
    
    app.mount('#app');
    
     You can also use our Vue component in your Vue 2 application
    import Vue from 'vue';
    import App from './App.vue';
    import VueLuzmoDashboard from '@luzmo/vue-embed/vue2';
    ...
    
    Vue.use(VueLuzmoDashboard);
    ...
    
    new Vue({
      render: (h) => h(App),
    }).$mount('#app');
    
    3 In your HTML template of your Vue application
    <template>
      ...
      <!--
      Clients on our US multi-tenant application environment,
      or a dedicated instance on a specific VPC, should specify:
      - :appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
      - :apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
       -->
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< SSO authorization key >"
        authToken="< SSO authorization token >"
        dashboardId="< dashboard id you want to embed >"
        dashboardSlug="< instead of dashboardId: a dashboard slug as specified in the Integration. >"
      ></luzmo-dashboard>
    </template>
    

    To embed a dashboard in your webpage, we use the Embed Libraries.

    First you should install the appropriate component library in your frontend. We have a Web component, React component, React Native component, Angular component and Vue.js component which are available via npm package manager.

    In this step we'll use the SSO key and token from step 1 to securely embed a dashboard in your frontend by referencing it with its id or slug.

    You can optionally retrieve a list of accessible dashboards (associated with the integration that the SSO token has access to) to dynamically provide them to your users in e.g. a sidebar in your application's frontend.

    Parameter Description
    appServer
    string
    Tenancy of Luzmo app to connect to. Defaults to 'https://app.luzmo.com/'.
    For US multi-tenant application, set appServer to 'https://app.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    apiHost
    string
    Tenancy of Luzmo API to connect to. Defaults to 'https://api.luzmo.com/'.
    For US multi-tenant application, set apiHost to 'https://api.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    authKey
    uuid
    The authorization key (i.e. "id") from the response of the authorization request in your backend.
    authToken
    string
    The authorization token from the response of the authorization request in your backend.
    dashboardId
    uuid
    This is the id of the dashboard that you want to embed.
    Specify either the dashboardId or dashboardSlug property.
    dashboardSlug
    string
    Instead of specifying a dashboardId, you can alternatively specify a dashboard slug. The slug is defined when associating a dashboard with an Integration.
    Specify either the dashboardId or dashboardSlug property.

    There are additional properties that can be specified to e.g. choose which screenmode or language will be loaded and/or to style the dashboard loader. This to ensure a perfect fit with the style of your page. Check the Embedding chapter for all documentation related to our frontend components.

    That's it, with these steps you securely embed a dashboard in your application/platform!

    Handling multi-tenant data

    Depending on your current data setup and use case, it might be necessary to dynamically:

    No worries if you're specific data setup is not covered by these options, we are sure we are able to support it via e.g. a plugin.
    Don't hesitate to reach out to support@luzmo.com if you'd like to have some assistance on this topic!

    Add a Parameter filter

    You can add Parameters to your authorization requests to dynamically filter the data in your embedded dashboards.

    First you need to create and define the Parameter, after which you can override the Parameter to a value of your choice when creating the authorization request.

    1. Define and set a Parameter

    This can be achieved when associating a dataset with an integration or when building a dashboard in our dashboard editor.

    When associating a dataset with an integration
       Link an integration to a dataset, give it read rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    client.associate("integration", "<your integration id >", "Securables", "< your dataset id >",
      ImmutableMap.of(
        "flagRead", true,
        "filters", ImmutableList.of(
          ImmutableMap.of(
            "clause", "where",
            "origin", "global",
            "securable_id", "< dataset id >",
            "column_id", "< column id of a column in the dataset >",
            "expression", "? in ?",
            "value", ImmutableMap.of(
              parameter: "metadata.< parameter name >",
              type: "array[hierarchy]",
              value: ImmutableList.of(
                "< default parameter value >"
              )
            )
          )
        )
      )
    );
    
       Link an integration to a dataset, give it read rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    
    properties.filters = new List<dynamic> {
      new {  
        clause = "where";
        origin = "global";
        securable_id = "< dataset id >";
        column_id = "< column id of a column in the dataset >";
        expression = "? in ?";
        value = new {
          parameter: "metadata.< parameter name >",
          type: "array[hierarchy]",
          value: new List<String> {
            "< default parameter value >"
          }
        };
      }
    };
    
    client.associate("integration", "< your integration id >", "Securables", "< your dataset id >",   properties );
    
       Link an integration to a dataset, give it read rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    let promise = client.associate("integration", "< your integration id >", {
      role: "Securables",
      id: "< your dataset id >"
    },
    {
      flagRead: true,
      filters: [
        {
          clause: "where",
          origin: "global",
          securable_id: "< dataset id >",
          column_id: "< column id of a column used in the dataset >",  
          expression: "? in ?",
          value: {
            parameter: "metadata.< parameter name >",
            type: "array[hierarchy]",
            value: ["< default parameter value >"]
          }
        }  
      ]
    });
    
       Link an integration to a dataset, give it read rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    <?php
    $client->associate("integration", "< your integration id >", "Securables", "< your dataset id >", ,
      array (
        "flagRead" => true,
        "filters" => array(
          array(
            "clause"       => "where",
            "origin"       => "global",
            "securable_id" => "< dataset id >",
            "column_id"    => "< column id of a column used in the dataset >",
            "expression"   => "? in ?",
            "value"        => array(
              "parameter" => "metadata.< parameter name >",
              "type" => "array[hierarchy]",
              "value" => array("< default parameter value >")
            )
          )
        )
      ) );
    ?>
    
       Link an integration to a dataset, give it read rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    curl https://api.luzmo.com/0.1.0/integration  \
    -H "Content-Type: application/json"  \
    -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "< your integration id >",
      "resource": {
        "role": "Securables",
        "id": "< your dataset id >"
      },
      "properties": {
        "flagRead": true,
        "filters": [
            {
              "clause": "where",
              "origin": "global",
              "securable_id": "< dataset id >",
              "column_id": "< column id of a column used in the dataset >",  
              "expression": "? in ?",
              "value": {
                "parameter": "metadata.< parameter name >",
                "type": "array[hierarchy]",
                "value": ["< default parameter value >"]
              }
            }
          ]
      }
    }
    EOF
    
       Link an integration to a dataset, give it read rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    client.associate("integration", "< your integration id >", {
      "role": "Securables",
      "id": "< your dataset id >"
    },
    {
      "flagRead": true,
      "filters": [
        {
          "clause": "where",
          "origin": "global",
          "securable_id": "< dataset id >",
          "column_id": "< column id of a column used in the dataset >",  
          "expression": "? in ?",
          "value": {
            "parameter": "metadata.< parameter name >",
            "type": "array[hierarchy]",
            "value": ["< default parameter value >"]
          }
        }  
      ]
    });
    

    After selecting the datasets that should be associated with the integration, you can optionally specify static & parameter filters on each dataset. Parameter filters ensure that you can dynamically fill in a parameter value in the authorization request based on the user logged in in your application!

    In the dashboard editor

    Instead of defining the parameter on the dashboard-integration association, you can also do this in the dashboard editor itself. This makes it easy to get a preview of how the dashboard would look like for your end user. Because the dashboard(s)/chart(s) are prefiltered they can also give a good indication of the embedded dashboard's loading performance!

    You can create a parameterized filter when setting up a filter on the dashboard or widget level, and clicking on the parameter icon instead of using a static value. This will automatically create and use this parameter in the filter, as well as allowing you to also reference the same parameter in any other widget/dashboard filter. Alternatively, you can also use the "Create parameter" button to create a new parameter with a suitable type, and use it in one or more filters!

    2. Override the parameter in the authorization request
       In the authorization request you should specify the parameter name together with the value to override the default value! 
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "properties":{
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your end user >",
        "name": "< end-user name >",
        "email": "< end-user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "viewer",
        "metadata": {
          "< parameter name >": ["< value to apply >"]
        }
      }
    }
    EOF
    
       In the authorization request you should specify the parameter name together with the value to override the default value! 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: "< Your API key >",
        api_token: "< Your API token >",
        host: "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >"
    });
    
    let promise = client.create("authorization", {
      type: "sso",
      expiry: "24 hours",
      inactivity_interval: "10 minutes",
      username: "< A unique and immutable identifier for your end user >",
      name: "< end-user name >",
      email: "< end-user email >",
      suborganization: "< a suborganization name >",
      integration_id: "< integration id >",
      role: "viewer",
      metadata: {
        "< parameter name >": ["< value to apply >"]
      }
    });
    
    promise.then(function(result){
      // return the result to the client
    })
    
    
       In the authorization request you should specify the parameter name together with the value to override the default value! 
    <?php
    $client = Luzmo::initialize("< your API key >", "< your API token >",
     "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    $authorization = $client->create("authorization", array(
      "type" => "sso",
      "expiry" => "24 hours",
      "inactivity_interval" => "10 minutes",
      "username" => "< A unique and immutable identifier for your end user >",
      "name" => "< end-user name >",
      "email" => "< end-user email >",
      "suborganization" => "< a suborganization name >",
      "integration_id" => "< integration id >",
      "role" => "viewer",
      "metadata" => array(
        "< parameter name >" => array(
          "< value to apply >"
        )
      )
    ));
    ?>
    
       In the authorization request you should specify the parameter name together with the value to override the default value! 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >", "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","sso")
      .put("expiry", "24 hours")
      .put("inactivity_interval", "10 minutes")
      .put("username", "< A unique and immutable identifier for your end user >")
      .put("name", "< end-user name >")
      .put("email", "< end-user email >")
      .put("suborganization", "< a suborganization name >")
      .put("integration_id", "< integration id >")
      .put("role", "viewer")
      .put("metadata", ImmutableMap.builder()
        .put("< parameter name >" = ImmutableList.of(
          "< value to apply >"
        ))
        .build()
      )
      .build()
    );
    
       In the authorization request you should specify the parameter name together with the value to override the default value! 
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    
    dynamic properties = new ExpandoObject();
    properties.type = "sso";
    properties.expiry = "24 hours";
    properties.inactivity_interval = "10 minutes";
    properties.username = "< A unique and immutable identifier for your end user >";
    properties.name = "< end-user name >";
    properties.email = "< end-user email >";
    properties.suborganization = "< a suborganization name >";
    properties.integration_id = "< integration id >";
    properties.role = "viewer";
    properties.metadata = new{
      parameter_name = new List<String>{
        "< value to apply >"
      }
    };
    
    dynamic authorization = client.create("authorization", properties);
    Console.WriteLine("Success!", authorization);
    
       In the authorization request you should specify the parameter name together with the value to override the default value! 
    from luzmo.luzmo import Luzmo
    
    key = "Your Luzmo key"
    token = "Your Luzmo token"
    
    client = Luzmo(key, token,
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    
    authorization = client.create("authorization", {
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your end user >",
        "name": "< end-user name >",
        "email": "< end-user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "viewer",
        "metadata": {
          "< parameter-name>": "< value to filter to >"
        }
    });
    
    

    Whether you've defined a default parameter filter in the dashboard editor or when associating the dataset with the integration, you want to override this parameter value in the SSO authorization request to dynamically filter the dashboard based on the end user logged in in your application. This is as easy as extending the code snippet used in step 1 by adding a metadata property to the request in which you specify the Parameter name and override its value.

    Property Description
    type
    string REQUIRED
    sso Use the value 'sso' for integrating a dashboard.
    expiry
    date (RFC 3339) or string REQUIRED
    Date/time when this authorization will cease working. To promote better security practices this property is required and enforced with a maximum expiry date of 1 year. It is advised to only use short-living tokens (max. 24 hours) for maximum security.
    inactivity_interval
    integer or string
    Duration of inactivity after which the token is prematurely invalidated. You can use this to invalidate tokens quickly when the session is ended (eg. all open dashboards are closed). If specified, a minimum value of 2 minutes is enforced to avoid undesired invalidation of a token due to e.g. missing a heartbeat signal sent by our server. Defaults to 0 (i.e. no inactivity_interval).
    username
    string REQUIRED
    Identifies the end-user uniquely and immutably. This should correspond to eg. the primary key for the end-user on your end. If it changes, the end-user will not have access to their previously created content anymore. So don't use eg. an e-mail address if those can change in your platform! This will also be used to uniquely identify a Monthly Active Viewer (MAV) for your Organization.
    name
    string REQUIRED
    The full name of the end-user (i.e. First name and Last name). This will be used in our UI.
    email
    string REQUIRED
    The email address of the end-user. This will be used in our UI.
    suborganization
    string REQUIRED
    Each SSO token should be in a suborganization. The suborganization determines which other users they can see & interact with. It is required to avoid accidentally forgetting to set it which would cause all users to see each other! If you want totally isolated users, set it to the unique username.
    integration_id
    uuid REQUIRED
    The UUID of the integration that the SSO token should have access to.
    role
    string REQUIRED
    The role of the user for who you are making the authorization request. More information on the different roles:
    • "viewer"
      SSO users that should only be able to view and interact with one or more dashboards, variants, and duplicates.
    • "designer"
      SSO users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates.
    • "owner"
      SSO users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates, and next to that they should be able to favorite dashboard variants for other SSO users within their suborganization.
    More info under Embedded Dashboard Editor.
    metadata
    object
    Parameter name and value. The value should be a number, string or array depending on the parameter type set when creating the parameter.

    Specify Connection/Account overrides

       Override the host property of your standard database connection 
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "properties":{
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your end user >",
        "name": "< end-user name >",
        "email": "< end-user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "viewer",
        "account_overrides": {
          "< Your connection id >" : {
            "host": "< The new database host to connect to. >"
          }
        }
      }
    }
    EOF
    
       Override the host property of your standard database connection 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
      api_key: "< Your API key >",
      api_token: "< Your API token >",
      host: "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    });
    
    client.create("authorization", {
      type: "sso",
      expiry: "24 hours",
      inactivity_interval: "10 minutes",
      username: "< A unique and immutable identifier for your end user >",
      name: "< end-user name >",
      email: "< end-user email >",
      suborganization: "< a suborganization name >",
      integration_id: "< integration id >",
      role: "viewer",
      account_overrides: {
        "< your connection id >": {
          host: "< The new database host to connect to. >",
        },
      },
    });
    
       Override the host property of your standard database connection 
    <?php
    $client = Luzmo::initialize("< your API key >", "< your API token >",
     "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    $authorization = $client->create("authorization", array(
      "type" => "sso",
      "expiry" => "24 hours",
      "inactivity_interval" => "10 minutes",
      "username" => "< A unique and immutable identifier for your end user >",
      "name" => "< end-user name >",
      "email" => "< end-user email >",
      "suborganization" => "< a suborganization name >",
      "integration_id" => "< integration id >",
      "role" => "viewer",
      "account_overrides" => array(
        "< your connection id >" => array(
          "host" => "< The new database host to connect to. >"
        )
       )
    ));
    ?>
    
       Override the host property of your standard database connection 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >",
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","sso")
      .put("expiry", "24 hours")
      .put("inactivity_interval", "10 minutes")
      .put("username", "< A unique and immutable identifier for your end user >")
      .put("name", "< end-user name >")
      .put("email", "< end-user email >")
      .put("suborganization", "< a suborganization name >")
      .put("integration_id", "< integration id >")
      .put("role", "viewer")
      .put("account_overrides", ImmutableMap.builder()
        .put("< your connection id >", ImmutableMap.builder()
          .put("host", "< The new database host to connect to. >")
          .build()
        )
        .build()
      )
      .build()
    );
    
       Override the host property of your standard database connection 
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "sso";
    properties.expiry = "24 hours";
    properties.inactivity_interval = "10 minutes";
    properties.username = "< A unique and immutable identifier for your end user >";
    properties.name = "< end-user name >";
    properties.email = "< end-user email >";
    properties.suborganization = "< a suborganization name >";
    properties.integration_id = "< integration id >";
    properties.role = "viewer";
    properties.account_overrides = new {
      "<your connection id>" = new {
        host = "< The new database host to connect to. >",
    
      }
    };
    
    dynamic authorization = client.create("authorization", properties);
    Console.WriteLine("Success!", authorization);
    
       Override the host property of your standard database connection 
    from luzmo.luzmo import Luzmo
    
    key = "Your Luzmo key"
    token = "Your Luzmo token"
    
    client = Luzmo(key, token,
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    
    authorization = client.create("authorization", {
      "type": "sso",
      "expiry": "24 hours",
      "inactivity_interval": "10 minutes",
      "username": "< A unique and immutable identifier for your end user >",
      "name": "< end-user name >",
      "email": "< end-user email >",
      "suborganization": "< a suborganization name >",
      "integration_id": "< integration id >",
      "role": "viewer",
      "account_overrides": {
        "< your connection id >" : {
          "host": "< The new database host to connect to. >"
        }
      }
    });
    
       Override the base_url and a custom authentication property of a plugin connection 
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "properties":{
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your end user >",
        "name": "< end-user name >",
        "email": "< end-user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "viewer",
        "account_overrides": {
          "< your connection id >" : {
            "base_url": "< The new plugin base URL to connect to. >",
            "properties": {
              "< custom authentication property ID >": "< the new custom authentication property value >"
            }
          }
        }
      }
    }
    EOF
    
       Override the base_url and a custom authentication property of a plugin connection 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
      api_key: "< Your API key >",
      api_token: "< Your API token >",
      host: "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    });
    
    client.create("authorization", {
      type: "sso",
      expiry: "24 hours",
      inactivity_interval: "10 minutes",
      username: "< A unique and immutable identifier for your end user >",
      name: "< end-user name >",
      email: "< end-user email >",
      suborganization: "< a suborganization name >",
      integration_id: "< integration id >",
      role: "viewer",
      account_overrides: {
        "< your connection id >": {
          base_url: "< The new plugin base URL to connect to. >",
          properties: {
            "< custom authentication property ID >":
              "< the new custom authentication property value >",
          },
        },
      },
    });
    
       Override the base_url and a custom authentication property of a plugin connection 
    <?php
    $client = Luzmo::initialize("< your API key >", "< your API token >",
     "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    $authorization = $client->create("authorization", array(
      "type" => "sso",
      "expiry" => "24 hours",
      "inactivity_interval" => "10 minutes",
      "username" => "< A unique and immutable identifier for your end user >",
      "name" => "< end-user name >",
      "email" => "< end-user email >",
      "suborganization" => "< a suborganization name >",
      "integration_id" => "< integration id >",
      "role" => "viewer",
      "account_overrides" => array(
        "< your connection id >" => array(
          "base_url" => "< The new plugin base URL to connect to. >",
          "properties" => array(
            "< custom authentication property ID >" => "< the new custom authentication property value >"
          )
        )
       )
    ));
    ?>
    
       Override the base_url and a custom authentication property of a plugin connection 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >",
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","sso")
      .put("expiry", "24 hours")
      .put("inactivity_interval", "10 minutes")
      .put("username", "< A unique and immutable identifier for your end user >")
      .put("name", "< end-user name >")
      .put("email", "< end-user email >")
      .put("suborganization", "< a suborganization name >")
      .put("integration_id", "< integration id >")
      .put("role", "viewer")
      .put("account_overrides", ImmutableMap.builder()
        .put("< your connection id >", ImmutableMap.builder()
          .put("base_url", "< The new plugin base URL to connect to. >")
          .put("properties", ImmutableMap.builder()
            .put("< custom authentication property ID >", "< the new custom authentication property value >")
            .build()
          )
          .build()
        )
        .build()
      )
      .build()
    );
    
       Override the base_url and a custom authentication property of a plugin connection 
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "sso";
    properties.expiry = "24 hours";
    properties.inactivity_interval = "10 minutes";
    properties.username = "< A unique and immutable identifier for your end user >";
    properties.name = "< end-user name >";
    properties.email = "< end-user email >";
    properties.suborganization = "< a suborganization name >";
    properties.integration_id = "< integration id >";
    properties.role = "viewer";
    properties.account_overrides = new {
      "<your connection id>" =  new {
        base_url = "< The new plugin base URL to connect to. >",
        properties = new {
          "< custom authentication property ID >" = "< the new custom authentication property value >"
        }
      }
      }
    };
    
    dynamic authorization = client.create("authorization", properties);
    Console.WriteLine("Success!", authorization);
    
       Override the base_url and a custom authentication property of a plugin connection 
    from luzmo.luzmo import Luzmo
    
    key = "Your Luzmo key"
    token = "Your Luzmo token"
    
    client = Luzmo(key, token,
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    
    authorization = client.create("authorization", {
      "type": "sso",
      "expiry": "24 hours",
      "inactivity_interval": "10 minutes",
      "username": "< A unique and immutable identifier for your end user >",
      "name": "< end-user name >",
      "email": "< end-user email >",
      "suborganization": "< a suborganization name >",
      "integration_id": "< integration id >",
      "role": "viewer",
      "account_overrides": {
        "< your connection id >" : {
          "base_url": "< The new plugin base URL to connect to. >",
          "properties": {
            "< custom authentication property ID >": "< the new custom authentication property value >"
          }
        }
      }
    });
    
      An example showing how to apply dataset level overrides when using account_overrides.
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","sso")
      .put("expiry", "24 hours")
      .put("inactivity_interval", "10 minutes")
      .put("username", "< A unique and immutable identifier for your end user >")
      .put("name", "< end-user name >")
      .put("email", "< end-user email >")
      .put("suborganization", "< a suborganization name >")
      .put("integration_id", "< integration id >")
      .put("role", "viewer")
      .put("account_overrides", ImmutableMap.builder()
        .put("< your connection id >", ImmutableMap.builder()
          .put("datasets", ImmutableMap.builder()
            .put("< dataset ID >", ImmutableMap.builder()
              .put("table", "< new table name >")
              .build()
            )
            .build()
          )
          .build()
        )
        .build()
      )
      .build()
    );
    System.out.println("Success! %s%n", authorization);
    
      An example showing how to apply dataset level overrides when using account_overrides.  
    
    dynamic properties = new ExpandoObject();
    
    properties.type = "sso";
    properties.expiry = "24 hours";
    properties.inactivity_interval = "10 minutes";
    properties.username = "< A unique and immutable identifier for your end user >";
    properties.name = "< end-user name >";
    properties.email = "< end-user email >";
    properties.suborganization = "< a suborganization name >";
    properties.integration_id = "< integration id >";
    properties.role = "viewer";
    properties.account_overrides = new {
      < your connection id > = new {
        datasets = new {
          < dataset ID > = new {
            table = "< my new table name >"
          }
        }
      }
    };
    
    dynamic authorization = client.create("authorization",    properties);
    Console.WriteLine("Success!", authorization);
    
      An example showing how to apply dataset level overrides when using account_overrides.  
    
    client
      .create("authorization", {
        type: "sso",
        expiry: "24 hours",
        inactivity_interval: "10 minutes",
        username: "< A unique and immutable identifier for your end user >",
        name: "< end-user name >",
        email: "< end-user email >",
        suborganization: "< a suborganization name >",
        integration_id: "< integration id >",
        role: "viewer",
        account_overrides: {
          "< your connection id >": {
            datasets: {
              "< dataset ID >": {
                table: "< my new table name >",
              },
            },
          },
        },
      })
      .then(function (authorization) {
        console.log("Success!", authorization);
      });
    
       An example showing how to apply dataset level overrides when using account_overrides.
    
    <?php
    $authorization = $client->create("authorization",
    
      array (
        "type" => "sso",
        "expiry" => "24 hours",
        "inactivity_interval" => "10 minutes",
        "username" => "< A unique and immutable identifier for your end user >",
        "name" => "< end-user name >",
        "email" => "< end-user email >",
        "suborganization" => "< a suborganization name >",
        "integration_id" => "< integration id >",
        "role" => "viewer",
        "account_overrides" => array (
          "< your connection id >" => array (
            "datasets" => array (
              "< dataset ID >" => array (
                "table" => "< my new table name >"
              )
            )
          )
        )
      )
    
    );
    print("Success! { $authorization }");
    ?>
    
        An example showing how to apply dataset level overrides when using account_overrides.
    
    curl https://api.luzmo.com/0.1.0/authorization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your end user >",
        "name": "< end-user name >",
        "email": "< end-user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "viewer",
        "account_overrides": {
          "<your connection id >": {
            "datasets": {
              "< dataset ID >": {
                "table": "< my new table name >"
              }
            }
          }
        }
      }
    }
    EOF
    
    
      An example showing how to apply dataset level overrides when using account_overrides.  
    
    authorization = client.create("authorization",
      {
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your end user >",
        "name": "< end-user name >",
        "email": "< end-user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "viewer",
        "account_overrides": {
          "< your connection id >": {
            "datasets": {
              "< dataset ID >": {
                "table": "< my new table name >"
              }
            }
          }
        }
      }
    
    )
    

    Your data may be split over databases per client. In such case, you can create multitenant dashboard in Luzmo using the connection overrides (account_overrides) functionality. A connection in Luzmo contains the information that is necessary to access a certain plugin or database. The connection overrides (account_overrides) functionality allows you to dynamically override one or multiple of these properties.

    You can override the connection properties when creating your authorization requests to switch between databases. You could also use this approach to change the user/password in a single database in case your database provides row-level security. Row-level security in this context means that the database can automatically filter out rows based on the credentials.

    You can use connection overrides if you are using one of the standard Luzmo connectors (MySQL, PostgreSQL, ...) as well as if you are using a Plugin to connect your data.

    You can find your connection id by going to the Connections tab in the side menu, look for your data connection, then click on the three dots to the right of the connection name and select "More Info." Alternatively you can perform an API call to get your connections id.

    Property Description
    type
    string REQUIRED
    sso Use the value 'sso' for integrating a dashboard.
    expiry
    date (RFC 3339) or string REQUIRED
    Date/time when this authorization will cease working. To promote better security practices this property is required and enforced with a maximum expiry date of 1 year. It is advised to only use short-living tokens (max. 24 hours) for maximum security.
    inactivity_interval
    integer or string
    Duration of inactivity after which the token is prematurely invalidated. You can use this to invalidate tokens quickly when the session is ended (eg. all open dashboards are closed). If specified, a minimum value of 2 minutes is enforced to avoid undesired invalidation of a token due to e.g. missing a heartbeat signal sent by our server. Defaults to 0 (i.e. no inactivity_interval).
    username
    string REQUIRED
    Identifies the end-user uniquely and immutably. This should correspond to eg. the primary key for the end-user on your end. If it changes, the end-user will not have access to their previously created content anymore. So don't use eg. an e-mail address if those can change in your platform! This will also be used to uniquely identify a Monthly Active Viewer (MAV) for your Organization.
    name
    string REQUIRED
    The full name of the end-user (i.e. First name and Last name). This will be used in our UI.
    email
    string REQUIRED
    The email address of the end-user. This will be used in our UI.
    suborganization
    string REQUIRED
    Each SSO token should be in a suborganization. The suborganization determines which other users they can see & interact with. It is required to avoid accidentally forgetting to set it which would cause all users to see each other! If you want totally isolated users, set it to the unique username.
    integration_id
    uuid REQUIRED
    The UUID of the integration that the SSO token should have access to.
    role
    string REQUIRED
    The role of the user for who you are making the authorization request. More information on the different roles:
    • "viewer"
      SSO users that should only be able to view and interact with one or more dashboards, variants, and duplicates.
    • "designer"
      SSO users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates.
    • "owner"
      SSO users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates, and next to that they should be able to favorite dashboard variants for other SSO users within their suborganization.
    More info under Embedded Dashboard Editor.
    account_overrides
    object
    Let this token override the connection to one or more data connections (to a Plugin or database). You can use this to dynamically route requests to different endpoints (eg. the correct endpoint per client in a single-tenant setup). All overrides are optional -- if not specified, the value as configured on the original connection will be used instead.
    connection id
    object
    The database connection id for which you want to override the properties.
    host
    string
    The new database host to connect to. The database must be of the same type as the originally configured database.
    port
    string
    The new port to connect to.
    user
    string
    The new user to use when connecting.
    password
    string
    The new password to use when connecting.
    database
    string
    The new database to retrieve data from.
    Note that to MySQL the concepts database and schema are identical. So when overriding a database / schema for MySQL, make sure to pass the same value for both schema and database
    schema
    string
    The new schema to retrieve data from.
    Note that to MySQL the concepts database and schema are identical. So when overriding a database / schema for MySQL, make sure to pass the same value for both schema and database
    table
    string
    The new table to retrieve data from.
    datasets
    object
    List of dataset-level overrides. Useful if you want to override only a single table in your dashboard or if you have a separate table per client. The SQL query of the dataset can also be overridden if it's a SQL dataset within Luzmo. Allowing you to call stored procedures for example.
    dataset_id
    string
    The dataset (securable) ID that you want to override.
    table
    string
    The new table to retrieve data from.
    schema
    string
    The new schema to retrieve data from.
    sql
    string
    The new SQL query to run. NOTE: the columns returned in the new query need to conform to the same schema as the original dataset.
    connection_id
    object
    The Plugin connection id for which you want to override the properties.
    base_url
    string
    The new base URL that will be called.
    properties
    object
    Lists the custom authentication properties to override for plugin-based connections.
    <custom_property_id>
    string
    The new custom authentication property value (the key is the custom authentication property id as defined when setting up the plugin in Luzmo).
    This will be sent as X-Property-<custom_property_id> header to the Plugin.
    datasets
    object
    List of dataset-level overrides. Useful if you want to override only a single table in your dashboard or if you have a separate table per client.
    dataset_id
    string
    The dataset (securable) ID that you want to override.
    table
    string
    The new canonical dataset identifier (as defined in the Plugin) to retrieve data from.

    Embedded dashboard editor

    Empower your users to create and alter dashboards straight from within your application with our embedded dashboard editor. With the embedded dashboard editor, non-technical users can easily create their own insights based on the data they were given access to!

    After setting up an Integration, adding the embedding code in your backend and frontend and handling your multi-tenancy, there are a few topics that are important for the embedded dashboard editor:

    Define securable access rights

    To start, it is important that you define the correct access rights when associating your dashboards and datasets with the Integration.

    Access to dashboard(s)
       Associate an Integration with a dashboard in order to make that dashboard available to users given access to the Integration via an SSO token. Set the rights to the dashboard to "can use".
    client.associate("integration", "< your integration id >", "Securables", "< your dashboard id >",
      ImmutableMap.of(
        "flagRead" , true,
        "flagUse", true,
        "slug", "< lowercase alphanumeric slug name >"
      ) );
    
       Associate an Integration with a dashboard in order to make that dashboard available to users given access to the Integration via an SSO token. Set the rights to the dashboard to "can use".
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagUse = true;
    properties.slug = "< lowercase alphanumeric slug name >";
    
    client.associate("integration", "< your integration id >", "Securables", "< your dashboard id >", properties );
    
       Associate an Integration with a dashboard in order to make that dashboard available to users given access to the Integration via an SSO token. Set the rights to the dashboard to "can use".
    let promise = client.associate("integration", "< your integration id >", {
        role: "Securables",
        id: "< your dashboard id >"
    },
    {
        flagRead: true,
      flagUse: true,
        slug: "< lowercase alphanumeric slug name >"
    });
    
      Associate an Integration with a dashboard in order to make that dashboard available to users given access to the Integration via an SSO token. Set the rights to the dashboard to "can use".
    <?php
    $client->associate("integration", "< your integration id >", "Securables", "< your dashboard id >", ,
      array (
        "flagRead" => true,
        "flagUse" => true,
        "slug => "< lowercase alphanumeric slug name >"
      ) );
    ?>
    
      Associate an Integration with a dashboard in order to make that dashboard available to users given access to the Integration via an SSO token. Set the rights to the dashboard to "can use".
    curl https://api.luzmo.com/0.1.0/integration  \
    -H "Content-Type: application/json"  \
    -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "< your integration id >",
      "resource": {
        "role": "Securables",
        "id": "< your dashboard id >"
      },
      "properties": {
        "flagRead": true,
        "flagUse": true,
        "slug": "< lowercase alphanumeric slug name >"
      }
    }
    EOF
    
      Associate an Integration with a dashboard in order to make that dashboard available to users given access to the Integration via an SSO token. Set the rights to the dashboard to "can use".
    client.associate("integration", "< your integration id >", {
        "role": "Securables",
        "id": "< your dashboard id >"
    },
    {
        "flagRead": true,
      "flagUse": true,
        "slug": "< lowercase alphanumeric slug name >"
    });
    

    The association has flag properties to define what kind of rights a user who has access to the Integration will receive. If no flag properties are specified, the rights will bet set to "can view" by default. The available flags are:

    Warning! If you give 'can use' or 'can edit' rights on a dashboard, you must ensure that all multi-tenant (parameter) filters are defined on the dataset level (i.e. when associating the dataset(s) with the Integration, Suborganization, Group, or User) and not on the dashboard level. Designer users are able to modify the dashboard content (either in a variant, in a duplicate or in the dashboard itself) and thus remove these (parameter) filters if you would define them on the dashboard!


    Access to dataset(s)
       Associate an Integration to a dataset, give use rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    client.associate("integration", "<your integration id >", "Securables", "< your dataset id >",
      ImmutableMap.of(
        "flagRead", true,
        "flagUse", true,
        "filters", ImmutableList.of(
          ImmutableMap.of(
            "clause", "where",
            "origin", "global",
            "securable_id", "< dataset id >",
            "column_id", "< column id of a column in the dataset >",
            "expression", "? in ?",
            "value", ImmutableMap.of(
              parameter: "metadata.< parameter name >",
              type: "array[hierarchy]",
              value: ImmutableList.of(
                "< default parameter value >"
              )
            )
          )
        )
      )
    );
    
       Associate an Integration to a dataset, give use rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagUse = true;
    
    properties.filters = new List<dynamic> {
      new {  
        clause = "where";
        origin = "global";
        securable_id = "< dataset id >";
        column_id = "< column id of a column in the dataset >";
        expression = "? in ?";
        value = new {
          parameter: "metadata.< parameter name >",
          type: "array[hierarchy]",
          value: new List<String> {
            "< default parameter value >"
          }
        };
      }
    };
    
    client.associate("integration", "< your integration id >", "Securables", "< your dataset id >",   properties );
    
       Associate an Integration to a dataset, give use rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    let promise = client.associate("integration", "< your integration id >", {
      role: "Securables",
      id: "< your dataset id >"
    },
    {
      flagRead: true,
      flagUse: true,
      filters: [
        {
          clause: "where",
          origin: "global",
          securable_id: "< dataset id >",
          column_id: "< column id of a column used in the dataset >",  
          expression: "? in ?",
          value: {
            parameter: "metadata.< parameter name >",
            type: "array[hierarchy]",
            value: ["< default parameter value >"]
          }
        }  
      ]
    });
    
       Associate an Integration to a dataset, give use rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    <?php
    $client->associate("integration", "< your integration id >", "Securables", "< your dataset id >", ,
      array (
        "flagRead" => true,
        "flagUse" => true,
        "filters" => array(
          array(
            "clause"       => "where",
            "origin"       => "global",
            "securable_id" => "< dataset id >",
            "column_id"    => "< column id of a column used in the dataset >",
            "expression"   => "? in ?",
            "value"        => array(
              "parameter" => "metadata.< parameter name >",
              "type" => "array[hierarchy]",
              "value" => array("< default parameter value >")
            )
          )
        )
      ) );
    ?>
    
       Associate an Integration to a dataset, give use rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    curl https://api.luzmo.com/0.1.0/integration  \
    -H "Content-Type: application/json"  \
    -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "< your integration id >",
      "resource": {
        "role": "Securables",
        "id": "< your dataset id >"
      },
      "properties": {
        "flagRead": true,
        "flagUse": true,
        "filters": [
            {
              "clause": "where",
              "origin": "global",
              "securable_id": "< dataset id >",
              "column_id": "< column id of a column used in the dataset >",  
              "expression": "? in ?",
              "value": {
                "parameter": "metadata.< parameter name >",
                "type": "array[hierarchy]",
                "value": ["< default parameter value >"]
              }
            }
          ]
      }
    }
    EOF
    
       Associate an Integration to a dataset, give use rights and apply some parameter filters. The parameter specified can be overridden when requesting a SSO token to apply dynamic row-level security! 
    client.associate("integration", "< your integration id >", {
      "role": "Securables",
      "id": "< your dataset id >"
    },
    {
      "flagRead": true,
      "flagUse": true,
      "filters": [
        {
          "clause": "where",
          "origin": "global",
          "securable_id": "< dataset id >",
          "column_id": "< column id of a column used in the dataset >",  
          "expression": "? in ?",
          "value": {
            "parameter": "metadata.< parameter name >",
            "type": "array[hierarchy]",
            "value": ["< default parameter value >"]
          }
        }  
      ]
    });
    
       Associate an Integration to a dataset, give it modify rights and apply a static filter for e.g. row-level security. 
    client.associate("integration", "< your integration id >", "Securables", "< your dataset id >",
      ImmutableMap.of(
        "flagRead", true,
        "flagUse", true,
        "flagModify", true,
        "filters", ImmutableList.of(
          ImmutableMap.of(
            "clause", "where",
            "origin", "global",
            "securable_id", "< dataset id >",
            "column_id", "< column id of a column in the dataset >",
            "expression", "? = ?",
            "value", "< value to be applied to the expression >"
          )
        )
      )
    );
    
       Associate an Integration to a dataset, give it modify rights and apply a static filter for e.g. row-level security. 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagUse = true;
    properties.flagModify = true;
    
    properties.filters = new List<dynamic> {
      new {  
        clause = "where";
        origin = "global";
        securable_id = "< dataset id >";
        column_id = "< column id of a column in the dataset >";
        expression = "? = ?";
        value = "< value to be applied to the expression >";
      }
    };
    
    client.associate("integration", "< your integration id >", "Securables", "< your dataset id >",   properties );
    
       Associate an Integration to a dataset, give it modify rights and apply a static filter for e.g. row-level security. 
    let promise = client.associate("integration", "< your integration id >", {
      role: "Securables",
      id: "< your dataset id >"
    },
    {
      flagRead: true,
      flagUse: true,
      flagModify: true,
      filters: [
        {
          clause: "where",
          origin: "global",
          securable_id: "< dataset id >",
          column_id: "< column id of a column used in the dataset >",  
          expression: "? = ?",
          value: "< value to be applied to the expression >"
        }  
      ]
    });
    
       Associate an Integration to a dataset, give it modify rights and apply a static filter for e.g. row-level security. 
    <?php
    $client->associate("integration", "< your integration id >", "Securables", "< your dataset id >", ,
      array (
        "flagRead" => true,
        "flagUse" => true,
        "flagModify" => true,
        "filters" => array(
          "clause"       => "where",
          "origin"       => "global",
          "securable_id" => "< dataset id >",
          "column_id"    => "< column id of a column used in the dataset >",
          "expression"   => "? = ?",
          "value"        => "< value to be applied to the expression >"
        )
      ) );
    ?>
    
       Associate an Integration to a dataset, give it modify rights and apply a static filter for e.g. row-level security. 
    curl https://api.luzmo.com/0.1.0/integration  \
    -H "Content-Type: application/json"  \
    -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your integration id >",
      "resource": {
        "role": "Securables",
        "id": "< your dataset id >"
      },
      "properties": {
        "flagRead": true,
        "flagUse": true,
        "flagModify": true,
        "filters": [
            {
              "clause": "where",
              "origin": "global",
              "securable_id": "< dataset id >",
              "column_id": "< column id of a column used in the dataset >",  
              "expression": "? = ?",
              "value": "< value to be applied to the expression >"
            }
          ]
      }
    }
    EOF
    

    When associating a dataset with an Integration you can specify some flag properties to define what kind of rights a user who has access to the Integration will receive. If no flag properties are specified, the rights will bet set to "can view" by default. The available flags are:

    Important! For security reasons it’s of uttermost importance that multi-tenant (parameter) filters are specified on the dataset level, this ensures that they are always applied when the user queries the dataset directly or via a (new) dashboard. Parameterizable filters can be used to dynamically apply these filters by overriding the parameter value(s) when requesting a SSO token for your user. Instead of using parameterizable filters, you could also specify static filters when associating a dataset with an Integration or when requesting SSO authorization tokens.

    Specify user role in backend

      Generate an SSO token for your user. Replace with your API key & token and integration_id and fill in the user's details. 
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "properties":{
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "designer"
      }
    }
    EOF
    
       Generate an SSO token for your user. Replace with your API key & token and integration_id and fill in the user's details.
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: "< Your API key >",
        api_token: "< Your API token >",
        host: "< https://api.luzmo.com (dclassefault) or https://api.us.luzmo.com/ or your VPC-specific address >"
    });
    
    let promise = client.create("authorization", {
      type: "sso",
      expiry: "24 hours",
      inactivity_interval: "10 minutes",
      username: "< A unique and immutable identifier for your user >",
      name: "< user name >",
      email: "< user email >",
      suborganization: "< a suborganization name >",
      integration_id: "< integration id >",
      role: "designer"
    });
    
    promise.then(function(result){
      // return the result to the client
    })
    
    
      Generate an SSO token for your user. Replace with your API key & token and integration_id and fill in the user's details.
    <?php
    $client = Luzmo::initialize("< your API key >", "< your API token >",
     "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    
    $authorization = $client->create("authorization", array(
      "type" => "sso",
      "expiry" => "24 hours",
      "inactivity_interval" => "10 minutes",
      "username" => "< A unique and immutable identifier for your user >",
      "name" => "< user name >",
      "email" => "< user email >",
      "suborganization" => "< a suborganization name >",
      "integration_id" => "< integration id >",
      "role" => "designer"
    ));
    ?>
    
      Generate an SSO token for your user. Replace with your API key & token and integration_id and fill in the user's details.
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >",
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","sso")
      .put("expiry", "24 hours")
      .put("inactivity_interval", "10 minutes")
      .put("username", "< A unique and immutable identifier for your user >")
      .put("name", "< user name >")
      .put("email", "< user email >")
      .put("suborganization", "< a suborganization name >")
      .put("integration_id", "< integration id >")
      .put("role", "designer")
      .build()
    );
    
       Generate an SSO token for your user. Replace with your API key & token and integration_id and fill in the user's details.
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "sso";
    properties.expiry = "24 hours";
    properties.inactivity_interval = "10 minutes";
    properties.username = "< A unique and immutable identifier for your user >";
    properties.name = "< user name >";
    properties.email = "< user email >";
    properties.suborganization = "< a suborganization name >";
    properties.integration_id = "< integration id >";
    properties.role = "designer";
    
    dynamic authorization = client.create("authorization", properties);
    Console.WriteLine("Success!", authorization);
    
       Generate an SSO token for your user. Replace with your API key & token and integration_id and fill in the user's details.
    from luzmo.luzmo import Luzmo
    
    key = "Your Luzmo key"
    token = "Your Luzmo token"
    
    client = Luzmo(key, token,
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    
    authorization = client.create("authorization", {
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "designer"
    });
    
    
       This returns a JSON object with an id/token combination that we will use to integrate: 
    {
      "type": "sso",
      "id": "< the SSO authorization key >",
      "token": "< the SSO authorization token >",
      "user_id": "< a uuid used on our end to identify the SSO user >"
      // ...
    }
    

    In this step, your server-side code makes an API request to retrieve an authorization token of type SSO. The result of this request is a key/token combination that will be used to in the frontend component to securely embed the dashboard in your application/platform.

    The API request is a 'create' request for an authorization. In this API call we use the integration id that we created before (see Set up an Integration), and next to that we specify the role that your user should have. The flow chart below should help in making that decision for your specific use-case and user!

    Property Description
    type
    string REQUIRED
    sso Use the value 'sso' for embedding a dashboard or the dashboard editor.
    expiry
    date (RFC 3339) or string REQUIRED
    Date/time when this authorization will cease working. To promote better security practices this property is required and enforced with a maximum expiry date of 1 year. It is advised to only use short-living tokens (max. 24 hours) for maximum security.
    inactivity_interval
    integer or string
    Duration of inactivity after which the token is prematurely invalidated. You can use this to invalidate tokens quickly when the session is ended (eg. all open dashboards are closed). If specified, a minimum value of 2 minutes is enforced to avoid undesired invalidation of a token due to e.g. missing a heartbeat signal sent by our server.
    Defaults to 0 (i.e. no inactivity_interval).
    username
    string REQUIRED
    Identifies the user uniquely and immutably. This should correspond to eg. the primary key for the user on your end. If it changes, the user will not have access to their previously created content anymore. So don't use eg. an e-mail address if those can change in your platform! This will also be used to uniquely identify a Monthly Active Viewer (MAV) for your Organization.
    name
    string REQUIRED
    The full name of the user (i.e. First name and Last name). This will be used in our UI.
    email
    string REQUIRED
    The email address of the user. This will be used in our UI.
    suborganization
    string REQUIRED
    Each SSO token should be in a suborganization. The suborganization determines which other users they can see & interact with. It is required to avoid accidentally forgetting to set it which would cause all users to see each other! If you want totally isolated users, set it to the unique username.
    integration_id
    uuid REQUIRED
    The UUID of the Integration that the SSO token should have access to.
    role
    string REQUIRED
    The role of the user for who you are making the authorization request. More information on the different roles:
    • "viewer"
      SSO users that should only be able to view and interact with one or more dashboards, variants, and duplicates.
    • "designer"
      SSO users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates.
    • "owner"
      SSO users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates, and next to that they should be able to favorite dashboard variants for other SSO users within their suborganization.

    For a list of all properties that you can use in the request, check Authorization in the Core API.

    The request returns a JSON object that contains an authorization id & token. This is the key/token combination that will be used in our next step (client-side) to embed the dashboard in a secure way.

    Set edit mode in frontend

       In the code example below, you can see how you can set the edit mode via the component properties, as well as the main and accent color of the editor 
    <!--
    Clients on our US multi-tenant application environment,
    or a dedicated instance on a specific VPC, should specify:
    - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
    - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
    -->
    <luzmo-dashboard
      appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
      apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
      authKey="< SSO authorization key >"
      authToken="< SSO authorization token >"
      editMode="< view, editLimited, or editFull >"
      dashboardId="< dashboard id you want to embed >"
    ></luzmo-dashboard>
    
    /*
    Clients on our US multi-tenant application environment,
    or a dedicated instance on a specific VPC, should specify:
    - [appServer]="'https://app.us.luzmo.com/'" (or your VPC-specific address)
    - [apiHost]="'https://api.us.luzmo.com/'" (or your VPC-specific address)
    */
    <luzmo-dashboard
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< SSO authorization key >'"
      [authToken]="'< SSO authorization token >'"
      [editMode]="'< view, editLimited, or editFull >'"
      [dashboardId]="'< dashboard id you want to embed >'"
    ></luzmo-dashboard>
    
    import { LuzmoDashboardComponent } from '@luzmo/react-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        /*
        Clients on our US multi-tenant application environment,
        or a dedicated instance on a specific VPC, should specify:
        - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
        - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
        */
        return (
          <LuzmoDashboardComponent
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< SSO authorization key >"
            authToken="< SSO authorization token >"
            editMode="< view, editLimited, or editFull >"
            dashboardId="< dashboard id you want to embed >"
          ></LuzmoDashboardComponent>
        );
      }
    
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        /*
        Clients on our US multi-tenant application environment,
        or a dedicated instance on a specific VPC, should specify:
        - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
        - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
        */
        return (
          <LuzmoDashboardComponent
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< SSO authorization key >"
            authToken="< SSO authorization token >"
            editMode="< view, editLimited, or editFull >"
            dashboardId="< dashboard id you want to embed >"
          ></LuzmoDashboardComponent>
        );
      }
    
    <template>
      ...
    
      <!--
      Clients on our US multi-tenant application environment,
      or a dedicated instance on a specific VPC, should specify:
      - :appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
      - :apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
       -->
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< SSO authorization key >"
        authToken="< SSO authorization token >"
        editMode="< view, editLimited, or editFull >"
        dashboardId="< dashboard id you want to embed >"
      ></luzmo-dashboard>
      ...
    </template>
    

    To embed a dashboard in your webpage, we use the Embed Libraries.

    First, you should install and import the appropriate component in your frontend (see here).

    In this step we'll use the SSO key and token received from the authorization request in your backend to securely embed a dashboard in your frontend (referencing either the dashboard id or slug). Next to that, we'll specify the initial edit mode in which the dashboard should be loaded!

    The flow chart below could help out in deciding which editMode fits your use-case and application.

    Parameter Description
    appServer
    string
    Tenancy of Luzmo app to connect to. Defaults to 'https://app.luzmo.com/'.
    For US multi-tenant application, set appServer to 'https://app.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    apiHost
    string
    Tenancy of Luzmo API to connect to. Defaults to 'https://api.luzmo.com/'.
    For US multi-tenant application, set apiHost to 'https://api.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    authKey
    uuid
    The authorization key (i.e. "id") from the response of the authorization request in your backend.
    authToken
    string
    The authorization token from the response of the authorization request in your backend.
    dashboardId
    uuid
    This is the id of the dashboard that you want to embed.
    Specify either the dashboardId or dashboardSlug property.
    dashboardSlug
    string
    Instead of specifying a dashboardId, you can alternatively specify a dashboard slug. The slug is defined when associating a dashboard with an Integration.
    Specify either the dashboardId or dashboardSlug property.
    mainColor
    string
    (Optional) Override the main color used in the whitelabeling of the embedded dashboard editor. If not provided, the main color of the whitelabeling colors set on the organization will be used.
    Should be specified as a string of rgb values, e.g. "rgb(50,50,50)".

    A gif showcasing the influence of specifying mainColor can be seen in this Academy article.
    accentColor
    string
    (Optional) Override the accent color used in the whitelabeling of the embedded dashboard editor. If not provided, the accent color of the whitelabeling colors set on the organization will be used.
    Should be specified as a string of rgb values, e.g. "rgb(50,50,50)".

    A gif showcasing the influence of specifying accentColor can be seen in this Academy article.
    editMode
    string DashboardEditMode
    The mode in which the dashboard should be loaded. Defaults to "view".
    • "view"
      This mode enables your users to view and interact with an embedded dashboard, without having the option to change the dashboard itself.
    • "editLimited"
      This mode is useful if you have your own dashboard navigation in your application (e.g. a sidebar containing dashboard tabs or a dropdown) and would like the user to edit (some of) the dashboards (e.g. by adding an “Edit” button that toggles the editMode between “view” and “editLimited” mode). Users will be able to create variants of the dashboard or edit the dashboard itself (depending on the access rights you defined for the dashboard) and share these dashboard (variants) with other users in their organization.
    • "editFull"
      If you have a dedicated place in your application where users should be able to create & edit all their accessible dashboard(s) (e.g. in your navigation bar you have a “Dashboard editor” tab that should show the embedded dashboard editor). The user will be able to create edit, duplicate and create a variant of existing dashboards (depending on the access rights you defined for the dashboard) as well as create new dashboards and share these dashboard (variants) with other users in their organization.

    There are additional properties that can be specified to e.g. choose which screenmode or language will be loaded and/or to style the dashboard loader. This to ensure a perfect fit with the style of your page. Check the Embedding chapter for all documentation related to our frontend components.

    That's it, with these steps you've set up the basics to provide Luzmo's embedded dashboard editor to your users!

    Next steps

    Below you can find some of the additional options related to embedding Luzmo dashboards into your application!

    Retrieving a list of dashboards

       First we pass along a SSO key and token to the Web component, and then we call the getAccessibleDashboards method to retrieve the dashboards that are accessible to that key-token pair
    <html>
      <luzmo-dashboard
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
      ></luzmo-dashboard>
    </html>
    
    <script>
      // Get the component reference
      const dashboardElement = document.querySelector("luzmo-dashboard");
    
      // Set the SSO Authorization key and token pair
      dashboardElement.authKey = "< SSO Authorization Key >";
      dashboardElement.authToken = "< SSO Authorization Token >";
    
      // Retrieve the dashboards that are accessible to the SSO Authorization token
      dashboardElement.getAccessibleDashboards()
          .then(dashboards => {
              // Do something with the response, e.g. dynamically fill your application's navigation
              console.log(dashboards);
          });
    </script>
    
    1 Add the Luzmo component in your Angular page
    <luzmo-dashboard
      #dashboardInstance
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
    ></luzmo-dashboard>
    
    2 In your Angular Component file, add the following code to set a SSO key & token, and then retrieve the accessible dashboards
    import {  OnInit, Component, ViewChild } from '@angular/core';
    ...
    import {
      NgxLuzmoDashboardModule,
      AccessibleDashboard
    } from '@luzmo/ngx-embed';
    ...
    
    @Component({
      ...
    })
    
    export class LuzmoEmbeddingComponent implements OnInit {
      // Component reference
      @ViewChild('dashboardInstance') dashboardInstance: NgxLuzmoDashboardModule;
    
      ngOnInit(): void {
        // Set the SSO Authorization key and token pair
        this.dashboardInstance.authKey = "< SSO Authorization Key >";
        this.dashboardInstance.authToken = "< SSO Authorization Token >";
    
        // Retrieve the dashboards that are accessible to the SSO Authorization token
        this.dashboardInstance.getAccessibleDashboards().pipe(take(1)).subscribe((dashboards: AccessibleDashboard[]) => {
          // Do something with the response, e.g. dynamically fill your application's navigation
          console.log(dashboards);
        });
      }
    }
    
     First we pass along a SSO key and token to the React component, and then we call the getAccessibleDashboards method to retrieve the dashboards that are accessible to that key-token pair
    import { useRef } from 'react';
    ...
    import {
      LuzmoDashboardComponent
    } from "@luzmo/react-embed";
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      // Set the SSO Authorization key and token pair
      dashboardInstance.current.authKey = = "< SSO Authorization Key >";
      dashboardInstance.current.authToken = "< SSO Authorization Token >";
    
      // Retrieve the dashboards that are accessible to the SSO Authorization token
      dashboardInstance.current.getAccessibleDashboards().then(dashboards => {
        // Do something with the response, e.g. dynamically fill your application's navigation
        console.log(dashboards);
      });
    
      return (
        <LuzmoDashboardComponent
          ref={dashboardInstance}
          appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
          apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        ></LuzmoDashboardComponent>
      );
    }
    
     First we pass along a SSO key and token to the React Native component, and then we call the getAccessibleDashboards method to retrieve the dashboards that are accessible to that key-token pair
    import { useRef } from 'react';
    ...
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      // Set the SSO Authorization key and token pair
      dashboardInstance.current.authKey = = "< SSO Authorization Key >";
      dashboardInstance.current.authToken = "< SSO Authorization Token >";
    
      // Retrieve the dashboards that are accessible to the SSO Authorization token
      dashboardInstance.current.getAccessibleDashboards().then(dashboards => {
        // Do something with the response, e.g. dynamically fill your application's navigation
        console.log(dashboards);
      });
    
      return (
        <LuzmoDashboardComponent
          ref={dashboardInstance}
          appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
          apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        ></LuzmoDashboardComponent>
      );
    
     First we pass along a SSO key and token to the Vue component, and then we call the getAccessibleDashboards method to retrieve the dashboards that are accessible to that key-token pair
    <template>
      ...
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
      ></luzmo-dashboard>
      ...
    </template>
    <script>
      export default {
        mounted() {
          // Set the SSO Authorization key and token pair
          this.$refs.dashboardInstance.authKey = = "< SSO Authorization Key >";
          this.$refs.dashboardInstance.authToken = "< SSO Authorization Token >";
    
          // Retrieve the dashboards that are accessible to the SSO Authorization token
          this.$refs.dashboardInstance.getAccessibleDashboards().then(dashboards => {
            // Do something with the response, e.g. dynamically fill your application's navigation
            console.log(dashboards);
          });
        },
        ...
      }
    </script>
    
       This returns an array of dashboards, together with some relevant information related to each dashboard: 
    [
        {
            "id": "< dashboard_1_id >",
            "modifiedAt": "2021-02-10T09:13:27.114Z",
            "name": "< dashboard_1_name >",
            "slug": null,
            "tags": [
                "< dashboard_1_tag_1 >",
                "< dashboard_1_tag_2 >"
            ],
            "accessibleBy": [
                {
                    "model": "User",
                    "id": "< user_A_id >",
                    "name": "< user_A_name >"
                },
                {
                    "model": "User",
                    "id": "< user_B_id >",
                    "name": "< user_B_name >"
                },
                {
                    "model": "Group",
                    "id": "< group_id >",
                    "name": "< group_name >"
                },
                {
                    "model": "Integration",
                    "id": "< integration_id >",
                    "name": "< integration_name >"
                }
            ],
            "accessRights": {
                "flagRead": true,
                "flagUse": true,
                "flagModify": false,
                "flagOwn": false
            }
        },
        ...
    ]
    

    When you embed a dashboard with one of our embedding components (all components are listed in the Embedding chapter), you can make use of the getAccessibleDashboards method in your frontend to programmatically retrieve a list of dashboards. The dashboards that are returned are associated with the specific integration that the SSO key and token has access to, or its bootstrapped Suborganization or SSO user.
    This is particularly useful if you'd like to have a dynamic way of retrieving and providing dashboards in your frontend! Some use-cases are described in this Academy article.

    In Angular, the getAccessibleDashboards method is an Observable to which you can subscribe an observer function to. The observable will deliver an array of AccessibleDashboard elements.

    The getAccessibleDashboards method returns a Promise that resolves with an array of AccessibleDashboard elements.

    Set an initialization filter

       An example showing how to request a SSO token with an initialization filter set on a specific filter item (slider, search and select box, ...). Specifying an SSO initialization filter on a specific filter item results in preselecting the specified values in that item when loading an embedded a dashboard with that SSO key and token. The preselected value(s) can still be modified using the item's interactivity.
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "properties":{
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your end user >",
        "name": "< end-user name >",
        "email": "< end-user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "viewer",
        "filters": [
          {
            "clause": "where",
            "origin": "initialization",
            "chart_id": "< chart id of a filter object contained in the dashboard >",
            "expression": "? = ?",
            "value": "< value to be applied to the expression >"
          }
        ]
      }
    }
    EOF
    
       (client created with API token) An example showing how to request a SSO token with an initialization filter set on a specific filter item (slider, search and select box, ...). Specifying an SSO initialization filter on a specific filter item results in preselecting the specified values in that item when loading an embedded a dashboard with that SSO key and token. The preselected value(s) can still be modified using the item's interactivity. 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
      api_key: "< Your API key >",
      api_token: "< Your API token >",
      host: "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    });
    
    let promise = client.create("authorization", {
      type: "sso",
      expiry: "24 hours",
      inactivity_interval: "10 minutes",
      username: "< A unique and immutable identifier for your end user >",
      name: "< end-user name >",
      email: "< end-user email >",
      suborganization: "< a suborganization name >",
      integration_id: "< integration id >",
      role: "viewer",
      filters: [
        {
          clause: "where",
          origin: "initialization",
          chart_id: "< chart id of a filter object contained in the dashboard >",
          expression: "? = ?",
          value: "< value to be applied to the expression >",
        },
      ],
    });
    
    promise.then(function (result) {
      // return the result to the client
    });
    
       (client created with API token) An example showing how to request a SSO token with an initialization filter set on a specific filter item (slider, search and select box, ...). Specifying an SSO initialization filter on a specific filter item results in preselecting the specified values in that item when loading an embedded a dashboard with that SSO key and token. The preselected value(s) can still be modified using the item's interactivity. 
    <?php
    $client = Luzmo::initialize("< your API key >", "< your API token >",
     "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    $authorization = $client->create("authorization", array(
      "type" => "sso",
      "expiry" => "24 hours",
      "inactivity_interval" => "10 minutes",
      "username" => "< A unique and immutable identifier for your end user >",
      "name" => "< end-user name >",
      "email" => "< end-user email >",
      "suborganization" => "< a suborganization name >",
      "integration_id" => "< integration id >",
      "role" => "viewer",
      "filters" => array(
        array(
          "clause"     => "where",
          "origin"     => "initialization",
          "chart_id"   => "< chart id of a filter object contained in the dashboard >",
          "expression" => "? = ?",
          "value"      => "< value to be applied to the expression >"
        )
      ),
    ));
    ?>
    
       (client created with API token) An example showing how to request a SSO token with an initialization filter set on a specific filter item (slider, search and select box, ...). Specifying an SSO initialization filter on a specific filter item results in preselecting the specified values in that item when loading an embedded a dashboard with that SSO key and token. The preselected value(s) can still be modified using the item's interactivity. 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >",
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","sso")
      .put("expiry", "24 hours")
      .put("inactivity_interval", "10 minutes")
      .put("username", "< A unique and immutable identifier for your end user >")
      .put("name", "< end-user name >")
      .put("email", "< end-user email >")
      .put("suborganization", "< a suborganization name >")
      .put("integration_id", "< integration id >")
      .put("role", "viewer")
      .put("filters", ImmutableList.of(
        ImmutableMap.builder()
        .put("clause",       "where")
        .put("origin",       "initialization")
        .put("chart_id",     "< chart id of a filter object contained in the dashboard >")
        .put("expression",   "? = ?")
        .put("value",        "< value to be applied to the expression >")
        .build()
      ))
      .build()
    );
    
       (client created with API token) An example showing how to request a SSO token with an initialization filter set on a specific filter item (slider, search and select box, ...). Specifying an SSO initialization filter on a specific filter item results in preselecting the specified values in that item when loading an embedded a dashboard with that SSO key and token. The preselected value(s) can still be modified using the item's interactivity. 
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "sso";
    properties.expiry = "24 hours";
    properties.inactivity_interval = "10 minutes";
    properties.username = "< A unique and immutable identifier for your end user >";
    properties.name = "< end-user name >";
    properties.email = "< end-user email >";
    properties.suborganization = "< a suborganization name >";
    properties.integration_id = "< integration id >";
    properties.role = "viewer";
    properties.filters = new List<dynamic> {
      new {
        clause = "where",
        origin = "initialization",
        chart_id = "< chart id of a filter object contained in the dashboard >",
        expression = "? = ?",
        value = "< value to be applied to the expression >"
      }
    };
    
    dynamic authorization = client.create("authorization", properties);
    Console.WriteLine("Success!", authorization);
    
       (client created with API token) An example showing how to request a SSO token with an initialization filter set on a specific filter item (slider, search and select box, ...). Specifying an SSO initialization filter on a specific filter item results in preselecting the specified values in that item when loading an embedded a dashboard with that SSO key and token. The preselected value(s) can still be modified using the item's interactivity. 
    from luzmo.luzmo import Luzmo
    
    key = "Your Luzmo key"
    token = "Your Luzmo token"
    
    client = Luzmo(key, token,
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    
    authorization = client.create("authorization", {
      "type": "sso",
      "expiry": "24 hours",
      "inactivity_interval": "10 minutes",
      "username": "< A unique and immutable identifier for your end user >",
      "name": "< end-user name >",
      "email": "< end-user email >",
      "suborganization": "< a suborganization name >",
      "integration_id": "< integration id >",
      "role": "viewer",
      "filters": [
        {
          "clause": "where",
          "origin": "initialization",
          "chart_id": "< chart id of a filter object contained in the dashboard >",
          "expression": "? = ?",
          "value": "< value to be applied to the expression >"
        }
      ]
    });
    
       (client created with API token) An example showing how to request a SSO token with an initialization filter set on a chart. Specifying an SSO initialization filter on a chart results in preselecting the specified values in that item when loading an embedded a dashboard with that SSO key and token. The preselected value(s) can still be modified using the item's interactivity. Note that in this case you need to supply a column_id and securable_id, next to the chart_id, and that the filter value must always consist of an array. 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >", "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","sso")
      .put("expiry", "24 hours")
      .put("inactivity_interval", "10 minutes")
      .put("username", "< A unique and immutable identifier for your end user >")
      .put("name", "< end-user name >")
      .put("email", "< end-user email >")
      .put("suborganization", "< a suborganization name >")
      .put("integration_id", "< integration id >")
      .put("role", "viewer")
      .put("filters", ImmutableList.of(
        ImmutableMap.builder()
        .put("clause",       "where")
        .put("origin",       "initialization")
        .put("chart_id",     "< chart id of a chart object contained in the dashboard >")
        .put("expression",   "? = ?")
        .put("column_id",    "< id of the column you want to filter on (usually in category slot) >")
        .put("securable_id", "< id of the dataset that the column belongs to >")
        .put("value",        ImmutableList.of(
          "<value to be applied to the expression>"
        ))
        .build()
      ))
      .build()
    );
    
       (client created with API token) An example showing how to request a SSO token with an initialization filter set on a chart. Specifying an SSO initialization filter on a chart results in preselecting the specified values in that item when loading an embedded a dashboard with that SSO key and token. The preselected value(s) can still be modified using the item's interactivity. Note that in this case you need to supply a column_id and securable_id, next to the chart_id, and that the filter value must always consist of an array. 
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "sso";
    properties.expiry = "24 hours";
    properties.inactivity_interval = "10 minutes";
    properties.username = "< A unique and immutable identifier for your end user >";
    properties.name = "< end-user name >";
    properties.email = "< end-user email >";
    properties.suborganization = "< a suborganization name >";
    properties.integration_id = "< integration id >";
    properties.role = "viewer";
    properties.filters = new List<dynamic> {
      new {
        clause = "where",
        origin = "initialization",
        chart_id = "< chart id of a chart object contained in the dashboard >",
        expression = "? = ?",
        column_id = "< id of the column to apply the filter to (usually the category) >",
        securable_id = "< id of the dataset that the column belongs to >",
        value = new List<string> {
          "< value to be applied to the expression >"
        }
      }
    };
    
       (client created with API token) An example showing how to request a SSO token with an initialization filter set on a chart. Specifying an SSO initialization filter on a chart results in preselecting the specified values in that item when loading an embedded a dashboard with that SSO key and token. The preselected value(s) can still be modified using the item's interactivity. Note that in this case you need to supply a column_id and securable_id, next to the chart_id, and that the filter value must always consist of an array. 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
      api_key: "< Your API key >",
      api_token: "< Your API token >",
      host: "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    });
    
    let promise = client.create("authorization", {
      type: "sso",
      expiry: "24 hours",
      inactivity_interval: "10 minutes",
      username: "< A unique and immutable identifier for your end user >",
      name: "< end-user name >",
      email: "< end-user email >",
      suborganization: "< a suborganization name >",
      integration_id: "< integration id >",
      role: "viewer",
      filters: [
        {
          clause: "where",
          origin: "initialization",
          chart_id: "< chart id of a chart object contained in the dashboard >",
          expression: "? = ?",
          column_id:
            "< id of the column to apply the filter to (usually the category) >",
          securable_id: "< id of the dataset that the column belongs to >",
          value: ["< value to be applied to the expression >"],
        },
      ],
    });
    
    promise.then(function (result) {
      // return the result to the client
    });
    
       (client created with API token) An example showing how to request a SSO token with an initialization filter set on a chart. Specifying an SSO initialization filter on a chart results in preselecting the specified values in that item when loading an embedded a dashboard with that SSO key and token. The preselected value(s) can still be modified using the item's interactivity. Note that in this case you need to supply a column_id and securable_id, next to the chart_id, and that the filter value must always consist of an array. 
    <?php
    $client = Luzmo::initialize("< your API key >", "< your API token >",
     "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    $authorization = $client->create("authorization", array(
      "type" => "sso",
      "expiry" => "24 hours",
      "inactivity_interval" => "10 minutes",
      "username" => "< A unique and immutable identifier for your end user >",
      "name" => "< end-user name >",
      "email" => "< end-user email >",
      "suborganization" => "< a suborganization name >",
      "integration_id" => "< integration id >",
      "role" => "viewer",
      "filters" => array(
        array(
          "clause"       => "where",
          "origin"       => "initialization",
          "chart_id"     => "< chart id of a chart object contained in the dashboard >",
          "expression"   => "? = ?",
          "column_id"    => "< id of the column to apply the filter to (usually the category) >",
          "securable_id" => "< id of the dataset that the column belongs to >"
          "value"        => array(
            "< value to be applied to the expression >"
          )
        )
      ),
    ));
    ?>
    
       An example showing how to request a SSO token with an initialization filter set on a chart. Specifying an SSO initialization filter on a chart results in preselecting the specified values in that item when loading an embedded a dashboard with that SSO key and token. The preselected value(s) can still be modified using the item's interactivity. Note that in this case you need to supply a column_id and securable_id, next to the chart_id, and that the filter value must always consist of an array. 
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "properties":{
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your end user >",
        "name": "< end-user name >",
        "email": "< end-user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "viewer",
        "filters": [
          {
            "clause": "where",
            "origin": "initialization",
            "chart_id": "< chart id of a chart object contained in the dashboard >",
            "expression": "? = ?",
            "column_id": "< id of the column to apply the filters to >",
            "securable_id": "< id of the dataset that the column belongs to >",
            "value": [
              "< value to be applied to the expression >"
            ]
          }
        ]
      }
    }
    EOF
    
       (client created with API token) An example showing how to request a SSO token with an initialization filter set on a chart. Specifying an SSO initialization filter on a chart results in preselecting the specified values in that item when loading an embedded a dashboard with that SSO key and token. The preselected value(s) can still be modified using the item's interactivity. Note that in this case you need to supply a column_id and securable_id, next to the chart_id, and that the filter value must always consist of an array. 
    from luzmo.luzmo import Luzmo
    
    key = "Your Luzmo key"
    token = "Your Luzmo token"
    
    client = Luzmo(key, token,
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    
    authorization = client.create("authorization", {
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your end user >",
        "name": "< end-user name >",
        "email": "< end-user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "viewer",
        "filters": [
          {
            "clause": "where",
            "origin": "initialization",
            "chart_id": "< chart id of a chart object contained in the dashboard >",
            "expression": "? = ?",
            "column_id": "< id of the column to apply the filters to >",
            "securable_id": "< id of the dataset that the column belongs to >",
            "value": [
              "< value to be applied to the expression >"
            ]
          }
        ]
    });
    

    An initialization filter is a type of filter that initializes a filter on a certain filter object (slider, search and select box, ...) in an embedded dashboard. This means that the specified filter will be applied when the dashboard loads, but it can still be turned off or modified afterwards.

    To do this, extend the code snippet used in step 1 by adding a filters parameter to the request.

    For an initialization filter on a filter object, it is not needed to specify the securable_id or column_id in the filters parameter. This is because a filter object can have multiple columns, coming from different datasets.

    You can also set initialization filters on chart objects. This pre-selects a portion of the chart when the dashboard opens. The structure in this case is slightly different: next to a chart_id, you need a column_id and a securable_id.

    Property Description
    type
    string REQUIRED
    sso Use the value 'sso' for integrating a dashboard.
    expiry
    date (RFC 3339) or string REQUIRED
    Date/time when this authorization will cease working. To promote better security practices this property is required and enforced with a maximum expiry date of 1 year. It is advised to only use short-living tokens (max. 24 hours) for maximum security.
    inactivity_interval
    integer or string
    Duration of inactivity after which the token is prematurely invalidated. You can use this to invalidate tokens quickly when the session is ended (eg. all open dashboards are closed). If specified, a minimum value of 2 minutes is enforced to avoid undesired invalidation of a token due to e.g. missing a heartbeat signal sent by our server. Defaults to 0 (i.e. no inactivity_interval).
    username
    string REQUIRED
    Identifies the end-user uniquely and immutably. This should correspond to eg. the primary key for the end-user on your end. If it changes, the end-user will not have access to their previously created content anymore. So don't use eg. an e-mail address if those can change in your platform! This will also be used to uniquely identify a Monthly Active Viewer (MAV) for your Organization.
    name
    string REQUIRED
    The full name of the end-user (i.e. First name and Last name). This will be used in our UI.
    email
    string REQUIRED
    The email address of the end-user. This will be used in our UI.
    suborganization
    string REQUIRED
    Each SSO token should be in a suborganization. The suborganization determines which other users they can see & interact with. It is required to avoid accidentally forgetting to set it which would cause all users to see each other! If you want totally isolated users, set it to the unique username.
    integration_id
    uuid REQUIRED
    The UUID of the integration that the SSO token should have access to.
    role
    string REQUIRED
    The role of the user for who you are making the authorization request. More information on the different roles:
    • "viewer"
      SSO users that should only be able to view and interact with one or more dashboards, variants, and duplicates.
    • "designer"
      SSO users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates.
    • "owner"
      SSO users that should be able to create, edit, view and interact with one or more dashboards, variants, and duplicates, and next to that they should be able to favorite dashboard variants for other SSO users within their suborganization.
    More info under Embedded Dashboard Editor.
    filters
    array[object]
    clause
    string
    Timing of application of the filter. Possible values: where (applied before aggregation/grouping, for example, only select rows with a specific price), having (applied after aggregation/grouping, for example, to select only groups in which the total price exceeds a specific value)
    origin
    string
    This parameter specifies the level to apply the filter. For an initialization filter, this parameter should be set to initialization.
    chart_id
    uuid
    The id of the chart you want to apply the filter to. This chart needs to be contained in the dashboard you specified in the securables parameter.
    expression
    string
    The expression to be used in your filter formula. The possible filter expressions are: ? IN ?, ? IS NOT IN ?, ? = ?, ? != ?, ? > ?, ? >= ?, ? < ?, ? <= ?, IS NULL and IS NOT NULL.
    value
    number, string, boolean, array
    Value to insert in the filter.
    column_id
    string
    (Only needed in case of a non-filter object) The column to apply the filter to
    securable_id
    string
    (Only needed in case of a non-filter object) The dataset to apply the filter to

    Set language or timezone

       You can specify the dashboard language and/or timezone as properties of the Frontend component 
    <luzmo-dashboard
      appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
      apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
      authKey="< SSO authorization key >"
      authToken="< SSO authorization token >"
      dashboardId="< dashboard id you want to embed >"
      language="< Language code, e.g. 'en', 'fr', etc. >"
      timezoneId="< Timezone ID, e.g. 'Europe/Brussels', 'America/New_York', etc. >"
    ></luzmo-dashboard>
    
    <luzmo-dashboard
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< SSO authorization key >'"
      [authToken]="'< SSO authorization token >'"
      [dashboardId]="'< dashboard id you want to embed >'"
      [language]="'< Language code, e.g. 'en', 'fr', etc. >'"
      [timezoneId]="'< Timezone ID, e.g. 'Europe/Brussels', 'America/New_York', etc. >'"
    ></luzmo-dashboard>
    
    import { LuzmoDashboardComponent } from '@luzmo/react-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        return (
          <LuzmoDashboardComponent
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< SSO authorization key >"
            authToken="< SSO authorization token >"
            dashboardId="< dashboard id you want to embed >"
            language="< Language code, e.g. 'en', 'fr', etc. >"
            timezoneId="< Timezone ID, e.g. 'Europe/Brussels', 'America/New_York', etc. >"
          ></LuzmoDashboardComponent>
        );
      }
    
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        return (
          <LuzmoDashboardComponent
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< SSO authorization key >"
            authToken="< SSO authorization token >"
            dashboardId="< dashboard id you want to embed >"
            language="< Language code, e.g. 'en', 'fr', etc. >"
            timezoneId="< Timezone ID, e.g. 'Europe/Brussels', 'America/New_York', etc. >"
          ></LuzmoDashboardComponent>
        );
      }
    
    <template>
      ...
      <luzmo-dashboard
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< SSO authorization key >"
        authToken="< SSO authorization token >"
        dashboardId="< dashboard id you want to embed >"
        language="< Language code, e.g. 'en', 'fr', etc. >"
        timezoneId="< Timezone ID, e.g. 'Europe/Brussels', 'America/New_York', etc. >"
      ></luzmo-dashboard>
    </template>
    
    Parameter Description
    appServer
    string
    Tenancy of Luzmo app to connect to. Defaults to 'https://app.luzmo.com/'.
    For US multi-tenant application, set appServer to 'https://app.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    apiHost
    string
    Tenancy of Luzmo API to connect to. Defaults to 'https://api.luzmo.com/'.
    For US multi-tenant application, set apiHost to 'https://api.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    authKey
    uuid
    The authorization key (i.e. "id") from the response of the authorization request in your backend.
    authToken
    string
    The authorization token from the response of the authorization request in your backend.
    dashboardId
    uuid
    This is the id of the dashboard that you want to embed.
    language
    string
    (Optional) The language code that you wish to use in the dashboard instead of the default language of the dashboard. You can specify 'en', 'cs', 'da', 'de', 'es', 'fi', 'fr', 'he', 'hu', 'it', 'ja', 'ko', 'mk', 'nl', 'pl', 'pt', 'ru', 'sv', 'zh_cn' or 'zh_tw'.
    If that language code is not configured in the dashboard, the default language of that dashboard will be used.

    This Academy Webinar goes into more detail about multi-lingual dashboards.
    timezoneId
    string
    (Optional) The timezone id you wish to use in your dashboard, instead of the default timezone of the dashboard (or SSO token). This timezone id needs to be a valid id that is available in the IANA timezone database, for example: Europe/Brussels or America/New_York.

    More info on timezone support in an (embedded) Luzmo dashboard can be found in this Academy article.

    For all possible frontend component properties, check the Embedding chapter.

    Set loader style

     You can specify the desired loader colors as rgb or rgba values in the relevant properties of the frontend component.
    <luzmo-dashboard
      appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
      apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
      authKey="< SSO authorization key >"
      authToken="< SSO authorization token >"
      dashboardId="< dashboard id you want to embed >"
      loaderBackground="rgb(249, 249, 249)"
      loaderFontColor="rgb(0,0,0)"
      loaderSpinnerColor="rgba(255, 165, 0, 0.7)"
      loaderSpinnerBackground="rgba(169, 169, 169, 0.14)"
    ></luzmo-dashboard>
    
    <luzmo-dashboard
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< SSO authorization key >'"
      [authToken]="'< SSO authorization token >'"
      [dashboardId]="'< dashboard id you want to embed >'"
      [language]="'< Language code, e.g. 'en', 'fr', etc. >'"
      [timezoneId]="'< Timezone ID, e.g. 'Europe/Brussels', 'America/New_York', etc. >'"
      [loaderBackground]="'rgb(249, 249, 249)'"
      [loaderFontColor]="'rgb(0,0,0)'"
      [loaderSpinnerColor]="'rgba(255, 165, 0, 0.7)'"
      [loaderSpinnerBackground]="'rgba(169, 169, 169, 0.14)'"
    ></luzmo-dashboard>
    
    import { LuzmoDashboardComponent } from '@luzmo/react-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        /*
        Clients on our US multi-tenant application environment,
        or a dedicated instance on a specific VPC, should specify:
        - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
        - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
        */
        return (
          <LuzmoDashboardComponent
            ref={ref}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< SSO authorization key >"
            authToken="< SSO authorization token >"
            dashboardId="< dashboard id you want to embed >"
            loaderBackground="rgb(249, 249, 249)"
            loaderFontColor="rgb(0,0,0)"
            loaderSpinnerColor="rgba(255, 165, 0, 0.7)"
            loaderSpinnerBackground="rgba(169, 169, 169, 0.14)"
          ></LuzmoDashboardComponent>
        );
      }
    
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        /*
        Clients on our US multi-tenant application environment,
        or a dedicated instance on a specific VPC, should specify:
        - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
        - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
        */
        return (
          <LuzmoDashboardComponent
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< SSO authorization key >"
            authToken="< SSO authorization token >"
            dashboardId="< dashboard id you want to embed >"
            loaderBackground="rgb(249, 249, 249)"
            loaderFontColor="rgb(0,0,0)"
            loaderSpinnerColor="rgba(255, 165, 0, 0.7)"
            loaderSpinnerBackground="rgba(169, 169, 169, 0.14)"
          ></LuzmoDashboardComponent>
        );
      }
    
    <template>
      ...
    
      <!--
      Clients on our US multi-tenant application environment,
      or a dedicated instance on a specific VPC, should specify:
      - :appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
      - :apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
       -->
      <luzmo-dashboard
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< SSO authorization key >"
        authToken="< SSO authorization token >"
        dashboardId="< dashboard id you want to embed >"
        loaderBackground="rgb(249, 249, 249)"
        loaderFontColor="rgb(0,0,0)"
        loaderSpinnerColor="rgba(255, 165, 0, 0.7)"
        loaderSpinnerBackground="rgba(169, 169, 169, 0.14)"
      ></luzmo-dashboard>
    </template>
    

    When you load a page that has an embedded dashboard or chart, a few resources will need to be retrieved, and access to the dashboard needs to be verified. During this process, a loading indicator is shown.

    This loader can be completely customized to match the styling of your website or platform.
    You can change the color of the background, the color of the font, the color of the spinner itself, and the background of the spinner.

    These colors can be specified in rgb or rgba values. For example: for the color red, the rgb value is rgb(255, 0, 0) and the rgba value is rgba(255, 0, 0, 1).

    Parameter Description
    appServer
    string
    Tenancy of Luzmo app to connect to. Defaults to 'https://app.luzmo.com/'.
    For US multi-tenant application, set appServer to 'https://app.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    apiHost
    string
    Tenancy of Luzmo API to connect to. Defaults to 'https://api.luzmo.com/'.
    For US multi-tenant application, set apiHost to 'https://api.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    authKey
    uuid
    The authorization key (i.e. "id") from the response of the authorization request in your backend.
    authToken
    string
    The authorization token from the response of the authorization request in your backend.
    dashboardId
    uuid
    This is the id of the dashboard that you want to embed.
    loaderBackground
    string
    (optional) The background color of the container while loading the dashboard.
    This property should be specified as a string of rgb or rgba values, e.g. "rgb(50,50,50)", "rgba(50,50,50, 0.5)", etc.
    loaderFontColor
    string
    (optional) The font color of the message(s) while loading the dashboard.
    This property should be specified as a string of rgb or rgba values, e.g. "rgb(50,50,50)", "rgba(50,50,50, 0.5)", etc.
    loaderSpinnerColor
    string
    (optional) The color of the spinner while loading the dashboard.
    This property should be specified as a string of rgb or rgba values, e.g. "rgb(50,50,50)", "rgba(50,50,50, 0.5)", etc.
    loaderSpinnerBackground
    string
    (optional) The background color of the spinner while loading the dashboard.
    This property should be specified as a string of rgb or rgba values, e.g. "rgb(50,50,50)", "rgba(50,50,50, 0.5)", etc.

    Embed a single dashboard item

    <luzmo-dashboard
      appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
      apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
      authKey="< SSO authorization key >"
      authToken="< SSO authorization token >"
      dashboardId="< dashboard id you want to embed >"
      itemId="< an id of a Luzmo item within the dashboard >"
    ></luzmo-dashboard>
    
    <luzmo-dashboard
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< SSO authorization key >'"
      [authToken]="'< SSO authorization token >'"
      [dashboardId]="'< dashboard id you want to embed >'"
      [itemId]="'< an id of a Luzmo item within the dashboard >'"
    ></luzmo-dashboard>
    
    import { LuzmoDashboardComponent } from '@luzmo/react-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        return (
          <LuzmoDashboardComponent
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< SSO authorization key >"
            authToken="< SSO authorization token >"
            dashboardId="< dashboard id you want to embed >"
            itemId="< an id of a Luzmo item within the dashboard >"
          ></LuzmoDashboardComponent>
        );
      }
    
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        return (
          <LuzmoDashboardComponent
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< SSO authorization key >"
            authToken="< SSO authorization token >"
            dashboardId="< dashboard id you want to embed >"
            itemId="< an id of a Luzmo item within the dashboard >"
          ></LuzmoDashboardComponent>
        );
      }
    
    <template>
      ...
      <luzmo-dashboard
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< SSO authorization key >"
        authToken="< SSO authorization token >"
        dashboardId="< dashboard id you want to embed >"
        itemId="< an id of a Luzmo item within the dashboard >"
      ></luzmo-dashboard>
    </template>
    

    It is possible to embed only a certain dashboard item instead of a specific dashboard. Next to specifying a dashboardId or dashboardSlug, you can specify the id of the item within the dashboard in the itemId property of the frontend component. The embedded dashboard item will automatically resize based on the parent container's width and height!

    Parameter Description
    appServer
    string
    Tenancy of Luzmo app to connect to. Defaults to 'https://app.luzmo.com/'.
    For US multi-tenant application, set appServer to 'https://app.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    apiHost
    string
    Tenancy of Luzmo API to connect to. Defaults to 'https://api.luzmo.com/'.
    For US multi-tenant application, set apiHost to 'https://api.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    authKey
    uuid
    The authorization key (i.e. "id") from the response of the authorization request in your backend.
    authToken
    string
    The authorization token from the response of the authorization request in your backend.
    dashboardId
    uuid
    This is the id of the dashboard that you want to embed.
    itemId
    uuid
    (Optional) In case you want to embed a single item of a dashboard, you should specify a dashboardId or dashboardSlug, together with this itemId property set to the id of the item that you want to embed.
    The embedded dashboard item will automatically resize based on the parent container's width and height.

    For all possible parameters, check the Embed documentation.

    Retrieving a dashboard id

    The dashboard id is a unique identifier for that dashboard.

    You can retrieve the id of a dashboard in the 'settings' tab of the dashboard editor, on the right hand side of the screen.
    At the bottom of the tab, you will find the dashboard id.

    Retrieving a dataset id

    The dataset id is a unique identifier for that dataset.

    You can retrieve the id of a dataset in the 'data' tab of the dashboard editor, on the right hand side of the screen.
    At the bottom of the tab, you will find the dataset id.

    Retrieving a column id

    The column id is a unique identifier for that column.

    You can retrieve the id of a dataset column in the dataset preview board by clicking on the gear wheel next to the column name.

    Secondly, you can also retrieve the Column ID from a widget, by hovering over the widget and clicking the table icon that appears next to it. You will now see an overview of all slots (columns) used in this chart. Click the gear icon next to the slot you want to know the id of, and then click the grey info circle.
    At the bottom of the modal, you can find the column ID. Additionally, you can also find the dataset ID here.

    Retrieving a chart id

    The chart id is a unique identifier for that chart.

    You can retrieve the id of a chart by hovering over the chart and clicking the gear icon that appears next to it. By doing this you will enter the item settings.
    At the bottom of the tab, you will find the chart id.

    Retrieving a connection id

    The connection id is a unique identifier for that connection. A connection contains the information that is necessary to access a certain plugin or database.

    You can retrieve the id of an connection in the Connections tab of the side menu.

    Retrieving an integration id

    The integration id is a unique identifier for the integration. You can retrieve the uuid of an integration in the Integrations overview in our UI as shown below.

    Invalidating SSO tokens

       Invalidating a SSO token 
    private Luzmo tempClient = new Luzmo("< SSO key >","< SSO token >", "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    tempClient.delete("authorization", "< SSO key >");
    
       Invalidating a SSO token 
    Luzmo tempclient = new Luzmo("< SSO key >", "< SSO token >");
    
    $tempClient->delete("authorization", "< SSO key >");
    
       Invalidating a SSO token 
    var tempclient = new Luzmo({
        api_key: "< SSO key >",
        api_token: "< SSO token >",
        host: "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >"
      });
    
    let promise = tempClient.delete("authorization", "< SSO key >");
    
       Invalidating a SSO token 
    <?php
    $tempclient = Luzmo::initialize("< SSO key >", "< SSO token >");
    
    $tempClient->delete("authorization", "< SSO key >");
    ?>
    
       Invalidating a SSO token 
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "delete",
      "key": "< SSO key >",
      "token": "< SSO token >",
      "version": "0.1.0",
      "id": "< SSO key >"
    }
    EOF
    
       Invalidating a SSO token 
    from luzmo.luzmo import Luzmo
    
    key = "< SSO key >"
    token = "< SSO token >"
    
    client = Luzmo(key, token)
    
    tempClient.delete("authorization", "< SSO key >",
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    

    A SSO token can only be invalidated by the SSO token itself.

    You can invalidate the SSO authorization tokens that you requested in step 1 at any moment, before their specified expiry time.

    Interacting with data

    Connecting

       In curl, there is no need for an initial authentication. Use your API key & token in every API call. 
       Replace with your API key and token. 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
      api_key: "< your API key >",
      api_token: "< your API token >"
    });
    
       Replace with your API key and token. 
    <?php
    $client = Luzmo::initialize(
      "< your API key >",
      "< your API token >"
    );
    ?>
    
       Replace with your API key and token. 
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >");
    
       Replace with your API key and token. 
    Luzmo client = new Luzmo("< Your API key >", "< Your API token >");
    
       Replace with your API key and token. 
    from luzmo.luzmo import Luzmo
    client = Luzmo("< Your API key >","< Your API token >")
    

    To get started, please make sure you have installed and are using the correct SDK for your preferred programming language. More info on how to connect and the different SDKs available can be found here.

    Retrieving datasets/dashboards

    Retrieving all columns of a particular dataset

       Replace with your API key & token and a valid dataset id. 
    curl https://api.luzmo.com/0.1.0/securable \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "get",
      "version": "0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "find": {
        "where": {
          "id": "< your dataset id >",
          "type": "dataset"
        },
        "include":
          [{
           "model": "Column",
           "attributes": ["name", "type"]
          }],
        "attributes": ["name", "rows", "created_at"]
      }
    }
    EOF
    
       Replace with your API key & token and a valid dataset id. 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
      api_key: "< your API key >",
      api_token: "< your API token >"
    });
    
    let promise = client.get("securable",
      {
        where: {
          id: "< your dataset id >"
          type: "dataset"
        },
        attributes: ["name", "rows", "created_at"],
        include:
          [{
          model: "Column",
          attributes: ["name", "type"]
          }],
      }
    )
      .then(function (data) {
        console.log("Success!", data);
      })
      .catch(function (error) {
        console.error("API error:", error);
      })
    
       Replace with your API key & token and a valid dataset id. 
    <?php
    $client = Luzmo::initialize(
      "< your API key >",
      "< your API token >"
    );
    
    $data = $client->get("securable", array(
      "where" => array(
        "id" => "< your dataset id >",
        "type" => "dataset",
      ),
      "attributes" => array("name", "rows", "created_at"),
      "include" => array(array(
        "model" => "Column",
        "attributes" => array(
          "name",
          "type")
        ))
      )
    );
    
    print_r($data);
    ?>
    
       Replace with your API key & token and a valid dataset id. 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >");
    
    private JSONObject data = client.get("securable", ImmutableMap.of(
        "where", ImmutableMap.of(
          "id", "< your dataset id >"
          "type", "dataset",
        ),
        "attributes", ImmutableList.of("name", "rows", "created_at"),
        "include", ImmutableList.of(
          ImmutableMap.of(
            "model", "Column",
            "attributes", ImmutableList.of("name", "type")
          )
        )
      )
    );
    
    System.out.println(data.toString(2));
    
       Replace with your API key & token and a valid dataset id. 
    Luzmo client = new Luzmo("< Your API key >", "< Your API token >");
    
    filter = new ExpandoObject();
    filter.where = new {
      id = "< your dataset id >",
      type = "dataset"
    };
    filter.attributes = new List<String> {
      "name", "rows", "created_at"
    };
    filter.include = new List<dynamic> {
      new {
        model = "Column",
        attributes = new List<String> {
          "name", "type"
        }
      }
    };
    dynamic data = client.get("securable", filter);
    Console.WriteLine(data);
    
       Replace with your API key & token and a valid dataset id. 
    data = client.get("securable", {
        "where": {
          "type": "dataset",
          "id": "your dataset id"
        },
        "include": [{
          "model": "Column",
          "attributes": ["name", "type"]
        }],
        "attributes": ["name", "rows", "created_at"]
    })
    

    This code example returns the name, number of rows and creation date of a specified dataset. Additionally, it returns the name and datatype of all its associated columns.

    For an overview of all possible parameters of the dataset entity, please refer to the full specification.

    For an overview of all possible parameters of the column entity, please refer to the full specification.

    Parameter Description
    where
    object
    (optional) A condition the entity should fulfill. This condition can be specified on any field of the entity. If this parameter is omitted, no filtering will be applied and all matches will be included in the response. To filter on columns of type date, pass your dates in the yyyy-MM-dd'T'HH:mm:ss.SSS format.
    attributes
    array[string]
    (optional) The attributes of the entity to be included. If this parameter is omitted, all attributes will be included in the response.
    include
    array[object]
    (optional)
    model
    string
    The name of an associated entity to be included. A full list of API entities and its associated entities can be found in the Core API section.
    attributes
    array[string]
    (optional) The attributes of the associated entity to be included in the response. If this parameter is omitted, all attributes will be included in the response.
    where
    object
    (optional) A condition the associated entity should fulfill. This condition can be specified on any field of the entity. If this parameter is omitted, no filtering will be applied and all matches will be included in the response.

    Retrieving a list of all your dashboards

       Replace with your API key & token. 
    curl https://api.luzmo.com/0.1.0/securable \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "get",
      "version": "0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "find": {
        "attributes": ["id", "name", "contents"],
        "include":
          [{
          "model": "Thumbnail",
          "attributes": ["url"],
          "where": {
            "size": "512px"
          }
          }],
        "type": "dashboard"
      }
    }
    EOF
    
       Replace with your API key & token. 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
      api_key: "< your API key >",
      api_token: "< your API token >",
    });
    
    let promise = client
      .get("securable", {
        attributes: ["name", "contents", "id"],
        include: [
          {
            model: "Thumbnail",
            attributes: ["url"],
            where: {
              size: "512px",
            },
          },
        ],
        type: "dashboard",
      })
      .then(function (data) {
        console.log("Success!", data);
      })
      .catch(function (error) {
        console.error("API error:", error);
      });
    
       Replace with your API key & token. 
    <?php
    $client = Luzmo::initialize(
      "< your API key >",
      "< your API token >"
    );
    
    $data = $client->get("securable", array(
      "type" => "dashboard",
      "attributes" => array("name", "contents", "id"),
      "include" => array(array(
        "model" => "Thumbnail",
        "attributes" => array("url"),
        "where" => array(
          "size" => "512px")
        ))
      )
    );
    
    print_r($data);
    ?>
    
       Replace with your API key & token. 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >");
    
    private JSONObject data = client.get("securable", ImmutableMap.of(
        "type", "dashboard",
        "attributes", ImmutableList.of("name", "contents", "id"),
        "include", ImmutableList.of(
          ImmutableMap.of(
            "model", "Thumbnail",
            "attributes", ImmutableList.of("url"),
            "where", ImmutableMap.of(
              "size", "512px"
            )
          )
        )
      )
    );
    
    System.out.println(data.toString(2));
    
       Replace with your API key & token. 
    Luzmo client = new Luzmo("< Your API key >", "< Your API token >");
    
    filter = new ExpandoObject();
    filter.type = "dashboard";
    filter.attributes = new List<String> {
      "name", "contents", "id"
    };
    filter.include = new List<dynamic> {
      new {
        model = "Thumbnail",
        attributes = new List<String> {
          "url"
        },
        where = new {
          size = "512px"
        }
      }
    };
    dynamic data = client.get("securable", filter);
    Console.WriteLine(data);
    

    To retrieve a full list of a certain entity, simply omit the where parameter from your request.

    In this particular example, we will use an API call to return a list of the id's, names and contents of all dashboards in your Luzmo account.

    Additionally, if applicable, for every dashboard the URL of the 512px dashboard thumbnail is added to the returned data.

    This examples shows that you can also use a where specifier in the include parameter.

    For an overview of all possible parameters of the dashboard entity, please refer to the full specification.

    Parameter Description
    type
    string
    The type of securable to be retrieved. Can be dashboard or dataset.
    where
    object
    (optional) A condition the entity should fulfill. This condition can be specified on any field of the entity. If this parameter is omitted, no filtering will be applied and all matches will be included in the response. To filter on columns of type date, pass your dates in the yyyy-MM-dd'T'HH:mm:ss.SSS format.
    attributes
    array[string]
    (optional) The attributes of the entity to be included. If this parameter is omitted, all attributes will be included in the response.
    include
    array[object]
    (optional)
    model
    string
    The name of an associated entity to be included. A full list of API entities and its associated entities can be found in the Core API section.
    attributes
    array[string]
    (optional) The attributes of the associated entity to be included in the response. If this parameter is omitted, all attributes will be included in the response.
    where
    object
    (optional) A condition the associated entity should fulfill. This condition can be specified on any field of the entity. If this parameter is omitted, no filtering will be applied and all matches will be included in the response.

    Creating datasets automatically

       Example of uploading data and creating the dataset + columns on the fly by detecting types from the sample 
    JSONObject data = client.create("data",
    
      ImmutableMap.of(
        "type" , "create",
        "data" , ImmutableList.of(
    
          ImmutableList.of(
            "Chicken baconito ",
            "3",
            "500",
            "menu"
          ),
    
          ImmutableList.of(
            "Quesarito",
            "3.5",
            "700",
            "menu"
          )
        ),
        "options" , ImmutableMap.of(
          "update-metadata" , "true",
          "header" , ImmutableList.of(
            "Burrito",
            "price",
            "weight",
            "order type"
          ),
          "name" , ImmutableMap.of(
            "en" , "Burritos"
          )
        )
      ));
    System.out.println("Success! %s%n", data);
    
       Example of uploading data and creating the dataset + columns on the fly by detecting types from the sample 
    client.create('data',
      {
        type: 'create',
        data: [
            [
                'Chicken baconito ',
                3,
                500,
                'menu'
            ],
            [
                'Quesarito',
                3.5,
                700,
                'menu'
            ]
        ],
        options: {
            'update-metadata': 'true',
            header: [
                'Burrito',
                'price',
                'weight',
                'order type'
            ],
            name: {
                en: 'Burritos'
            }
        }
    }
    
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Example of uploading data and creating the dataset + columns on the fly by detecting types from the sample 
    curl https://api.luzmo.com/0.1.0/data  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "type": "create",
      "data": [
        [
          "Chicken baconito ",
          3,
          500,
          "menu"
        ],
        [
          "Quesarito",
          3.5,
          700,
          "menu"
        ]
      ],
      "options": {
        "update-metadata": "true",
        "header": [
          "Burrito",
          "price",
          "weight",
          "order type"
        ],
        "name": {
          "en": "Burritos"
        }
      }
    }
    }
    EOF
    
    
       Example of uploading data and creating the dataset + columns on the fly by detecting types from the sample 
    <?php
    $data = $client->create('data',
    
      array (
        'type' => 'create',
        'data' => array (
    
          array (
            'Chicken baconito ',
            '3',
            '500',
            'menu'
          ),
    
          array (
            'Quesarito',
            '3.5',
            '700',
            'menu'
          )
        ),
        'options' => array (
          'update-metadata' => 'true',
          'header' => array (
            'Burrito',
            'price',
            'weight',
            'order type'
          ),
          'name' => array (
            'en' => 'Burritos'
          )
        )
      )
    
    );
    print("Success! { $data }");
    ?>
    
       Example of uploading data and creating the dataset + columns on the fly by detecting types from the sample 
    dynamic properties = new ExpandoObject();
    properties.type = "create";
    properties.data = new List<Object> {
    
          new List<Object> {
            "Chicken baconito ",
            "3",
            "500",
            "menu"
          },
    
          new List<Object> {
            "Quesarito",
            "3.5",
            "700",
            "menu"
          }
        };
    properties.options = new {
          update-metadata = "true",
          header = new List<Object> {
            "Burrito",
            "price",
            "weight",
            "order type"
          },
          name = new {
            en = "Burritos"
          }
        };
    
    dynamic data = client.create("data",    properties);
    Console.WriteLine("Success!", data);
    
       Example of uploading data and creating the dataset + columns on the fly by detecting types from the sample 
    data = client.create("data",
    {
        "type": "create",
        "data": [["Chicken baconito ",3,500,"menu"],["Quesarito",3.5,700,"menu"]],
        "options": {
          "update-metadata": "true",
          "header": ["Burrito","price","weight","order type"],
          "name": {
            "en": "Burritos"
          }
        }
    })
    print("Success! ", data)
    

    It is possible in Luzmo to create a dataset programmatically by just sending a sample the 'data' endpoint.

    In order to create it, the sample will be analyzed to determine the types of the different columns. To give names to your dataset and columns there is a header and a name option provided. The code sample on the right will create a new dataset and create 4 columns. To make sure that the types are detected correctly it is advised to send a good sample for the initial creation where each column has at least a few values.

    Behind the scenes, this call is creating a securable and columns. In case you want full control on the creation of securables and columns you can also create them manually by following the Creating datasets manually guide.

    Creating datasets manually

    Creating a new dataset

       This code snippet creates a new dataset: 
    curl https://api.luzmo.com/0.1.0/securable \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "create",
      "version": "0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "properties": {
          "type": "dataset",
          "name": {
            "en": "< dataset name in English >",
            "fr": "< dataset name in French >"
        },
      "description": {
        "en": "< description in English >",
        "fr": "< description in French >"
      }
     }
    }
    EOF
    
       This code snippet creates a new dataset: 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
      api_key: "< your API key >",
      api_token: "< your API token >",
    });
    
    client
      .create("securable", {
        name: {
          en: "< dataset name in English >",
          fr: "< dataset name in French >",
          // optionally add more languages here...
        },
        description: {
          en: "< dataset description in English >",
          fr: "< dataset description in French >",
          // optionally add more languages here...
        },
        type: "dataset",
      })
      .then(function (dataset) {
        console.log("My new dataset id:", dataset.id);
      });
    
       This code snippet creates a new dataset: 
    <?php
    $client = Luzmo::initialize(
      "< your API key >",
      "< your API token >"
    );
    
    $securable = $client->create("securable", array(
      "type" => "dataset",
      "name" => array(
        "en" => "< dataset name in English >",
        "fr" => "< dataset name in French >"
      ),
      "description" => array(
        "en" => "< dataset description in English >",
        "fr" => "< dataset description in French >"
      )
    ));
    ?>
    
       This code snippet creates a new dataset: 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >");
    
    private JSONObject securable = client.create("securable", ImmutableMap.of(
      "type", "dataset",
      "name", ImmutableMap.of(
        "en", "< dataset name in English >",
        "fr", "< dataset name in French >"
      ),
      "description", ImmutableMap.of(
        "en", "< dataset description in English >",
        "fr", "< dataset description in French >"
      )
    ));
    
       This code snippet creates a new dataset: 
    Luzmo client = new Luzmo("< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "dataset";
    properties.name = new {
      en = "< dataset name in English >",
      fr = "< dataset name in French >"
    };
    properties.description = new {
      en = "< dataset description in English >",
      fr = "< dataset description in French >"
    };
    
    dynamic securable = client.create("securable", properties);
    Console.WriteLine("Dataset created with ID " + securable.id);
    

    You can create datasets and their metadata programmatically via the API. In this case, we first build a new Securable (this is a dataset or dashboard).

    The name and description are localized strings: use them to provide translations of dataset or dashboard titles, columns and other metadata. You can retrieve the most recent set languages from the locale entity.

    For an explanation of the dataset entity and its possible parameters, please refer to the full specification.

    Creating a column and immediately linking (associating) it with a dataset

       This code snippet creates a new column within a specified dataset, and immediately associates it with the specified dataset: 
    curl https://api.luzmo.com/0.1.0/column \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "name": {
          "en": "< column name in English >",
          "fr": "< column name in French >"
        },
        "type": "hierarchy",
        "informat": "hierarchy",
        "order": 0,
        "color": "#45DE25"
      },
      "associations": [{
        "role": "Securable",
        "id": "< your dataset id >"
      }]
    }
    EOF
    
       This code snippet creates a new column within a specified dataset, and immediately associates it with the specified dataset: 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
      api_key: "< your API key >",
      api_token: "< your API token >"
    });
    
    client.create("column",
     {
       name: {
         en: "< column name in English >",
         fr: "< column name in French >"
       },
       type: "hierarchy",
       informat: "hierarchy",
       order: 0,
       color: "#45DE25"
     },
     [{
       role: "Securable",
       id: "< your dataset id >"
     }]
    )
     .then(...);
    
       This code snippet creates a new column within a specified dataset, and immediately associates it with the specified dataset: 
    <?php
    $client = Luzmo::initialize(
      "< your API key >",
      "< your API token >"
    );
    
    $column = $client->create("column", array(
      "name" => array(
        "en" => "< column name in English >",
        "fr" => "< column name in French >"
      ),
      "type" => "hierarchy",
      "informat" => "hierarchy",
      "order" => 0,
      "color" => "#45DE25"),
      array(
        array(
        "role" => "Securable",
        "id" => "< your dataset id >"
        )
      )
    );
    ?>
    
       This code snippet creates a new column within a specified dataset, and immediately associates it with the specified dataset: 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >");
    
    private JSONObject column = client.create("column", ImmutableMap.of(
      "name", ImmutableMap.of(
        "en", "< column name in English >",
        "fr", "< column name in French >"
      ),
      "type", "hierarchy",
      "informat", "hierarchy",
      "order", 0,
      "color", "#45DE25",
      ImmutableList.of(
        ImmutableMap.of(
          "role", "Securable",
          "id", "< your dataset id >"
        )
      )
    )
    );
    
       This code snippet creates a new column within a specified dataset, and immediately associates it with the specified dataset: 
    Luzmo client = new Luzmo("< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.name = new {
      en = "< column name in English >",
      fr = "< column name in French >"
    };
    properties.type = "hierarchy";
    properties.informat = "hierarchy";
    properties.order = 0;
    properties.color = "#45DE25";
    
    associations = new List<ExpandoObject>();
    dynamic association = new ExpandoObject();
    association.role = "Securable";
    association.id = "< your dataset id >"
    associations.Add(association);
    
    dynamic column = client.create("column", properties, associations);
    Console.WriteLine("Column created with ID " + column.id + " and associated.");
    

    After you have created a dataset, it is possible to create a new column and associate it to your dataset.

    For an explanation of the column entity and its possible parameters, please refer to the full specification.

    Linking (associating) a dataset and a column in a seperate call

       This code snippet associates the specified column with a specified dataset. 
    curl https://api.luzmo.com/0.1.0/column \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "associate",
      "version": "0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "id": "< your column id >",
      "resource": {
        "role": "Securable",
        "id": "< your dataset id >"
      }
    }
    EOF
    
       This code snippet associates the specified column with a specified dataset. 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
      api_key: "< your API key >",
      api_token: "< your API token >",
    });
    
    client.associate("securable", "< your dataset id >", {
      role: "Columns",
      id: "< your column id >",
    });
    
       This code snippet associates the specified column with a specified dataset. 
    <?php
    $client = Luzmo::initialize(
      "< your API key >",
      "< your API token >"
    );
    
    $securable = $client->associate(
      "securable",
      "< your dataset id >",
      "Columns",
      "< your column id >");
    ?>
    
       This code snippet associates the specified column with a specified dataset. 
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >");
    
    client.associate("column", "< your column id >", "securable", "< your dataset id >");
    
       This code snippet associates the specified column with a specified dataset. 
    Luzmo client = new Luzmo("< Your API key >", "< Your API token >");
    
    client.associate("column", "< your column id >", "securable", "< your dataset id >", new ExpandoObject());
    

    Alternatively, you could explicitly associate both new entities at a later time.

    You can do this by using the associate action on the Column entity, and specifying an instance of a Securable entity as the resource parameter.

    Pushing data

       Example of appending data to an existing dataset 
    JSONObject data = client.create("data",
    
      ImmutableMap.of(
        "securable_id" , "< Your securable id >",
        "type" , "append",
        "data" , ImmutableList.of(
    
          ImmutableList.of(
            "Fresh new burrito ",
            "3",
            "500",
            "menu"
          ),
    
          ImmutableList.of(
            "Guacarrito",
            "3.5",
            "700",
            "menu"
          )
        )
      ));
    System.out.println("Success! %s%n", data);
    
       Example of appending data to an existing dataset 
    client.create('data',
      {
        securable_id: '< Your securable id >',
        type: 'append',
        data: [
            [
                'Fresh new burrito ',
                3,
                500,
                'menu'
            ],
            [
                'Guacarrito',
                3.5,
                700,
                'menu'
            ]
        ]
    }
    
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Example of appending data to an existing dataset 
    curl https://api.luzmo.com/0.1.0/data  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "securable_id": "< Your securable id >",
      "type": "append",
      "data": [
        [
          "Fresh new burrito ",
          3,
          500,
          "menu"
        ],
        [
          "Guacarrito",
          3.5,
          700,
          "menu"
        ]
      ]
    }
    }
    EOF
    
    
       Example of appending data to an existing dataset 
    <?php
    $data = $client->create('data',
    
      array (
        'securable_id' => '< Your securable id >',
        'type' => 'append',
        'data' => array (
    
          array (
            'Fresh new burrito ',
            '3',
            '500',
            'menu'
          ),
    
          array (
            'Guacarrito',
            '3.5',
            '700',
            'menu'
          )
        )
      )
    
    );
    print("Success! { $data }");
    ?>
    
       Example of appending data to an existing dataset 
    dynamic properties = new ExpandoObject();
    properties.securable_id = "< Your securable id >";
    properties.type = "append";
    properties.data = new List<Object> {
    
          new List<Object> {
            "Fresh new burrito ",
            "3",
            "500",
            "menu"
          },
    
          new List<Object> {
            "Guacarrito",
            "3.5",
            "700",
            "menu"
          }
        };
    
    dynamic data = client.create("data",    properties);
    Console.WriteLine("Success!", data);
    
       Example of appending data to an existing dataset 
    data = client.create("data",
    {
        "securable_id": "< Your securable id >",
        "type": "append",
        "data": [["Fresh new burrito ",3,500,"menu"],["Guacarrito",3.5,700,"menu"]]
    })
    print("Success! ", data)
    
       Example of replacing data in an existing dataset. The columns will remain the same but the data will be completely replaced. 
    JSONObject data = client.create("data",
    
      ImmutableMap.of(
        "securable_id" , "< Your securable id >",
        "type" , "replace",
        "data" , ImmutableList.of(
    
          ImmutableList.of(
            "New collection Guacarrito",
            "3",
            "500",
            "menu"
          ),
    
          ImmutableList.of(
            "New collection Quasarito",
            "3.5",
            "700",
            "menu"
          )
        )
      ));
    System.out.println("Success! %s%n", data);
    
       Example of replacing data in an existing dataset. The columns will remain the same but the data will be completely replaced. 
    client.create('data',
      {
        securable_id: '< Your securable id >',
        type: 'replace',
        data: [
            [
                'New collection Guacarrito',
                3,
                500,
                'menu'
            ],
            [
                'New collection Quasarito',
                3.5,
                700,
                'menu'
            ]
        ]
    }
    
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Example of replacing data in an existing dataset. The columns will remain the same but the data will be completely replaced. 
    curl https://api.luzmo.com/0.1.0/data  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "securable_id": "< Your securable id >",
      "type": "replace",
      "data": [
        [
          "New collection Guacarrito",
          3,
          500,
          "menu"
        ],
        [
          "New collection Quasarito",
          3.5,
          700,
          "menu"
        ]
      ]
    }
    }
    EOF
    
    
       Example of replacing data in an existing dataset. The columns will remain the same but the data will be completely replaced. 
    <?php
    $data = $client->create('data',
    
      array (
        'securable_id' => '< Your securable id >',
        'type' => 'replace',
        'data' => array (
    
          array (
            'New collection Guacarrito',
            '3',
            '500',
            'menu'
          ),
    
          array (
            'New collection Quasarito',
            '3.5',
            '700',
            'menu'
          )
        )
      )
    
    );
    print("Success! { $data }");
    ?>
    
       Example of replacing data in an existing dataset. The columns will remain the same but the data will be completely replaced. 
    dynamic properties = new ExpandoObject();
    properties.securable_id = "< Your securable id >";
    properties.type = "replace";
    properties.data = new List<Object> {
    
          new List<Object> {
            "New collection Guacarrito",
            "3",
            "500",
            "menu"
          },
    
          new List<Object> {
            "New collection Quasarito",
            "3.5",
            "700",
            "menu"
          }
        };
    
    dynamic data = client.create("data",    properties);
    Console.WriteLine("Success!", data);
    
       Example of replacing data in an existing dataset. The columns will remain the same but the data will be completely replaced. 
    data = client.create("data",
    {
        "securable_id": "< Your securable id >",
        "type": "replace",
        "data": [["New collection Guacarrito",3,500,"menu"],["New collection Quasarito",3.5,700,"menu"]]
    })
    print("Success! ", data)
    
       Append data to a dataset by using 'update_metadata: true' with a header with a different set of columns. Given that there are  4 columns (Burrito, price, weight, order type), this call would introduce a new column 'newColumn' and remove weight and order type. Careful. This will delete the data from these two columns. You can also opt to update the name fo the dataset 
    JSONObject data = client.create("data",
    
      ImmutableMap.of(
        "securable_id" , "< Your securable id >",
        "type" , "append",
        "data" , ImmutableList.of(
    
          ImmutableList.of(
            "Fresh new burrito ",
            "3",
            "500",
            "menu",
            "newColumndata"
          ),
    
          ImmutableList.of(
            "Guacarrito",
            "3.5",
            "700",
            "menu",
            "newColumndata"
          )
        ),
        "options" , ImmutableMap.of(
          "update_metadata" , true,
          "header" , ImmutableList.of(
            "Burrito",
            "price",
            "weight",
            "order type",
            "newColumn"
          ),
          "name" , ImmutableMap.of(
            "en" , "Updated Burritos Name"
          )
        )
      ));
    System.out.println("Success! %s%n", data);
    
       Append data to a dataset by using 'update_metadata: true' with a header with a different set of columns. Given that there are  4 columns (Burrito, price, weight, order type), this call would introduce a new column 'newColumn' and remove weight and order type. Careful. This will delete the data from these two columns. You can also opt to update the name fo the dataset 
    client.create('data',
      {
        securable_id: '< Your securable id >',
        type: 'append',
        data: [
            [
                'Fresh new burrito ',
                3,
                500,
                'menu',
                'newColumnData'
            ],
            [
                'Guacarrito',
                3.5,
                700,
                'menu',
                'newColumnData'
            ]
        ],
        options: {
            update_metadata: true,
            header: [
                'Burrito',
                'price',
                'weight',
                'order type',
                'newColumn'
            ],
            name: {
                en: 'Updated Burritos Name'
            }
        }
    }
    
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Append data to a dataset by using 'update_metadata: true' with a header with a different set of columns. Given that there are  4 columns (Burrito, price, weight, order type), this call would introduce a new column 'newColumn' and remove weight and order type. Careful. This will delete the data from these two columns. You can also opt to update the name fo the dataset 
    curl https://api.luzmo.com/0.1.0/data  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "securable_id": "< Your securable id >",
      "type": "append",
      "data": [
        [
          "Fresh new burrito ",
          3,
          500,
          "menu",
          "newColumndata"
        ],
        [
          "Guacarrito",
          3.5,
          700,
          "menu",
          "newColumndata"
        ]
      ],
      "options": {
        "update_metadata": true,
        "header": [
          "Burrito",
          "price",
          "weight",
          "order type",
          "newColumn"
        ],
        "name": {
          "en": "Updated Burritos Name"
        }
      }
    }
    }
    EOF
    
    
       Append data to a dataset by using 'update_metadata: true' with a header with a different set of columns. Given that there are  4 columns (Burrito, price, weight, order type), this call would introduce a new column 'newColumn' and remove weight and order type. Careful. This will delete the data from these two columns. You can also opt to update the name fo the dataset 
    <?php
    $data = $client->create('data',
    
      array (
        'securable_id' => '< Your securable id >',
        'type' => 'append',
        'data' => array (
    
          array (
            'Fresh new burrito ',
            '3',
            '500',
            'menu',
            'newColumnData'
          ),
    
          array (
            'Guacarrito',
            '3.5',
            '700',
            'menu',
            'newColumnData'
          )
        ),
        'options' => array (
          'update_metadata' => true,
          'header' => array (
            'Burrito',
            'price',
            'weight',
            'order type',
            'newColumn'
          ),
          'name' => array (
            'en' => 'Updated Burritos Name'
          )
        )
      )
    
    );
    print("Success! { $data }");
    ?>
    
       Append data to a dataset by using 'update_metadata: true' with a header with a different set of columns. Given that there are  4 columns (Burrito, price, weight, order type), this call would introduce a new column 'newColumn' and remove weight and order type. Careful. This will delete the data from these two columns. You can also opt to update the name fo the dataset 
    dynamic properties = new ExpandoObject();
    properties.securable_id = "< Your securable id >";
    properties.type = "append";
    properties.data = new List<Object> {
    
          new List<Object> {
            "Fresh new burrito ",
            "3",
            "500",
            "menu",
            "newColumndata"
          },
    
          new List<Object> {
            "Guacarrito",
            "3.5",
            "700",
            "menu",
            "newColumndata"
          }
        };
    properties.options = new {
          update_metadata = true,
          header = new List<Object> {
            "Burrito",
            "price",
            "weight",
            "order type",
            "newColumn"
          },
          name = new {
            en = "Updated Burritos Name"
          }
        };
    
    dynamic data = client.create("data",    properties);
    Console.WriteLine("Success!", data);
    
       Append data to a dataset by using 'update_metadata: true' with a header with a different set of columns. Given that there are  4 columns (Burrito, price, weight, order type), this call would introduce a new column 'newColumn' and remove weight and order type. Careful. This will delete the data from these two columns. You can also opt to update the name fo the dataset 
    data = client.create("data",
    {
        "securable_id": "< Your securable id >",
        "type": "append",
        "data": [["Fresh new burrito ",3,500,"menu","newColumndata"],["Guacarrito",3.5,700,"menu","newColumndata"]],
        "options": {
          "update_metadata": True,
          "header": ["Burrito","price","weight","order type","newColumn"],
          "name": {
            "en": "Updated Burritos Name"
          }
        }
    })
    print("Success! ", data)
    

    Regardless of how you created the dataset and columns (manually or automatically) you can append or replace the data by providing the securable_id and setting the type to 'append' or 'replace' as shown in the second and third example on the right. As long as the update_metadata boolean is disabled, this will never change anything to your columns. Setting the type to replace will replace the data in the dataset. Every row in your data parameter should have exactly the same amount of entries as there are columns in your dataset. For more information on how to find the id of a dataset, please refer to this section.

    When pushing data, the dashboards that are viewing this data will be automatically brought up to date.

    In case you want to automatically add/remove/update columns (use this with care), you can set the 'update_metadata' boolean to true. For example, in the third example on the right, two columns are removed and a new column is added.

    Querying data

    Simple example

       Replace with your own API key & token, a valid dataset id and valid column id's. 
    curl https://api.luzmo.com/0.1.0/data \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "get",
      "version": "0.1.0",
      "key":  "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "find": {
        "dimensions": [{
          "column_id": "Type of burrito column id",
          "dataset_id": "< your dataset id >"
        }],
        "measures": [{
          "column_id": "Number burritos savoured column id",
          "dataset_id": "< your dataset id >"
        }]
      }
    }
    EOF
    
       Replace with your own API key & token, a valid dataset id and valid column id's. 
    client
      .query({
        dimensions: [
          {
            column_id: "Type of burrito column id",
            dataset_id: "< your dataset id >",
          },
        ],
        measures: [
          {
            column_id: "Number burritos savoured column id",
            dataset_id: "< your dataset id >",
          },
        ],
      })
      .then(function (data) {
        console.log("Result set: ", data.data);
        // Prints: [["spicy", 1256],
        //          ["sweet",  913]]
      });
    
       Replace with your own API key & token, a valid dataset id and valid column id's. 
    <?php
    $client = Luzmo::initialize(
      "< your API key >",
      "< your API token >"
    );
    
    $data = $client->query(
      array(
        "dimensions" => array(array(
          "column_id" => "Type of burrito column id",
          "dataset_id" => "< your dataset id >"
        )),
        "measures" => array(array(
          "column_id" => "Number burritos savoured column id",
          "dataset_id" => "< your dataset id >"
        ))
      )
    );
    
    print_r($data);
    // Prints: [["spicy", 1256],
    //          ["sweet",  913]]
    ?>
    
       Replace with your own API key & token, a valid dataset id and valid column id's. 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >", "< Your API token >");
    
    private JSONObject data = client.query(
      ImmutableMap.of(
        "dimensions", ImmutableList.of(
          ImmutableMap.of(
            "column_id", "Type of burrito column id",
            "dataset_id", "< your dataset id >"
          )
        ),
        "measures", ImmutableList.of(
          ImmutableMap.of(
            "column_id", "Number of burritos savoured column id",
            "dataset_id", "< your dataset id >"
          )
        )
      )
    );
    
    System.out.println(data.toString(2));
    // Prints: [["spicy", 1256],
    //          ["sweet",  913]]
    
       Replace with your own API key & token, a valid dataset id and valid column id's. 
    Luzmo client = new Luzmo("< Your API key >", "< Your API token >");
    
    query = new ExpandoObject();
    query.type = "dashboard";
    query.dimensions = new List<dynamic> {
      new {
        column_id = "Type of burrito column id",
        dataset_id = "< your dataset id >"
      }
    };
    query.measures = new List<dynamic> {
      new {
        column_id = "Number burritos savoured column id",
        dataset_id = "< your dataset id >"
      }
    };
    
    dynamic data = client.query(query);
    Console.WriteLine(data);
    // Prints: [["spicy", 1256],
    //          ["sweet",  913]]
    

    Just like the charts on your dashboards request data in real-time, you can interrogate your data within the platform as well.

    For example, to retrieve the total number of burritos savoured per type of burrito.

    Advanced example

       Replace with your own API key & token, a valid dataset id and valid column id's. 
    curl https://api.luzmo.com/0.1.0/data \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "get",
      "version": "0.1.0",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "find": {
        "dimensions": [{
          "column_id": "Burrito weight column id",
          "dataset_id": "< your dataset id >",
          "discretization": {
            "type": "linear",
            "bins": "10"
          }
        }],
        "measures": [{
          "column_id": "Number burritos savoured column id",
          "dataset_id": "< your dataset id >",
          "aggregation": {
            "type": "sum"
          }
        }],
        "where": [{
          "expression": "? = ?",
          "parameters": [{
            "column_id": "Type of burrito column id",
            "dataset_id": "< your dataset id >"
          },
          "spicy"
          ]
        }],
        "order": [{
          "column_id": "Number burritos savoured column id",
          "dataset_id": "< your dataset id >",
          "aggregation": {
            "type": "sum"
          },
          "order": "desc"
        }],
        "limit": {
          "by": 5
        }
      }
    }
    EOF
    
       Replace with your own API key & token, a valid dataset id and valid column id's. 
    client
      .query({
        dimensions: [
          {
            column_id: "Burrito weight column id",
            dataset_id: "< your dataset id >",
            discretization: {
              type: "linear",
              bins: 10,
            },
          },
        ],
        measures: [
          {
            column_id: "Number burritos savoured column id",
            dataset_id: "< your dataset id >",
            aggregation: {
              type: "sum",
            },
          },
        ],
        where: [
          {
            expression: "? = ?",
            parameters: [
              {
                column_id: "Type of burrito column id",
                dataset_id: "< your dataset id >",
              },
              "spicy",
            ],
          },
        ],
        order: [
          {
            column_id: "Number burritos savoured column id",
            dataset_id: "< your dataset id >",
            aggregation: {
              type: "sum",
            },
            order: "desc",
          },
        ],
        limit: {
          by: 5,
        },
      })
      .then(function (data) {
        console.log("Result set:", data.data);
        // Prints: [["[ 100 - 150 [", 125],
        //            ["[ 150 - 200 [", 121]]
      });
    
       Replace with your own API key & token, a valid dataset id and valid column id's. 
    <?php
    $client = Luzmo::initialize(
      "< your API key >",
      "< your API token >"
    );
    
    $data = $client->query(
      array(
        "dimensions" => array(
          array(
            "column_id" => "Burrito weight id column id",
            "dataset_id" => "< your dataset id >",
            "discretization" => array(
              "type" => "linear",
              "bins" => 10
            )
          )
        ),
        "measures" => array(
          array(
            "column_id" => "Number burritos savoured column id",
            "dataset_id" => "< your dataset id >",
            "aggregation" => array(
              "type" => "sum"
            )
          )
        ),
        "where" => array(
          array(
            "expression" => "? = ?",
            "parameters" => array(
              array(
                "column_id" => "Type of burrito column id",
                "dataset_id" => "< your dataset id >"
              ),
            "spicy"
            )
          )
        ),
        "order" => array(
          array(
            "column_id" => "Number burritos savoured column id",
            "dataset_id" => "< your dataset id >",
            "order" => "desc",
            "aggregation" => array(
              "type" => "sum"
            )
          )
        ),
        "limit" => array(
          "by" => 5
        )
      )
    );
    
    print_r($data);
    // Prints: [["[ 100 - 150 [", 125],
    //            ["[ 150 - 200 [", 121]]
    ?>
    
       Replace with your own API key & token, a valid dataset id and valid column id's. 
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >");
    
    private JSONObject data = client.query(
      ImmutableMap.of(
        "dimensions", ImmutableList.of(
          ImmutableMap.of(
            "column_id", "Burrito weight id column id",
            "dataset_id", "< your dataset id >",
            "discretization", ImmutableMap.of(
              "type", "linear",
              "bins", 10
            )
          )
        ),
        "measures", ImmutableList.of(
          ImmutableMap.of(
            "column_id", "Number of burritos savoured column id",
            "dataset_id", "< your dataset id >",
            "aggregation" = new {
              "type"= "sum"
            }
          )
        ),
        "where", ImmutableList.of(
          ImmutableMap.of(
            "expression", "? = ?",
            "parameters", ImmutableList.of(
              ImmutableMap.of(
                "column_id", "Type of burrito column id",
                "dataset_id", "< your dataset id >"
              ),
              "spicy"
            )
          )
        ),
        "order", ImmutableList.of(
          ImmutableMap.of(
            "column_id", "Number of burritos savoured column id",
            "dataset_id", "< your dataset id >",
            "aggregation" = new {
              "type"= "sum"
            },
            "order", "desc"
          )
        ),
        "limit", ImmutableMap.of(
          "by", 5
        )
      )
    );
    
    System.out.println(data.toString(2));
    // Prints: [["[ 100 - 150 [", 125],
    //          ["[ 150 - 200 [", 121]]
    
       Replace with your own API key & token, a valid dataset id and valid column id's. 
    Luzmo client = new Luzmo("< Your API key >", "< Your API token >");
    
    query = new ExpandoObject();
    query.type = "dashboard";
    query.dimensions = new List<dynamic> {
      new {
        column_id = "Burrito weight column id",
        dataset_id = "< your dataset id >",
        discretization = new {
          type = "linear",
          bins = 10
        }
      }
    };
    query.measures = new List<dynamic> {
      new {
        column_id = "Number burritos savoured column id",
        dataset_id = "< your dataset id >"
      }
    };
    query.where = new List<dynamic> {
      new {
        expression = "? = ?",
        parameters = new List<dynamic> {
          new {
            column_id = "Type of burrito column id",
            dataset_id = "< your dataset id >"
          },
          "spicy"
        }
      }
    }
    query.order = new List<dynamic> {
      new {
        column_id = "Number burritos savoured column id",
        dataset_id = "< your dataset id >",
        order = "desc"
      }
    }
    query.limit = new {
      by = 5
    }
    
    dynamic data = client.query(query);
    Console.WriteLine(data);
    // Prints: [["[ 100 - 150 [", 125],
    //          ["[ 150 - 200 [", 121]]
    

    A more elaborate example: let’s record the weight per burrito as another numeric measure.

    We want the weights to be classified in 10 equal sized bins, for example [50, 100[ grams, [100, 150[ grams. These bins will be made by equally dividing the range between the minimum and maximum values in the column specified.

    Now we want to retrieve the top 5 weight classes by number of burritos savoured, but only for burritos that are of the type ‘spicy’.

    External data changes

       This code snippet notifies Luzmo that a dataset has changed via an external source: 
    curl https://api.luzmo.com/0.1.0/data \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "update",
      "version": "0.1.0",
      "key":"$LUZMO_API_KEY",
      "token":"$LUZMO_API_TOKEN",
      "id": "< your dataset id >"
    }
    EOF
    
       This code snippet notifies Luzmo that a dataset has changed via an external source: 
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
      api_key: "< your API key >",
      api_token: "< your API token >",
    });
    
    client.update("data", "< your dataset id >");
    
       This code snippet notifies Luzmo that a dataset has changed via an external source: 
    <?php
    $client = Luzmo::initialize(
      "< your API key >",
      "< your API token >"
    );
    
    $client->update("data", "< your dataset id >", array());
    ?>
    
       This code snippet notifies Luzmo that a dataset has changed via an external source: 
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >");
    
    client.update("data", "< your dataset id >", ImmutableMap.of()));
    
       This code snippet notifies Luzmo that a dataset has changed via an external source: 
    Luzmo client = new Luzmo("< Your API key >", "< Your API token >");
    
    client.update("data", "< your dataset id >", new ExpandoObject());
    

    When you push data points into a dataset that is stored in Luzmo, all dashboards are brought up-to-date immediately. To also have real-time updates to dashboards that use data providers like relational databases, you can notify Luzmo when data changes via the Update action on the Data entity.

    For example, you can do this call from within your RDBMS with a trigger on update, eg. via curl.

    Core API

    Introduction

    This document describes the Core API which is also used by the Luzmo application. As a client, you have access to the same API that we used to build Luzmo. That means that you can automate everything:

    The Core API uses REST with default HTTP verbs and JSON Content.

    Connect

    The API is available via WebSocket or via REST. We provide several client libraries for different languages.

    Token

    In order to send requests to our API, you will first need to create an API key and API token. You can get these here. Your API key and token should always be stored securely and stay private: this token pair should be considered your username and password to Luzmo!
    There are multiple types of tokens; for more information about each token or how to create them programmatically, refer to the Authorization Resource.

    SDKs

       Connect to the REST API 
    var Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
      api_key: '< your API key >',
      api_token: '< your API token >',
      host: '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >'
    });
    
       Connect to the REST API 
    Luzmo client = new Luzmo(
      "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
      "< your API key >",
      "< your API token >"
    );
    
       Connect to the REST API 
    <?php
    $client = Luzmo::initialize(
      '< your API key >',
      '< your API token >',
      '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >'
    );
    ?>
    
       Connect to the REST API 
    export $LUZMO_API_KEY="your-api-key"
    export $LUZMO_API_TOKEN="your-api-token"
    
    curl https://api.luzmo.com/0.1.0/<entity>  -H "Content-Type: application/json" -d @- << EOF
    {
     "action": "<your-action>",
     "key": "$LUZMO_API_KEY",
     "token": "$LUZMO_API_TOKEN",
     "version": "0.1.0",
     ...
    }
    EOF
    
    or
    
    curl https://api.us.luzmo.com/0.1.0/<entity>  -H "Content-Type: application/json" -d @- << EOF
    {
     "action": "<your-action>",
     "key": "$LUZMO_API_KEY",
     "token": "$LUZMO_API_TOKEN",
     "version": "0.1.0",
     ...
    }
    EOF
    
       Connect to the REST API 
    export $LUZMO_API_KEY="your-api-key"
    export $LUZMO_API_TOKEN="your-api-token"
    
    curl https://api.luzmo.com/0.1.0/<entity>  -H "Content-Type: application/json" -d @- << EOF
    {
     "action": "<your-action>",
     "key": "$LUZMO_API_KEY",
     "token": "$LUZMO_API_TOKEN",
     "version": "0.1.0",
     ...
    }
    EOF
    
    or
    
    curl https://api.us.luzmo.com/0.1.0/<entity>  -H "Content-Type: application/json" -d @- << EOF
    {
     "action": "<your-action>",
     "key": "$LUZMO_API_KEY",
     "token": "$LUZMO_API_TOKEN",
     "version": "0.1.0",
     ...
    }
    EOF
    
       Connect to the REST API 
    Luzmo client = new Luzmo("< Your API key >","< Your API token >",
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
       Connect to the REST API 
    from luzmo.luzmo import Luzmo
    client = Luzmo("< Your API key >","< Your API token >",
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    

    The libraries below are built around the REST API. The code and installation instructions for each language can be found in the respective README file:

    Node.js
    Java
    C#
    Python

    These libraries require a connection step where you provide the api key and token to get started. Sometimes the token has to be one for a specific user. For example binding a locale to a User requires you to be owner of that user. You can take ownership by using the login/api token of that specific user.

    You can also access our API without a library using pure rest calls in which case you have to pass the api key and token on each call. For pure REST examples you can refer to the curl examples.

    Schema

    Below you can see the resources that can be accessed/created/updated/deleted via the API and how they are connected to each other: %3 <!-- Dashboard --> Dashboard Dashboard <!-- Securable --> Securable Securable <!-- Dashboard->Securable --> Dashboard->Securable <!-- Dataset --> Dataset Dataset <!-- Dataset->Securable --> Dataset->Securable <!-- Account --> Account Account <!-- User --> User User <!-- User->Account --> User->Account <!-- Authorization --> Authorization Authorization <!-- User->Authorization --> User->Authorization <!-- Locale --> Locale Locale <!-- User->Locale --> User->Locale <!-- User->Securable --> User->Securable <!-- Country --> Country Country <!-- User->Country --> User->Country <!-- Organization --> Organization Organization <!-- User->Organization --> User->Organization <!-- Thumbnail --> Thumbnail Thumbnail <!-- User->Thumbnail --> User->Thumbnail <!-- Share --> Share Share <!-- User->Share --> User->Share <!-- Group --> Group Group <!-- User->Group --> User->Group <!-- Schedule --> Schedule Schedule <!-- User->Schedule --> User->Schedule <!-- Plugin --> Plugin Plugin <!-- User->Plugin --> User->Plugin <!-- Locale->Authorization --> Locale->Authorization <!-- Theme --> Theme Theme <!-- Theme->Authorization --> Theme->Authorization <!-- Theme->Organization --> Theme->Organization <!-- Column --> Column Column <!-- Column->Column --> Column->Column <!-- Securable->Column --> Securable->Column <!-- Securable->Securable --> Securable->Securable <!-- HierarchyLevel --> HierarchyLevel HierarchyLevel <!-- HierarchyLevel->Column --> HierarchyLevel->Column <!-- Organization->Locale --> Organization->Locale <!-- Organization->Country --> Organization->Country <!-- Thumbnail->Securable --> Thumbnail->Securable <!-- Thumbnail->Organization --> Thumbnail->Organization <!-- Thumbnail->Plugin --> Thumbnail->Plugin <!-- Tag --> Tag Tag <!-- Tag->Securable --> Tag->Securable <!-- Share->Locale --> Share->Locale <!-- Share->Securable --> Share->Securable <!-- Group->Securable --> Group->Securable <!-- Schedule->Securable --> Schedule->Securable <!-- Plugin->Securable --> Plugin->Securable <!-- Plugin->Organization --> Plugin->Organization

    The graph shows which resources can be associated/dissociated. When resources are associated, you can include the associated resource in a get or query request.

    Actions

    The core API defines actions that can be called on the resources. The api call of a specific action is standardized which means that you access each resource in a similar way. In total, 6 types of actions are defined:

    Create
    Get
    List
    Update
    Delete
    Associate
    Dissociate

    Not every action is supported on every resource (e.g. you can not delete a Dataprovider). The rest of this documentation will provide information on the call signature for each action and will then go into details with concrete examples for each combination of resource and action.

    Create

       Create general Signature 
    JSONObject < resource name > = client.create("< resource name >",
    
      ImmutableMap.of(
        "attribute name" , "<attribute value>"
      ),
      ImmutableList.of(
    
        ImmutableMap.of(
          "role" , "<resource to link name>",
          "id" , "<resource entity id>"
        ),
    
        ImmutableMap.of(
          "role" , "<resource to link name>",
          "id" , "<resource entity id>"
        )
      ));
    System.out.println("Success! %s%n", < resource name >);
    
       Create general Signature 
    dynamic properties = new ExpandoObject();
    properties.attribute name = "<attribute value>";
    
    dynamic < resource name > = client.create("< resource name >",    properties);
    Console.WriteLine("Success!", < resource name >);
    
       Create general Signature 
    client.create('< resource name >',
      {
        'attribute name': '<attribute value>'
    },
      [ {
        role: '<resource to link name>',
        id: '<resource entity id>'
    },{
        role: '<resource to link name>',
        id: '<resource entity id>'
    } ]
    )
      .then(function(< resource name >) {
        console.log('Success!', < resource name >);
      });
    
       Create general Signature 
    <?php
    $< resource name > = $client->create('< resource name >',
    
      array (
        'attribute name' => '<attribute value>'
      ),
    
      array (
    
        array (
          'role' => '<resource to link name>',
          'id' => '<resource entity id>'
        ),
    
        array (
          'role' => '<resource to link name>',
          'id' => '<resource entity id>'
        )
      )
    );
    print("Success! { $< resource name > }");
    ?>
    
       Create general Signature 
    curl https://api.luzmo.com/0.1.0/< resource name > \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "attribute name": "<attribute value>"
    },
      "associations": [
      {
        "role": "<resource to link name>",
        "id": "<resource entity id>"
      },
      {
        "role": "<resource to link name>",
        "id": "<resource entity id>"
      }
    ]
    }
    EOF
    
    
       Create general Signature 
    resource_name = client.create("resource_name",
    {
        "attribute name": "<attribute value>"
    },[{
        "role": "<resource to link name>",
        "id": "<resource entity id>"
    },{
        "role": "<resource to link name>",
        "id": "<resource entity id>"
    }])
    print("Success! ", resource_name)
    

    Create a new instance of the requested resource type, for example: create a new User within an Organization, create a new access group, create new data rows, …

    Parameter
    Description
    resource:
    string
    The lowercase name of the resource we want to create
    properties:
    object
    Here you provide the properties of the entity you want to create in the form of a map/object

    Update

       Update general Signature 
    JSONObject < resource name > = client.update("< resource name >", "<your < resource name > id>", 
      ImmutableMap.of(
        "attribute name" , "<attribute value>"
      ));
    
       Update general Signature 
    dynamic properties = new ExpandoObject();
    properties.attribute name = "<attribute value>";
    
    dynamic < resource name > = client.update("< resource name >", "<your < resource name > id>", );
    
       Update general Signature 
    client.update('< resource name >',
      '<your < resource name > id>',
      {
        'attribute name': '<attribute value>'
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Update general Signature 
    <?php
    $user = $client->update('< resource name >', '<your < resource name > id>', 
      array (
        'attribute name' => '<attribute value>'
      ));
    ?>
    
       Update general Signature 
    curl https://api.luzmo.com/0.1.0/< resource name > \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your < resource name > id>",
      "properties": {
      "attribute name": "<attribute value>"
    }
    }
    EOF
    
       Update general Signature 
    resource_name = client.update("resource_name", "<your_resource_name_id>", {
        "attribute name": "<attribute value>"
    })
    

    Update the properties of a single specific entity, eg. update a column name or user password.

    Parameter
    Description

    Resource
    string
    The lowercase name of the resource we want to update

    Id
    uuid
    The id of the entity to update

    Properties
    object
    Here you provide the properties of the entity you want to update in the form of a map/object. If a property is not present in the map, it will remain untouched

    Delete

       Delete general Signature 
    client.delete("< resource name >", "<your < resource name > id>");
    
       Delete general Signature 
    $client->delete("< resource name >", "<your < resource name > id>");
    
       Delete general Signature 
    let promise = client.delete('< resource name >', '<your < resource name > id>');
    
       Delete general Signature 
    <?php
    $client->delete('< resource name >', '<your < resource name > id>');
    ?>
    
       Delete general Signature 
    curl https://api.luzmo.com/0.1.0/< resource name > \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your < resource name > id>"
    }
    EOF
    
       Delete general Signature 
    client.delete("resource_name", "<your_resource_name_id>")
    

    Delete a resource, eg. delete a dataset or group.

    Parameter
    Description

    Resource
    string
    The lowercase name of the resource we want to delete

    Id
    uuid
    The id of the entity to delete

    Get & List

       Get general Signature 
    JSONObject data = client.get("< resource name >", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "attribute name" , "<attribute value>"
        ),
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "<resource name>"
          )
        ),
        "attributes" , ImmutableList.of(
          "<attribute name>",
          "<attribute name>"
        ),
        "order" , ImmutableList.of(
    
          ImmutableList.of(
            "<attribute name>",
            "asc"
          ),
    
          ImmutableList.of(
    
            ImmutableMap.of(
              "model" , "<resource name>"
            ),
            "<attribute name>",
            "asc"
          )
        )
      ));
    
    
       Get general Signature 
    dynamic query = new ExpandoObject();
    query.where = new {
          attribute name = "<attribute value>"
        };
    query.include = new List<Object> {
    
          new {
            model = "<resource name>"
          }
        };
    query.attributes = new List<Object> {
          "<attribute name>",
          "<attribute name>"
        };
    query.order = new List<Object> {
    
          new List<Object> {
            "<attribute name>",
            "asc"
          },
    
          new List<Object> {
    
            new {
              model = "<resource name>"
            },
            "<attribute name>",
            "asc"
          }
        };
    
    dynamic data = client.get("< resource name >",     query);
    
    
       Get general Signature 
    client.get('< resource name >', {
        where: {
            'attribute name': '<attribute value>'
        },
        include: [
            {
                model: '<resource name>'
            }
        ],
        attributes: [
            '<attribute name>',
            '<attribute name>'
        ],
        order: [
            [
                '<attribute name>',
                'asc'
            ],
            [
                {
                    model: '<resource name>'
                },
                '<attribute name>',
                'asc'
            ]
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Get general Signature 
    <?php
    $user = $client->get('< resource name >', 
      array (
        'where' => array (
          'attribute name' => '<attribute value>'
        ),
        'include' => array (
    
          array (
            'model' => '<resource name>'
          )
        ),
        'attributes' => array (
          '<attribute name>',
          '<attribute name>'
        ),
        'order' => array (
    
          array (
            '<attribute name>',
            'asc'
          ),
    
          array (
    
            array (
              'model' => '<resource name>'
            ),
            '<attribute name>',
            'asc'
          )
        )
      ));
    
    ?>
    
       Get general Signature 
    curl https://api.luzmo.com/0.1.0/< resource name > \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "attribute name": "<attribute value>"
      },
      "include": [
        {
          "model": "<resource name>"
        }
      ],
      "attributes": [
        "<attribute name>",
        "<attribute name>"
      ],
      "order": [
        [
          "<attribute name>",
          "asc"
        ],
        [
          {
            "model": "<resource name>"
          },
          "<attribute name>",
          "asc"
        ]
      ]
    }
    }
    EOF
    
    
       Get general Signature 
    data = client.get("resource_name", {
        "where": {
          "attribute name": "<attribute value>"
        },
        "include": [{
          "model": "<resource name>"
        }],
        "attributes": ["<attribute name>","<attribute name>"],
        "order": [["<attribute name>","asc"],[{
          "model": "<resource name>"
        },"<attribute name>","asc"]]
    })
    
    

    Get and List are the same call. The reason why we differentiate between a Get and a List action is that different security rules apply. A user who can get a resource can't necessarily list the same resource. Get and List have a different structure than the other calls since it allows for complex queries. A call is considered to be a get action if you fetch an entity using a specific id in the where clause, else it is considered to be a list action. The query syntax is very close to SQL, it consists of the following attributes:

    Parameter
    Description
    resource:
    string
    The lowercase name of the resource we want to get or list
    query:
    object
    A query object consisting of SQL-like keywords such as: where, include, attributes, order
    attributes:
    string[]
    instead of returning all attributes, limit the set of attributes to the given list
    where:
    object[]
    Filter the selection, each where statement has to match
    include:
    object[]
    embed a connected object in the results, within an include you can again use where, include, attributes
    order:
    array[]
    Order on attributes. Either provide only an attribute and 'desc' or 'asc' to filter on a top-level attribute. or provide models in the beginning of the array if you want to target the attribute of an embedded resource.

    Associate

       Associate general Signature 
    client.associate("< resource name >", "<your < resource name > id>", "<resource to link name>", "<resource entity id>", 
      ImmutableMap.of(
        "property name" , "<property value>"
      ) );
    
       Associate general Signature 
    dynamic properties = new ExpandoObject();
    properties.property name = "<property value>";
    
    client.associate("< resource name >", "<your < resource name > id>", "<resource to link name>", "<resource entity id>",     properties );
    
       Associate general Signature 
    let promise = client.associate('< resource name >', '<your < resource name > id>', {
        role: '<resource to link name>',
        id: '<resource entity id>'
    }, {
        'property name': '<property value>'
    } );
    
       Associate general Signature 
    <?php
    $client->associate('< resource name >', '<your < resource name > id>', '<resource to link name>', '<resource entity id>', , 
      array (
        'property name' => '<property value>'
      ) );
    ?>
    
       Associate general Signature 
    curl https://api.luzmo.com/0.1.0/< resource name > \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your < resource name > id>",
      "resource": {
      "role": "<resource to link name>",
      "id": "<resource entity id>"
    },
      "properties": {
      "property name": "<property value>"
    }
    }
    EOF
    
       Associate general Signature 
    client.associate("resource_name", "<your_resource_name_id>", "role":"<resource to link name>","id":"<resource entity id>", {
        "property name": "<property value>"
    } )
    

    Associate two entities to each other, eg. link a Column to a Dataset. Associations can be set in both directions. Many associations are automatically set on creation as well, for example a dashboard is automatically associated with the user that created the dashboard. To know which resources can be associated please refer to the schema at the beginning of this chapter Schema).

    Parameter
    Description

    id:
    uuid
    The uuid of the resource you want to associate with another resource

    resource:
    object
    An object indicating which resource type (role) and which entity (id)

    role:
    string
    the role of the to-be-associated resource which is usually the capitalized plural name of the resource e.g. 'Users', 'Organizations'

    id:
    uuid
    the id of the to-be-associated resource

    properties:
    object
    some associations can have property set on them. e.g. on a User - Dataset relationship, there is a flagOwner property

    Dissociate

       Dissociate general Signature 
    client.dissociate("< resource name >", "<your < resource name > id>", "<resource to link name>", "<resource entity id>");
    
       Dissociate general Signature 
    client.dissociate("< resource name >", "<your < resource name > id>", "<resource to link name>", "<resource entity id>");
    
       Dissociate general Signature 
    let promise = client.dissociate('< resource name >', '<your < resource name > id>', {
        role: '<resource to link name>',
        id: '<resource entity id>'
    });
    
       Dissociate general Signature 
    <?php
    $client->associate('< resource name >', '<your < resource name > id>', "<resource to link name>", "<resource entity id>");
    ?>
    
       Dissociate general Signature 
    curl https://api.luzmo.com/0.1.0/< resource name > \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your < resource name > id>",
      "resource": {
      "role": "<resource to link name>",
      "id": "<resource entity id>"
    }
    }
    EOF
    
       Dissociate general Signature 
    client.dissociate("resource_name", "<your_resource_name_id>", "role":"<resource to link name>","id":"<resource entity id>")
    

    Remove an association between 2 entities. To know which resources can be disassociated please refer to the schema at the beginning of this chapter Schema).

    Parameter
    Description

    id:
    uuid
    The uuid of the resource you want to dissociate with another resource

    resource:
    object
    An object indicating which resource type (role) and which entity (id)

    role:
    string
    the role of the to-be-dissociated resource which is usually the capitalized plural name of the resource e.g. 'Users', 'Organizations'

    id:
    uuid
    the id of the to-be-dissociated resource

    Resources

    Account

    Accounts contain the information necessary to access a certain plugin (e.g. Teamleader, Google Drive, your own custom plugin, etc..) or database The easiest to understand what a plugin is to show you what part of the UI makes an account (see the screenshot below). When you add a database connection and click 'connect' an account is created to make sure you can connect when you retrieve datasets later on.

    Note that accounts employ a general terminology to accommodate both different plugins as dataproviders. Eg. a token in Luzmo terminology corresponds to a 'password' in a DB, where a scope in Luzmo terminology refers to the 'database' in a db which can have a different meaning in a plugin.

    Properties

    Parameter
    Description

    id
    uuid
    Unique key of the account (automatically assigned)

    provider
    string
    Type of data provider to retrieve data from. Either the 'slug' of a plugin, e.g. googleanalytics, googledrive, quandl, salesforce, mailchimp, etc... the slug of your own plugin or one of a database such as 'postgresql'. Slugs are unique short names for plugins and dataproviders (such as dbs)

    date
    datetime
    Date/time this account was linked by the user. Defaults to the current date.

    expiry
    datetime
    Expiry date of the credentials.

    scope
    string
    Provider-specific description of services used (eg. which accesses were granted, which database is used, ...).

    host
    string
    Endpoint of this account. For relational database connections, this corresponds to the hostname of the database.

    active
    boolean
    Indicates whether queries may be sent to this database or plugin connection. You can use this field to eg. temporarily disable any connections / queries. This might be useful in case of elevated stress on your systems.

    invalid
    boolean
    Read-only. Indicates whether this connection has been disabled because the source system reported that the used credentials are invalid.

    token
    boolean
    Token or password of this account.

    identifier
    string
    Key or username of this account.

    cache
    integer
    Defaults to 0. Number of seconds queries to this data connector are cached in Luzmo's caching layer. Use 0 to disable caching for this connector entirely. Note that queries might still not be cached if there are other uncached data connectors called in a query. You can invalidate the cache before the expiry time by calling the update method on the data endpoint.

    code
    string
    (Update-only) OAauth2 authorization code used to retrieve an access token and refresh token.

    Actions

    Create
    Update
    Get
    List
    Delete

    Action: Create

       Accounts are linked to users on creation 
    JSONObject account = client.create("account",
    
      ImmutableMap.of(
        "provider" , "postgresql",
        "host" , "<host address / ip>",
        "port" , "5432",
        "scope" , "<your database name>",
        "identifier" , "<username>",
        "token" , "<password>"
      ));
    System.out.printf("Account id: %s%n", account.get("id"));
    
       Accounts are linked to users on creation 
    dynamic properties = new ExpandoObject();
    properties.provider = "postgresql";
    properties.host = "<host address / ip>";
    properties.port = "5432";
    properties.scope = "<your database name>";
    properties.identifier = "<username>";
    properties.token = "<password>";
    
    dynamic account = client.create("account",    properties);
    
     Console.WriteLine("Account id is {0}", account["id"]);
    
       Accounts are linked to users on creation 
    client.create('account',
      {
        provider: 'postgresql',
        host: '<host address / ip>',
        port: 5432,
        scope: '<your database name>',
        identifier: '<username>',
        token: '<password>'
    }
    
    )
      .then(function(account) {
        var account_id = account.id;
      });
    
       Accounts are linked to users on creation 
    <?php
    $account = $client->create('account',
    
      array (
        'provider' => 'postgresql',
        'host' => '<host address / ip>',
        'port' => '5432',
        'scope' => '<your database name>',
        'identifier' => '<username>',
        'token' => '<password>'
      )
    
    );
    print( $account['id'] );
    ?>
    
       Accounts are linked to users on creation 
    curl https://api.luzmo.com/0.1.0/account  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "provider": "postgresql",
      "host": "<host address / ip>",
      "port": 5432,
      "scope": "<your database name>",
      "identifier": "<username>",
      "token": "<password>"
    }
    }
    EOF
    # result format of the account contains the account id 
    {
     ... 
     "id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
       Accounts are linked to users on creation 
    account = client.create("account",
    {
        "provider": "postgresql",
        "host": "<host address / ip>",
        "port": 5432,
        "scope": "<your database name>",
        "identifier": "<username>",
        "token": "<password>"
    })
    user = account["user_id"]
    
    Create
    can be executed by:
    Logged-in User

    Action: Update

       Update the credentials of an account 
    JSONObject account = client.update("account", "<your account id>", 
      ImmutableMap.of(
        "identifier" , "<username>",
        "token" , "<password>"
      ));
    
       Update the credentials of an account 
    dynamic properties = new ExpandoObject();
    properties.identifier = "<username>";
    properties.token = "<password>";
    
    dynamic account = client.update("account", "<your account id>", );
    
       Update the credentials of an account 
    client.update('account',
      '<your account id>',
      {
        identifier: '<username>',
        token: '<password>'
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Update the credentials of an account 
    <?php
    $user = $client->update('account', '<your account id>', 
      array (
        'identifier' => '<username>',
        'token' => '<password>'
      ));
    ?>
    
       Update the credentials of an account 
    curl https://api.luzmo.com/0.1.0/account  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your account id>",
      "properties": {
      "identifier": "<username>",
      "token": "<password>"
    }
    }
    EOF
    
       Update the credentials of an account 
    account = client.update("account", "<your_account_id>", {
        "identifier": "<username>",
        "token": "<password>"
    })
    
    Update
    can be executed by:
    Account Owner

    Action: Get

       Retrieve all your accounts 
    JSONObject data = client.get("account", 
      ImmutableMap.of(
    
      ));
    
    
       Retrieve all your accounts 
    dynamic query = new ExpandoObject();
    
    dynamic data = client.get("account",     query);
    
    
       Retrieve all your accounts 
    client.get('account', {})
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Retrieve all your accounts 
    <?php
    $user = $client->get('account', 
      array (
    
      ));
    
    ?>
    
       Retrieve all your accounts 
    curl https://api.luzmo.com/0.1.0/account  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {}
    }
    EOF
    
    
       Retrieve all your accounts 
    data = client.get("account", {
    
    })
    
    
    Get
    can be executed by:
    Account Reader
    List
    can be executed by:
    Account Reader

    Retrieving accounts.

    Action: Delete

       Delete an account 
    client.delete("account", "<your account id>");
    
       Delete an account 
    $client->delete("account", "<your account id>");
    
       Delete an account 
    let promise = client.delete('account', '<your account id>');
    
       Delete an account 
    <?php
    $client->delete('account', '<your account id>');
    ?>
    
       Delete an account 
    curl https://api.luzmo.com/0.1.0/account  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your account id>"
    }
    EOF
    
       Delete an account 
    client.delete("account", "<your_account_id>")
    
    Delete
    can be executed by:
    Account Owner

    Delete is the same for each resource, the only parameters required are the resource type and the uuid of the entity you want to delete.

    Associations

    As can be seen from the schema, accounts are only linked to users. This link to accounts is created automatically so you will never associate an account manually.

    %3 <!-- Account --> Account Account <!-- User --> User User <!-- User->Account --> User->Account

    Associate: User (implicit)

       Accounts are linked to users on creation 
    JSONObject account = client.create("account",
    
      ImmutableMap.of(
        "provider" , "postgresql",
        "host" , "<host address / ip>",
        "port" , "5432",
        "scope" , "<your database name>",
        "identifier" , "<username>",
        "token" , "<password>"
      ));
    System.out.printf("User id: %s%n", account.get("user_id"));
    
       Accounts are linked to users on creation 
    dynamic properties = new ExpandoObject();
    properties.provider = "postgresql";
    properties.host = "<host address / ip>";
    properties.port = "5432";
    properties.scope = "<your database name>";
    properties.identifier = "<username>";
    properties.token = "<password>";
    
    dynamic account = client.create("account",    properties);
    
     Console.WriteLine("User id is {0}", account["user_id"]);
    
       Accounts are linked to users on creation 
    client.create('account',
      {
        provider: 'postgresql',
        host: '<host address / ip>',
        port: 5432,
        scope: '<your database name>',
        identifier: '<username>',
        token: '<password>'
    })
      .then(function(account) {
        var user = account.user_id;
      });
    
       Accounts are linked to users on creation 
    <?php
    $account = $client->create('account',
    
      array (
        'provider' => 'postgresql',
        'host' => '<host address / ip>',
        'port' => '5432',
        'scope' => '<your database name>',
        'identifier' => '<username>',
        'token' => '<password>'
      )
    
    );
    print( $account['user_id'] );
    ?>
    
       Accounts are linked to users on creation 
    curl https://api.luzmo.com/0.1.0/account  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "provider": "postgresql",
        "host": "<host address / ip>",
        "port": 5432,
        "scope": "<your database name>",
        "identifier": "<username>",
        "token": "<password>"
      } 
    }
    EOF
    # result format of the account contains the user_id 
    {
     ... 
     "user_id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
    User
    Account
    Associate
    requires:
    Account Owner
    and
    User Owner

    This is a special case similar to many entities that are linked to user. The association to the creating user is automatically added when a new account is created.

    Alert

    Alerts allow a user to be notified when some interesting condition on their data is met. A simple example is an email send to the sales team when the quarterly sales target has been exceeded.

    The core elements of an alert are the query that checks the condition and the communication channels through which a notification will be send.

    The query can be any valid query that could be send to the data service. When the query returns at least one row, the condition is assumed to have been met and the alert is fired.

    A single alert can have multiple configured channels. Each will receive a message when the alert fires. Currently only email is supported as a channel, but more will follow.

    Properties

    Parameter
    Description
    id
    uuid
    Unique key of the alert (automatically assigned)
    name
    localized
    Title of the alert
    query
    json
    The query to execute
    frequency
    json
    Defines the frequency at which the condition is checked. Consists of a json object containing 2 properties: 'unit'(minute, hour, day, week, month, quarter, year) and 'quantity'
    channels
    json
    Array of channel configurations

    Actions

    Create
    Update
    Get
    List
    Delete

    Action: Create

       Alerts are linked to users on creation 
    JSONObject account = client.create("alert",
    
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "<title of your alert>"
        ),
        "query", ImmutableMap.of(
          "dimensions" , ImmutableList.of(
    
            ImmutableMap.of(
              "dataset_id" , "< Burrito dataset id >",
              "column_id" , "< Type of burrito column id >"
            )
          ),
          "measures" , ImmutableList.of(
    
            ImmutableMap.of(
              "dataset_id" , "< Burrito dataset id >",
              "column_id" , "< Number of burritos column id >",
              "aggregation" , ImmutableMap.of(
                "type" , "sum"
              )
            )
          ),
          "where" , ImmutableList.of(
    
            ImmutableMap.of(
              "expression" , "? in ?",
              "parameters" , ImmutableList.of(
    
                ImmutableMap.of(
                  "dataset_id" , "< Burrito dataset id >",
                  "column_id" , "< Type of burrito column id >"
                ),
                ImmutableList.of("Quesarito", "Chicken baconito")
              )
            )
          ),
          "having", ImmutableList.of(
    
            ImmutableMap.of(
              "expression" , "? >= ?",
              "parameters" , ImmutableList.of(
                ImmutableMap.of(
                  "dataset_id" , "< Burrito dataset id >",
                  "column_id" , "< Sold units column id >"
                  aggregation: {
                    type: 'sum'
                  }
                ),
                10000
              )
            )
          )
        ),
        "frequency", ImmutableMap.of(
          "unit", "day",
          "quantity", 1 
        ),
        "channels, ImmutableList.of(
          ImmutableMap.of(
            "type", "email",
            "config", ImmutableMap.of(
              "recipients", ImmutableList.of(
                "address", "user@organization.com",
                "type", "to",
                "locale", "en"
              ),
              "subject", ImmutableMap.of(
                "en", "Great sales!"
              ),
              "message", ImmutableMap.of(
                "en", "We've done great boys! Check out these numbers!"
              )
            )
          )
        )
      )
    );
    
    
       Alerts are linked to users on creation 
    dynamic properties = new ExpandoObject();
    properties.name = new {
      en = "<title of your alert>"
    };
    properties.query = new {
      dimensions = new List<Object> {
        new {
          dataset_id = "< Burrito dataset id >",
          column_id = "< Type of burrito column id >"
        }
      },
      measures = new List<Object> {
        new {
          dataset_id = "< Burrito dataset id >",
          column_id = "< Number of burritos column id >",
          aggregation = new {
            type = "sum"
          }
        }
      },
      where = new List<Object> {
        new {
          expression = "? in ?",
          parameters = new List<Object> {
            new {
              dataset_id = "< Burrito dataset id >",
              column_i = "< Type of burrito column id >"
            },
            new List<Object>{'Quesarito', 'Chicken baconito'}
          }
        }
      },
      having = new List<Object> {
        new {
          expression = "? >= ?",
          parameters = new List<Object> {
            new {
              dataset_id = "< Burrito dataset id >",
              column_id = "< Sold units column id >",
              aggregation = new {
                type = "sum"
              }
            },
            10000
          }
        }
      }
    };
    properties.frequency = new {
      unit = "day",
      quantity = 1
    };
    properties.channels = new List<Object> {
      new {
        type = "email",
        config = new {
          recipients = new List<Object> {
            new {
              address = "user@organization.com",
              type = "to",
              locale = "en"
            }
          },
          subject = new {
            en = "Great sales!"
          },
          message = new {
            en: "We've done great boys! Check out these numbers!"
          }
        }
      }
    };
    
    dynamic alert = client.create("alert", properties);
    
       Alerts are linked to users on creation 
    client.create('account',
      {
        name: { en: '<title of your alert>' },
        query: {
        dimensions: [
          {
            dataset_id: '< Burrito dataset id >',
            column_id: '< Type of burrito column id >'
          }
        ],
        measures: [
          {
            dataset_id: '< Burrito dataset id >',
            column_id: '< Number of burritos column id >',
            aggregation: {
              type: 'sum'
            }
          }
        ],
        where: [
          {
            expression: '? in ?',
            parameters: [
              {
                dataset_id: '< Burrito dataset id >',
                column_id: '< Type of burrito column id >'
              },
              ['Quesarito', 'Chicken baconito']
            ]
          }
        ],
        having: [
          {
            expression: '? >= ?',
            parameters: [
              {
                dataset_id: '< Burrito dataset id >',
                column_id: '< Sold units column id >',
                aggregation: {
                  type: 'sum'
                }
              },
              10000
            ]
          }
        ]
      },
        frequency: {
        unit: 'day',
        quantity: 1
      },
      channels: [
        {
          type: 'email',
          config: {
            recipients: [
              {
                address: 'user@organization.com',
                type: 'to',
                locale: 'en'
              }
            ],
            subject: {
              en: 'Great sales!'
            },
            message: {
              en: "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    }
    );
    
       Alerts are linked to users on creation 
    <?php
    $alert = $client->create('alert',
      array (
        'name' => array (
          'en' => '<title of your alert>'
        ),
        'query' => array (
          'dimensions' => array (
            array (
              'dataset_id' => '< Burrito dataset id >',
              'column_id' => '< Type of burrito column id >'
            )
          ),
          'measures' => array (
            array (
              'dataset_id' => '< Burrito dataset id >',
              'column_id' => '< Number of burritos column id >',
              'aggregation' => array (
                'type' => 'sum'
              )
            )
          ),
          'where' => array (
            array (
              'expression' => '? in ?',
              'parameters' => array (
                array (
                  'dataset_id' => '< Burrito dataset id >',
                  'column_id' => '< Type of burrito column id >'
                ),
                array ('Quesarito', 'Chicken baconito')
              )
            )
          ),
          'having' => array (
            array (
              'expression' => '? >= ?',
              'parameters' => array (
                array (
                  'dataset_id' => '< Burrito dataset id >',
                  'column_id' => '< Sold units column id >',
                  'aggregation' => array (
                    'type' => 'sum'
                  )
                ),
              10000
              )
            )
          )
        )
        'frequency' => array (
          'unit' => 'day',
          'quantity' => 1
        ),
        'channels' => array (
          array (
            'type' => 'email',
            'config' => array (
              'recipients' => array (
                array (
                  'address' => 'user@organization.com',
                  'type' => 'to',
                  'locale' => 'en'
                )
              ),
              'subject' => array (
                'en' => 'Great sales!'
              ),
              'message' => array (
                'en' => "We've done great boys! Check out these numbers!"
              )
            )
          )
        )
      )
    
    );
    ?>
    
       Alerts are linked to users on creation 
    curl https://api.luzmo.com/0.1.0/alert  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "name": { "en": "<title of your alert>" }
      "query": {
        "dimensions": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Type of burrito column id >"
          }
        ],
        "measures": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Number of burritos column id >",
            "aggregation": {
              "type": "sum"
            }
          }
        ],
        "where": [
          {
            "expression": "? in ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Type of burrito column id >"
              },
              ["Quesarito", "Chicken baconito"]
            ]
          }
        ],
        "having": [
          {
            "expression": "? >= ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Sold units column id >",
                "aggregation": {
                  "type": "sum"
                }
              },
              10000
            ]
          }
        ]
      },
      "frequency": { "unit": "day", "quantity": 1 }
      "channels": [
        {
          "type": "email",
          "config": {
            "recipients": [
              {
                "address": "user@organization.com",
                "type": "to",
                "locale": "en"
              }
            ],
            "subject": {
              "en": "Great sales!"
            },
            "message": {
              "en": "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    }
    }
    EOF
    
    Create
    can be executed by:
    Logged-in (SSO) User

    Action: Update

       Update the frequency of an alert 
    JSONObject account = client.update("alert", "<your alert id>", 
      ImmutableMap.of(
        "frequency" , ImmutableMap.of(
          "unit", "week",
          "quantity", 1
        )
      ));
    
       Update the frequency of an alert 
    dynamic properties = new ExpandoObject();
    properties.frequency = new {
      unit = "week",
      quantity = 1
    };
    
    dynamic account = client.update("alert", "<your alert id>", properties);
    
       Update the frequency of an alert 
    client.update('alert',
      '<your alert id>',
      {
        frequency: {
          unit: 'week',
          quantity: 1
        }
      }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Update the frequency of an alert 
    <?php
    $user = $client->update('alert', '<your alert id>', 
      array (
        'frequency' => array (
          'unit' => 'week',
          'quantity' => 1
        )
      ));
    ?>
    
       Update the frequency of an alert 
    curl https://api.luzmo.com/0.1.0/alert  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your alert id>",
      "properties": {
        "frequency": { "unit": "week", "quantity": 1 }
      }
    }
    EOF
    
    Update
    can be executed by:
    Alert Owner

    Action: Get

       Retrieve all your alerts 
    JSONObject data = client.get("alert", 
      ImmutableMap.of(
    
      ));
    
    
       Retrieve all your alerts 
    dynamic query = new ExpandoObject();
    
    dynamic data = client.get("alert",     query);
    
    
       Retrieve all your alerts 
    client.get('alert', {})
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Retrieve all your alerts 
    <?php
    $user = $client->get('alert', 
      array (
    
      ));
    
    ?>
    
       Retrieve all your alerts 
    curl https://api.luzmo.com/0.1.0/alert  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {}
    }
    EOF
    
    
    Get
    can be executed by:
    Alert Owner
    List
    can be executed by:
    Alert Owner

    Retrieving alerts.

    Action: Delete

       Delete an alert 
    client.delete("alert", "<your alert id>");
    
       Delete an alert 
    $client->delete("alert", "<your alert id>");
    
       Delete an alert 
    let promise = client.delete('alert', '<your alert id>');
    
       Delete an alert 
    <?php
    $client->delete('alert', '<your alert id>');
    ?>
    
       Delete an alert 
    curl https://api.luzmo.com/0.1.0/alert  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your alert id>"
    }
    EOF
    
    Delete
    can be executed by:
    Alert Owner

    Delete is the same for each resource, the only parameters required are the resource type and the uuid of the entity you want to delete.

    Associations

    Alerts are implicitly associated with the User that created the alert and with a Schedule to trigger the alert.

    Associate: Schedule (implicit)

       Schedules are automatically linked to the alert on creation time 
    JSONObject account = client.create("alert",
    
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "<title of your alert>"
        ),
        "query", ImmutableMap.of(
          "dimensions" , ImmutableList.of(
    
            ImmutableMap.of(
              "dataset_id" , "< Burrito dataset id >",
              "column_id" , "< Type of burrito column id >"
            )
          ),
          "measures" , ImmutableList.of(
    
            ImmutableMap.of(
              "dataset_id" , "< Burrito dataset id >",
              "column_id" , "< Number of burritos column id >",
              "aggregation" , ImmutableMap.of(
                "type" , "sum"
              )
            )
          ),
          "where" , ImmutableList.of(
    
            ImmutableMap.of(
              "expression" , "? in ?",
              "parameters" , ImmutableList.of(
    
                ImmutableMap.of(
                  "dataset_id" , "< Burrito dataset id >",
                  "column_id" , "< Type of burrito column id >"
                ),
                ImmutableList.of("Quesarito", "Chicken baconito")
              )
            )
          ),
          "having", ImmutableList.of(
    
            ImmutableMap.of(
              "expression" , "? >= ?",
              "parameters" , ImmutableList.of(
                ImmutableMap.of(
                  "dataset_id" , "< Burrito dataset id >",
                  "column_id" , "< Sold units column id >"
                  aggregation: {
                    type: 'sum'
                  }
                ),
                10000
              )
            )
          )
        ),
        "frequency", ImmutableMap.of(
          "unit", "day",
          "quantity", 1 
        ),
        "channels, ImmutableList.of(
          ImmutableMap.of(
            "type", "email",
            "config", ImmutableMap.of(
              "recipients", ImmutableList.of(
                "address", "user@organization.com",
                "type", "to",
                "locale", "en"
              ),
              "subject", ImmutableMap.of(
                "en", "Great sales!"
              ),
              "message", ImmutableMap.of(
                "en", "We've done great boys! Check out these numbers!"
              )
            )
          )
        )
      )
    );
    
    
       Schedules are automatically linked to the alert on creation time 
    dynamic properties = new ExpandoObject();
    properties.name = new {
      en = "<title of your alert>"
    };
    properties.query = new {
      dimensions = new List<Object> {
        new {
          dataset_id = "< Burrito dataset id >",
          column_id = "< Type of burrito column id >"
        }
      },
      measures = new List<Object> {
        new {
          dataset_id = "< Burrito dataset id >",
          column_id = "< Number of burritos column id >",
          aggregation = new {
            type = "sum"
          }
        }
      },
      where = new List<Object> {
        new {
          expression = "? in ?",
          parameters = new List<Object> {
            new {
              dataset_id = "< Burrito dataset id >",
              column_i = "< Type of burrito column id >"
            },
            new List<Object>{'Quesarito', 'Chicken baconito'}
          }
        }
      },
      having = new List<Object> {
        new {
          expression = "? >= ?",
          parameters = new List<Object> {
            new {
              dataset_id = "< Burrito dataset id >",
              column_id = "< Sold units column id >",
              aggregation = new {
                type = "sum"
              }
            },
            10000
          }
        }
      }
    };
    properties.frequency = new {
      unit = "day",
      quantity = 1
    };
    properties.channels = new List<Object> {
      new {
        type = "email",
        config = new {
          recipients = new List<Object> {
            new {
              address = "user@organization.com",
              type = "to",
              locale = "en"
            }
          },
          subject = new {
            en = "Great sales!"
          },
          message = new {
            en: "We've done great boys! Check out these numbers!"
          }
        }
      }
    };
    
    dynamic alert = client.create("alert", properties);
    
       Schedules are automatically linked to the alert on creation time 
    client.create('account',
      {
        name: { en: '<title of your alert>' },
        query: {
        dimensions: [
          {
            dataset_id: '< Burrito dataset id >',
            column_id: '< Type of burrito column id >'
          }
        ],
        measures: [
          {
            dataset_id: '< Burrito dataset id >',
            column_id: '< Number of burritos column id >',
            aggregation: {
              type: 'sum'
            }
          }
        ],
        where: [
          {
            expression: '? in ?',
            parameters: [
              {
                dataset_id: '< Burrito dataset id >',
                column_id: '< Type of burrito column id >'
              },
              ['Quesarito', 'Chicken baconito']
            ]
          }
        ],
        having: [
          {
            expression: '? >= ?',
            parameters: [
              {
                dataset_id: '< Burrito dataset id >',
                column_id: '< Sold units column id >',
                aggregation: {
                  type: 'sum'
                }
              },
              10000
            ]
          }
        ]
      },
        frequency: {
        unit: 'day',
        quantity: 1
      },
      channels: [
        {
          type: 'email',
          config: {
            recipients: [
              {
                address: 'user@organization.com',
                type: 'to',
                locale: 'en'
              }
            ],
            subject: {
              en: 'Great sales!'
            },
            message: {
              en: "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    }
    );
    
       Schedules are automatically linked to the alert on creation time 
    <?php
    $alert = $client->create('alert',
      array (
        'name' => array (
          'en' => '<title of your alert>'
        ),
        'query' => array (
          'dimensions' => array (
            array (
              'dataset_id' => '< Burrito dataset id >',
              'column_id' => '< Type of burrito column id >'
            )
          ),
          'measures' => array (
            array (
              'dataset_id' => '< Burrito dataset id >',
              'column_id' => '< Number of burritos column id >',
              'aggregation' => array (
                'type' => 'sum'
              )
            )
          ),
          'where' => array (
            array (
              'expression' => '? in ?',
              'parameters' => array (
                array (
                  'dataset_id' => '< Burrito dataset id >',
                  'column_id' => '< Type of burrito column id >'
                ),
                array ('Quesarito', 'Chicken baconito')
              )
            )
          ),
          'having' => array (
            array (
              'expression' => '? >= ?',
              'parameters' => array (
                array (
                  'dataset_id' => '< Burrito dataset id >',
                  'column_id' => '< Sold units column id >',
                  'aggregation' => array (
                    'type' => 'sum'
                  )
                ),
              10000
              )
            )
          )
        )
        'frequency' => array (
          'unit' => 'day',
          'quantity' => 1
        ),
        'channels' => array (
          array (
            'type' => 'email',
            'config' => array (
              'recipients' => array (
                array (
                  'address' => 'user@organization.com',
                  'type' => 'to',
                  'locale' => 'en'
                )
              ),
              'subject' => array (
                'en' => 'Great sales!'
              ),
              'message' => array (
                'en' => "We've done great boys! Check out these numbers!"
              )
            )
          )
        )
      )
    
    );
    ?>
    
       Schedules are automatically linked to the alert on creation time 
    curl https://api.luzmo.com/0.1.0/alert  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "name": { "en": "<title of your alert>" }
      "query": {
        "dimensions": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Type of burrito column id >"
          }
        ],
        "measures": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Number of burritos column id >",
            "aggregation": {
              "type": "sum"
            }
          }
        ],
        "where": [
          {
            "expression": "? in ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Type of burrito column id >"
              },
              ["Quesarito", "Chicken baconito"]
            ]
          }
        ],
        "having": [
          {
            "expression": "? >= ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Sold units column id >",
                "aggregation": {
                  "type": "sum"
                }
              },
              10000
            ]
          }
        ]
      },
      "frequency": { "unit": "day", "quantity": 1 }
      "channels": [
        {
          "type": "email",
          "config": {
            "recipients": [
              {
                "address": "user@organization.com",
                "type": "to",
                "locale": "en"
              }
            ],
            "subject": {
              "en": "Great sales!"
            },
            "message": {
              "en": "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    }
    }
    EOF
    
       Schedules are automatically linked to the alert on creation time 
    alert = client.create("alert",
    {
        "name": { "en": "<title of your alert>" }
      "query": {
        "dimensions": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Type of burrito column id >"
          }
        ],
        "measures": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Number of burritos column id >",
            "aggregation": {
              "type": "sum"
            }
          }
        ],
        "where": [
          {
            "expression": "? in ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Type of burrito column id >"
              },
              ["Quesarito", "Chicken baconito"]
            ]
          }
        ],
        "having": [
          {
            "expression": "? >= ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Sold units column id >",
                "aggregation": {
                  "type": "sum"
                }
              },
              10000
            ]
          }
        ]
      },
      "frequency": { "unit": "day", "quantity": 1 }
      "channels": [
        {
          "type": "email",
          "config": {
            "recipients": [
              {
                "address": "user@organization.com",
                "type": "to",
                "locale": "en"
              }
            ],
            "subject": {
              "en": "Great sales!"
            },
            "message": {
              "en": "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    })
    
    Alert
    Schedule

    The association to the schedule is created automatically when an alert is made, this association cannot be created manually.

    Associate: User (implicit)

       Alerts are automatically linked to the user on creation time 
    JSONObject account = client.create("alert",
    
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "<title of your alert>"
        ),
        "query", ImmutableMap.of(
          "dimensions" , ImmutableList.of(
    
            ImmutableMap.of(
              "dataset_id" , "< Burrito dataset id >",
              "column_id" , "< Type of burrito column id >"
            )
          ),
          "measures" , ImmutableList.of(
    
            ImmutableMap.of(
              "dataset_id" , "< Burrito dataset id >",
              "column_id" , "< Number of burritos column id >",
              "aggregation" , ImmutableMap.of(
                "type" , "sum"
              )
            )
          ),
          "where" , ImmutableList.of(
    
            ImmutableMap.of(
              "expression" , "? in ?",
              "parameters" , ImmutableList.of(
    
                ImmutableMap.of(
                  "dataset_id" , "< Burrito dataset id >",
                  "column_id" , "< Type of burrito column id >"
                ),
                ImmutableList.of("Quesarito", "Chicken baconito")
              )
            )
          ),
          "having", ImmutableList.of(
    
            ImmutableMap.of(
              "expression" , "? >= ?",
              "parameters" , ImmutableList.of(
                ImmutableMap.of(
                  "dataset_id" , "< Burrito dataset id >",
                  "column_id" , "< Sold units column id >"
                  aggregation: {
                    type: 'sum'
                  }
                ),
                10000
              )
            )
          )
        ),
        "frequency", ImmutableMap.of(
          "unit", "day",
          "quantity", 1 
        ),
        "channels, ImmutableList.of(
          ImmutableMap.of(
            "type", "email",
            "config", ImmutableMap.of(
              "recipients", ImmutableList.of(
                "address", "user@organization.com",
                "type", "to",
                "locale", "en"
              ),
              "subject", ImmutableMap.of(
                "en", "Great sales!"
              ),
              "message", ImmutableMap.of(
                "en", "We've done great boys! Check out these numbers!"
              )
            )
          )
        )
      )
    );
    
    
       Alerts are automatically linked to the user on creation time 
    dynamic properties = new ExpandoObject();
    properties.name = new {
      en = "<title of your alert>"
    };
    properties.query = new {
      dimensions = new List<Object> {
        new {
          dataset_id = "< Burrito dataset id >",
          column_id = "< Type of burrito column id >"
        }
      },
      measures = new List<Object> {
        new {
          dataset_id = "< Burrito dataset id >",
          column_id = "< Number of burritos column id >",
          aggregation = new {
            type = "sum"
          }
        }
      },
      where = new List<Object> {
        new {
          expression = "? in ?",
          parameters = new List<Object> {
            new {
              dataset_id = "< Burrito dataset id >",
              column_i = "< Type of burrito column id >"
            },
            new List<Object>{'Quesarito', 'Chicken baconito'}
          }
        }
      },
      having = new List<Object> {
        new {
          expression = "? >= ?",
          parameters = new List<Object> {
            new {
              dataset_id = "< Burrito dataset id >",
              column_id = "< Sold units column id >",
              aggregation = new {
                type = "sum"
              }
            },
            10000
          }
        }
      }
    };
    properties.frequency = new {
      unit = "day",
      quantity = 1
    };
    properties.channels = new List<Object> {
      new {
        type = "email",
        config = new {
          recipients = new List<Object> {
            new {
              address = "user@organization.com",
              type = "to",
              locale = "en"
            }
          },
          subject = new {
            en = "Great sales!"
          },
          message = new {
            en: "We've done great boys! Check out these numbers!"
          }
        }
      }
    };
    
    dynamic alert = client.create("alert", properties);
    
       Alerts are automatically linked to the user on creation time 
    client.create('account',
      {
        name: { en: '<title of your alert>' },
        query: {
        dimensions: [
          {
            dataset_id: '< Burrito dataset id >',
            column_id: '< Type of burrito column id >'
          }
        ],
        measures: [
          {
            dataset_id: '< Burrito dataset id >',
            column_id: '< Number of burritos column id >',
            aggregation: {
              type: 'sum'
            }
          }
        ],
        where: [
          {
            expression: '? in ?',
            parameters: [
              {
                dataset_id: '< Burrito dataset id >',
                column_id: '< Type of burrito column id >'
              },
              ['Quesarito', 'Chicken baconito']
            ]
          }
        ],
        having: [
          {
            expression: '? >= ?',
            parameters: [
              {
                dataset_id: '< Burrito dataset id >',
                column_id: '< Sold units column id >',
                aggregation: {
                  type: 'sum'
                }
              },
              10000
            ]
          }
        ]
      },
        frequency: {
        unit: 'day',
        quantity: 1
      },
      channels: [
        {
          type: 'email',
          config: {
            recipients: [
              {
                address: 'user@organization.com',
                type: 'to',
                locale: 'en'
              }
            ],
            subject: {
              en: 'Great sales!'
            },
            message: {
              en: "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    }
    );
    
       Alerts are automatically linked to the user on creation time 
    <?php
    $alert = $client->create('alert',
      array (
        'name' => array (
          'en' => '<title of your alert>'
        ),
        'query' => array (
          'dimensions' => array (
            array (
              'dataset_id' => '< Burrito dataset id >',
              'column_id' => '< Type of burrito column id >'
            )
          ),
          'measures' => array (
            array (
              'dataset_id' => '< Burrito dataset id >',
              'column_id' => '< Number of burritos column id >',
              'aggregation' => array (
                'type' => 'sum'
              )
            )
          ),
          'where' => array (
            array (
              'expression' => '? in ?',
              'parameters' => array (
                array (
                  'dataset_id' => '< Burrito dataset id >',
                  'column_id' => '< Type of burrito column id >'
                ),
                array ('Quesarito', 'Chicken baconito')
              )
            )
          ),
          'having' => array (
            array (
              'expression' => '? >= ?',
              'parameters' => array (
                array (
                  'dataset_id' => '< Burrito dataset id >',
                  'column_id' => '< Sold units column id >',
                  'aggregation' => array (
                    'type' => 'sum'
                  )
                ),
              10000
              )
            )
          )
        )
        'frequency' => array (
          'unit' => 'day',
          'quantity' => 1
        ),
        'channels' => array (
          array (
            'type' => 'email',
            'config' => array (
              'recipients' => array (
                array (
                  'address' => 'user@organization.com',
                  'type' => 'to',
                  'locale' => 'en'
                )
              ),
              'subject' => array (
                'en' => 'Great sales!'
              ),
              'message' => array (
                'en' => "We've done great boys! Check out these numbers!"
              )
            )
          )
        )
      )
    
    );
    ?>
    
       Alerts are automatically linked to the user on creation time 
    curl https://api.luzmo.com/0.1.0/alert  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "name": { "en": "<title of your alert>" }
      "query": {
        "dimensions": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Type of burrito column id >"
          }
        ],
        "measures": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Number of burritos column id >",
            "aggregation": {
              "type": "sum"
            }
          }
        ],
        "where": [
          {
            "expression": "? in ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Type of burrito column id >"
              },
              ["Quesarito", "Chicken baconito"]
            ]
          }
        ],
        "having": [
          {
            "expression": "? >= ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Sold units column id >",
                "aggregation": {
                  "type": "sum"
                }
              },
              10000
            ]
          }
        ]
      },
      "frequency": { "unit": "day", "quantity": 1 }
      "channels": [
        {
          "type": "email",
          "config": {
            "recipients": [
              {
                "address": "user@organization.com",
                "type": "to",
                "locale": "en"
              }
            ],
            "subject": {
              "en": "Great sales!"
            },
            "message": {
              "en": "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    }
    }
    EOF
    
       Alerts are automatically linked to the user on creation time 
    alert = client.create("alert",
    {
        "name": { "en": "<title of your alert>" }
      "query": {
        "dimensions": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Type of burrito column id >"
          }
        ],
        "measures": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Number of burritos column id >",
            "aggregation": {
              "type": "sum"
            }
          }
        ],
        "where": [
          {
            "expression": "? in ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Type of burrito column id >"
              },
              ["Quesarito", "Chicken baconito"]
            ]
          }
        ],
        "having": [
          {
            "expression": "? >= ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Sold units column id >",
                "aggregation": {
                  "type": "sum"
                }
              },
              10000
            ]
          }
        ]
      },
      "frequency": { "unit": "day", "quantity": 1 }
      "channels": [
        {
          "type": "email",
          "config": {
            "recipients": [
              {
                "address": "user@organization.com",
                "type": "to",
                "locale": "en"
              }
            ],
            "subject": {
              "en": "Great sales!"
            },
            "message": {
              "en": "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    })
    
    Alert
    User

    The association to the user is created automatically when an alert is made, this association cannot be created manually. The alert will be associated with the user making the request.

    Authorization

    Authorizations are tokens that grant access to the Luzmo platform. Tokens can be created in a cascaded way but are always ultimately tied to a single User. Authorizations are subservient to groups and users. If a user for which you make a token has no access to a certain dashboard or dataset then an authorization token made by this user will also not have access to these resources, regardless of the filters. Of course it is possible to combine the mechanisms of groups, users and authorizations. Just like groups and users, authorizations have very powerful filters that allow filtering on the granularity of datasets/dashboards as well as at the row level of datasets.

    Properties

    Parameter
    Description
    id
    uuid
    Unique key of the authorization (automatically assigned)
    type
    string
    Authorization type. Possible types created by an API token are:
    • embed: create a temporary embed token for an end-user.
    • sso: (deprecated in favor of type 'embed') create a temporary single sign-on session for an end-user.
    Other token types:
    • login: a session started by manually authenticating using your user credentials
    • api: API token for programmatic access to Luzmo resources. Can be created only through a login session
    access
    object
    Specifies which datasets, dashboards and/or collections the token should have access to. When providing direct access to a dashboard, make sure to also provide access to the underlying dataset(s) to avoid 'No access' errors!
    collections
    array[object]
    List of Collections that contain one or more securables (dashboards and/or datasets), to which the token should have access to. The token will not have access to the Collection itself, but rather uses the Collection to access the underlying resources.
    If a securable is added or removed from a collection, you must generate a new token (i.e the token gets access to securables inside the collection at the time of creation).
    If you specify a dashboard and/or dataset in the dashboards / datasets property, which is also accessible to the token through a Collection which include this dashboard / dataset, the more specific right is applied (i.e the right specified in the dashboards / datasets property overrides the rights from the Collection).
    id
    uuid
    Collection id through which you'd like to provide the token access to the underlying securables (i.e. dashboards & datasets).
    inheritRights
    string
    One of read,use, modify or own.
    The API token used to generate the embed token must have similar or more access to the securables in the collection! If not, a warning message will be returned in the response to indicate that the embed token doesn't have access to one or more collection securables.
    datasets
    array[object]
    List of datasets the token should have access to, with their individual access rights. If dataset(s) are specified which are also accessible through a specified Collection, the explicit dataset access rights specified in this datasets property will override the inherited access right from the Collection.
    id
    uuid
    Id of the dataset to which your token should have access to
    rights
    string
    One of read,use, modify or own.
    Note that the API token used to generate the embed token must have similar or more access to the dataset!
    dashboards
    array[object]
    List of dashboards the token should have access to, with their individual access rights. If dashboard(s) are specified which are also accessible through a specified Collection, the explicit dashboard access rights specified in this dashboards property will override the inherited access right from the Collection.
    id
    uuid
    Id of the dashboard to which your token should have access to
    rights
    string
    One of read,use, modify or own.
    Note that the API token used to generate the embed token must have similar or more access to the dashboard!
    expiry
    date (RFC 3339)
    RFC3339 timestamp when this authorization will cease working. Defaults to 24 hours from creation default, with a maximum of 1 year.
    This is the hard (maximum) expiry time of the token, after which it will *always* be invalid. We advise using short expiry time, eg. 24 hours from now.
    inactivity_interval
    integer
    Duration of inactivity (in seconds) after which the token is prematurely invalidated. Defaults to 0.
    You can use this to prematurely invalidate tokens when the user session in your application has ended (eg. all open dashboards are closed). A value of 0 means no premature invalidation due to inactivity (the token will only expire on the datetime specified in the expiry property of the Authorization request).

    We advise not to set the interval to a value smaller than 120 seconds, to avoid accidental invalidation for a dashboard that is still open, eg. when a heartbeat signal sent to the server is missed.
    parameter_overrides
    object
    Use this property to override parameter values of a parameterized filter(s). This must be a valid JSON object with a maximum length of 10 000 characters.

    To clear parameterized filter(s) completely (i.e. not apply them), override its value to: {"<your_parameter_name>": {"clear": true}}

    This property is only available for Authorization of type 'embed', for Authorization tokens with deprecated type 'sso', you should use the metadata property.
    metadata
    object
    Use the metadata property specify optional Viewer metadata. This must be a valid JSON object with a maximum length of 10 000 characters. For Authorization tokens with deprecated type 'sso', you can also use the metadata property to override parameter values of parameterized filters.

    To clear a parameter filter completely (deactivate it on the dashboard), set the metadata property clear to true: {"metadata": {"clear": true}}

    To mark sensitive metadata that should not be logged, like JWT or authentication tokens, store it as an object with the sensitive property set: {"metadata": {"jwt": {"sensitive": true, "token": "..."}}}
    environment
    string
    Whether this a production or test token. If set to production, your integrations will show the published production dashboard, if one exists, and the latest dashboard otherwise. If set to null, the latest dashboard will be loaded regardless of the publish status.

    This property defaults to production.
    ip
    array[string]
    List of IP addresses or subnets. Both IPv4 and IPv6 IPs and subnets can be used. Leave empty to disable IP whitelisting. Eg.: ["123.45.67.89", "123.45.66.0/4", "2001:db8:0:1:1:1:1:1"]
    screenmode
    string
    Screen mode of dashboards to use. Either desktop, tablet, mobile, largeScreen, fixed. If empty, the window size will be used to determine the screen mode.
    currency_id
    string
    Override the currency used in all datasets changing the displayed currency symbol on the dashboards. Expects a currency_id in the form of an ISO 4217 currency code, for example: EUR or USD.
    suborganization
    string
    Each embed token should be in a suborganization. The suborganization determines which other users they can see & interact with. it defaults to username to have total isolation, set to null if you want all users to see each other.
    username
    string
    Viewer metadata: The username of the end-user. This will be used to uniquely identify a Monthly Active Viewer (MAV) for your Organization. If not provided, functional session cookies will be used to distinguish MAVs.
    name
    string
    Viewer metadata: name of the end-user.
    email
    string
    Viewer metadata: email address of the end-user.
    theme
    object
    Optional JSON definition of a theme to apply to the dashboard
    css
    string
    Optional CSS override to apply to the dashboard. The CSS gets appended to the existing CSS overrides in the dashboard.
    account_overrides
    object
    Let this token override the connection to one or more data connections (to a Plugin or database). You can use this to dynamically route requests to different endpoints (eg. the correct endpoint per client in a single-tenant setup). All overrides are optional -- if not specified, the value as configured on the original Account will be used instead.
    < account id >
    object
    The Plugin account id for which you want to override properties as property name.
    base_url
    string
    (optional) The new base URL that will be called.
    properties
    object
    (optional) Lists the custom authentication properties to override for plugin-based connections.
    <custom_property_id>
    string
    (optional) The new custom authentication property value (the key is the custom authentication property id as defined when setting up the plugin in Luzmo).
    This will be sent as X-Property-<custom_property_id> header to the Plugin.
    datasets
    object
    (optional) List of dataset-level overrides. Useful if you want to override only a single table in your dashboard or if you have a separate table per client.
    < dataset id >
    object
    The dataset (securable) ID that you want to override.
    table
    string
    (optional) The new canonical dataset identifier (as defined in the Plugin) to retrieve data from.
    < account id >
    object
    The database account id for which you want to override properties as property name.
    host
    string
    (optional) The new database host to connect to. The database must be of the same type as the originally configured database.
    port
    string
    (optional) The new port to connect to.
    user
    string
    (optional) The new user to use when connecting.
    password
    string
    (optional) The new password to use when connecting.
    schema
    string
    (optional) The new schema to retrieve data from. Note that to MySQL the concepts database and schema are identical. So when overriding a database / schema for MySQL, make sure to pass the same value to both schema and database
    database
    string
    (optional) the new database to retrieve data from. Note that to MySQL the concepts database and schema are identical. So when overriding a database / schema for MySQL, make sure to pass the same value to both schema and database
    table
    string
    (optional) The new table to retrieve data from.
    datasets
    object
    (optional) List of dataset-level overrides. Useful if you want to override only a single table in your dashboard or if you have a separate table per client. The SQL query of the dataset can also be overridden if it's a SQL dataset within Luzmo. Allowing you to call stored procedures for example.
    < dataset id >
    object
    The dataset (securable) ID that you want to override.
    table
    string
    (optional) The new table to connect to
    schema
    string
    (optional) The new schema to connect to.
    sql
    string
    (optional) The new SQL statement to use. NOTE: the columns returned in the new query need to conform to the same schema as the original dataset.
    filters
    array[object]
    List of data filters to apply when data queries are performed with this authorization. This can be used with multi-tenanted datasets to ensure end-clients can only access their own data. The use of parameter filters is usually a better approach, however.
    clause
    string
    Timing of application of the filter. Possible values: where (applied before aggregation/grouping, for example, only select rows with a specific price), having (applied after aggregation/grouping, for example, to select only groups in which the total price exceeds a specific value)
    origin
    string
    Level to apply the filter. Possible values: global (row-level security, exclude specific rows from users for the complete dataset), chart (row-level security, exclude specific rows from users for a single chart), initialization (initialize an interactive filter within a dashboard to a particular value, but the end-user can override the filter value)
    securable_id
    uuid
    In case of global or chart filter:
    Dataset id to filter.
    column_id
    uuid
    In case of global or chart filter:
    Column id to filter.
    chart_id
    uuid
    In case of initialization or chart filter:
    Chart id to initialize.
    expression
    *
    Which filter to apply. Possible values: ? = ?, ? > ?, ? >= ?, ? < ?, ? <= ?, ? in ?, ? not in ?, ? is null, ? is not null.
    value
    number, string, boolean, array
    Value to insert in the filter.
    last_used_at
    datetime
    (Read-only) Timestamp of the last API call of this authorization. Can be delayed up to 5 minutes.

    Actions

    Create
    Get
    List
    Delete

    Remember that an authorization is always immutable and therefore only supports Create, Get and Delete. It is possible though to associate using create fields which is explained further on. An authorization token can only be associated to the user that created it and is automatically associated to that User. Locale on the other hand is set using a property locale_id and cannot be updated after creation.

    Action: Create

       Example of creating a technical user to start creating temporary tokens. The result will contain a Login token that you can use to request an API token. Make sure it is added to the correct organization using the API token of an organization owner which has access to your organization's resources 
    JSONObject user = client.create("user",
    
      ImmutableMap.of(
        "name" , "Technical User",
        "email" , "technical-user@luzmo.com",
        "password" , "... random password ..."
      ));
    String login_token_key = user.getJSONObject("token").getString("id");
    String login_token = user.getJSONObject("token").getString("token");
    
       Example of creating a technical user to start creating sso tokens. The result will contain a Login token that you can use to request an API token. Make sure it is added to the correct organization using the API token of an organization owner which has access to your organization's resources 
    dynamic properties = new ExpandoObject();
    properties.name = "Technical User";
    properties.email = "technical-user@luzmo.com";
    properties.password = "... random password ...";
    
    dynamic user = client.create("user",    properties);
    
    // The user contains a new login token
    Console.WriteLine("Token Key is {0}", user["token"]["id"]);
    Console.WriteLine("Token is {0}", user["token"]["token"]);
    
       Example of creating a technical user to start creating sso tokens. The result will contain a Login token that you can use to request an API token. Make sure it is added to the correct organization using the API token of an organization owner which has access to your organization's resources 
    client.create('user',
      {
      name: 'Technical User',
      email: 'technical-user@luzmo.com',
      password: '... random password ...'
    }
    
    )
      .then(function(user) {
        var login_token_key = user.token.id; 
    var login_token = user.token.token;
      });
    
       Example of creating a technical user to start creating sso tokens. The result will contain a Login token that you can use to request an API token. Make sure it is added to the correct organization using the API token of an organization owner which has access to your organization's resources 
    <?php
    $user = $client->create('user',
    
      array (
        'name' => 'Technical User',
        'email' => 'technical-user@luzmo.com',
        'password' => '... random password ...'
      )
    
    );
    $login_token_key = $user['token']['id'] );
     $login_token = $user['token']['token'] );
    ?>
    
       Example of creating a technical user to start creating sso tokens. The result will contain a Login token that you can use to request an API token. Make sure it is added to the correct organization using the API token of an organization owner which has access to your organization's resources 
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "name": "Technical User",
      "email": "technical-user@luzmo.com",
      "password": "... random password ..."
    }
    }
    EOF
    # result format of the user contains the token 
    {
     ... 
     "token":{
       "uid":"9392b9d6-d182-4072-8608-17d8ff7019de",
       "id":"301ca544-b8c4-42c7-8da1-ff2d76351020",
       "token":"h1MgJq0DUR2sXxI...",
       "tokenExpiry":1534412805941,
       "cookieExpiry":"2018-08-16T09:46:45.941Z"}
    ...
    }
    
       API token, (client created with LOGIN token) Get an API token for a newly created user using the login token 
    JSONObject authorization = client.create("authorization",
    
      ImmutableMap.of(
        "type" , "api"
      ));
    System.out.println("Success! %s%n", authorization);
    
       API token, (client created with LOGIN token) Get an API token for a newly created user using the login token 
    dynamic properties = new ExpandoObject();
    properties.type = "api";
    
    dynamic authorization = client.create("authorization",    properties);
    Console.WriteLine("Success!", authorization);
    
       API token, (client created with LOGIN token) Get an API token for a newly created user using the login token 
    client.create('authorization',
      {
        type: 'api'
      }
    )
      .then(function(authorization) {
        console.log('Success!', authorization);
      });
    
       API token, (client created with LOGIN token) Get an API token for a newly created user using the login token 
    <?php
    $authorization = $client->create('authorization',
    
      array (
        'type' => 'api'
      )
    
    );
    print("Success! { $authorization }");
    ?>
    
       API token, (client created with LOGIN token) Get an API token for a newly created user using the login token 
    curl https://api.luzmo.com/0.1.0/authorization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_LOGIN_KEY",
      "token": "$LUZMO_LOGIN_TOKEN",
      "version": "0.1.0",
      "properties": {
        "type": "api"
      }
    }
    EOF
    
    
       API token, (client created with LOGIN token) Get an API token for a newly created user using the login token 
    authorization = client.create("authorization",
    {
        "type": "api"
    })
    print("Success! ", authorization)
    
       Embed token (client created with API token) An example showing how temporary Embed tokens can be requested for a specific user of your application.
    from luzmo.luzmo import Luzmo
    
    key = "Your Luzmo key"
    token = "Your Luzmo token"
    
    client = Luzmo(key, token, 
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    
    authorization = client.create("authorization", {
        "type": "embed",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "access": {
          "collections": [
            {
              "id": "< collection id >",
              "inheritRights": "use"
            }
          ],
          "datasets": [
            {
              "id": "< dataset id >",
              "rights": "use"
            }
          ],
          "dashboards":[
            {
              "id": "< dashboard id >",
              "rights": "use"
            }
          ]
        }
    });
    
       Embed token (client created with API token) An example showing how temporary Embed tokens can be requested for a specific user of your application.
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >", 
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","embed")
      .put("username", "< A unique and immutable identifier for your user >")
      .put("name", "< user name >")
      .put("email", "< user email >")
      .put("suborganization", "< a suborganization name >")
      .put("access", ImmutableList.of(
        ImmutableMap.of(
          "collections", ImmutableList.of(
            ImmutableMap.of(
              "id", "< collection id >",
              "inheritRights", "use"
            )
          ),
          "datasets", ImmutableList.of(
            ImmutableMap.of(
              "id", "< dataset id >",
              "rights", "use"
            )
          ),
          "dashboards", ImmutableList.of(
            ImmutableMap.of(
              "id", "< dashboard id >",
              "rights", "use"
            )
          )
        )
      ))
      .build()
    );
    
        Embed token (client created with API token) An example showing how temporary Embed tokens can be requested for a specific user of your application.
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "embed";
    properties.username = "< A unique and immutable identifier for your user >";
    properties.name = "< user name >";
    properties.email = "< user email >";
    properties.suborganization = "< a suborganization name >";
    properties.access = new List<Object> {
      new {
        collections = new List<Object> {
          new {
            id = "< collection id >",
            inheritRights = "use"
          }
        }
      },
      new {
        datasets = new List<Object> {
          new {
            id = "< dataset id >",
            rights = "use"
          }
        }
      },
      new {
        dashboards = new List<Object> {
          new {
            id = "< dashboard id >",
            rights = "use"
          }
        }
      },
    };
    
    dynamic authorization = client.create("authorization", properties);
    Console.WriteLine("Success!", authorization);
    
        Embed token (client created with API token) An example showing how temporary Embed tokens can be requested for a specific user of your application.
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: '< Your API key >',
        api_token: '< Your API token >',
        host: '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >'
    });
    
    let promise = client.create('authorization', {
      type: 'embed',
      username: '< A unique and immutable identifier for your user >',
      name: '< user name >',
      email: '< user email >',
      suborganization: '< suborganization name >',
      access: {
        collections: [
          {
            id: '< collection id >',
            inheritRights: 'use'
          }
        ],
        datasets: [
          {
            id: '< dataset id >',
            rights: 'use'
          }
        ],
        dashboards: [
          {
            id: '< dashboard id >',
            rights: 'use'
          }
        ]
      }
    });
    
    promise.then(function(result){
      // return the result to the client
    })
    
       Embed token (client created with API token) An example showing how temporary Embed tokens can be requested for a specific user of your application.
    <?php
    $client = Luzmo::initialize('< your API key >', '< your API token >',
     '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >');
    
    
    $authorization = $client->create('authorization', array(
      'type' => 'embed',
      'username' => "< A unique and immutable identifier for your user >",
      'name' => "< user name >",
      'email' => "< user email >",
      'suborganization' => "< a suborganization name >",
      'access' => array (
        'collections' => array(
          array(
            'id' => "<collection_id>",
            'inheritRights' => "use"
          )
        ),
        'datasets' => array(
          array(
            'id' => "<dataset_id>",
            'inheritRights' => "use"
          )
        ),
        'dashboards' => array(
          array(
            'id' => "<dashboard_id>",
            'inheritRights' => "use"
          )
        )
      )
    ));
    ?>
    
       Embed token (client created with API token) An example showing how temporary Embed tokens can be requested for a specific user of your application.
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "create",
      "version": "0.1.0",
      "key": "< your API key >",
      "token": "< your API token >",
      "properties": {
        "type": "embed",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "access": {
          "collections": [
            {
              "id": "<collection_id>",
              "inheritRights": "use"
            }
          ],
          "datasets": [
            {
              "id": "<dataset_id>",
              "rights": "use"
            }
          ],
          "dashboards":[
            {
              "id": "<dashboard_id>",
              "rights": "use"
            }
          ]
        }
      }
    }
    EOF
    
       Embed token (client created with API token) An example showing how temporary Embed access with a Parameter overrides can be used to dynamically apply filter(s) on all queries. To clear a Parameter, you should use using the special value {"clear": true}. Make sure to first create and set the Parameter in the Embed filters.
    from luzmo.luzmo import Luzmo
    
    key = "Your Luzmo API key"
    token = "Your Luzmo API token"
    
    client = Luzmo(key, token, 
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    
    authorization = client.create("authorization", {
        "type": "embed",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "access": {
          "collections": [
            {
              "id": "< collection id >",
              "inheritRights": "use"
            }
          ]
        },
        "parameter_overrides": {
          "< parameter-name>": "< value to filter to >",
          "< parameter name of parameter to clear >" : {
            "clear": true
          }
        }
    });
    
       Embed token (client created with API token) An example showing how temporary Embed access with a Parameter overrides can be used to dynamically apply filter(s) on all queries. To clear a Parameter, you should use using the special value ImmutableMap.of("clear", true). Make sure to first create and set the Parameter in the Embed filters.
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >", "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","embed")
      .put("username", "< A unique and immutable identifier for your user >")
      .put("name", "< user name >")
      .put("email", "< user email >")
      .put("suborganization", "< a suborganization name >")
      .put("access", ImmutableList.of(
        ImmutableMap.of(
          "collections", ImmutableList.of(
            ImmutableMap.of(
              "id", "< collection id >",
              "inheritRights", "use"
            )
          )
        )
      ))
      .put("parameter_overrides", ImmutableMap.builder()
        .put("Country"= ImmutableList.of(
          "Spain"
        ))
        .put("< parameter name >" = ImmutableList.of(
          "< value to apply >"
        ))
        .put("< parameter to clear >" = ImmutableMap.of(
          "clear", true
        ))
        .build()
      )
      .build()
    );
    
       Embed token (client created with API token) An example showing how temporary Embed access with a Parameter overrides can be used to dynamically apply filter(s) on all queries. To clear a Parameter, you should use using the special value new {"clear" = true}. Make sure to first create and set the Parameter in the Embed filters.
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    
    dynamic properties = new ExpandoObject();
    properties.type = "embed";
    properties.username = "< A unique and immutable identifier for your user >";
    properties.name = "< user name >";
    properties.email = "< user email >";
    properties.suborganization = "< a suborganization name >";
    properties.access = new List<Object> {
      new {
        collections = new List<Object> {
          new {
            id = "< collection id >",
            inheritRights = "use"
          }
        }
      }
    };
    properties.parameter_overrides = new{
      parameter_name = new List<String>{
        "< value to apply >"
      },
      " < parameter to clear >" = new {
        clear = true
      }
    };
    
    dynamic authorization = client.create("authorization", properties);
    Console.WriteLine("Success!", authorization);
    
       Embed token (client created with API token) An example showing how temporary Embed access with a Parameter overrides can be used to dynamically apply filter(s) on all queries. To clear a Parameter, you should use using the special value {clear: true}. Make sure to first create and set the Parameter in the Embed filters.
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: '< Your API key >',
        api_token: '< Your API token >',
        host: '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >'
    });
    
    let promise = client.create('authorization', {
      type: 'embed',
      username: '< A unique and immutable identifier for your user >',
      name: '< user name >',
      email: '< user email >',
      suborganization: '< suborganization name >',
      access: {
        collections: [
          {
            id: '< collection id >',
            inheritRights: 'use'
          }
        ]
      },
      parameter_overrides: {
        "< parameter name >": ["< value to apply >"],
        '< parameter to clear >': {
          clear: true
        }
      }
    });
    
    promise.then(function(result){
      // return the result to the client
    })
    
       Embed token (client created with API token) An example showing how temporary Embed access with a Parameter overrides can be used to dynamically apply filter(s) on all queries. To clear a Parameter, you should use using the special value array("clear" => true). Make sure to first create and set the Parameter in the Embed filters.
    <?php
    $client = Luzmo::initialize('< your API key >', '< your API token >',
     '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >');
    
    $authorization = $client->create('authorization', array(
      'type' => 'embed',
      'username' => "< A unique and immutable identifier for your user >",
      'name' => "< user name >",
      'email' => "< user email >",
      'suborganization' => "< a suborganization name >",
      'access' => array (
        'collections' => array(
          array(
            'id' => "<collection_id>",
            'inheritRights' => "use"
          )
        )
      ),
      'parameter_overrides' => array(
        '< parameter name >' => array(
          "< value to apply >"
        ),
        '< parameter to clear >' => array (
          'clear' => true
        )
      )
    ));
    ?>
    
       Embed token (client created with API token) An example showing how temporary Embed access with a Parameter overrides can be used to dynamically apply filter(s) on all queries. To clear a Parameter, you should use using the special value {"clear", true}. Make sure to first create and set the Parameter in the Embed filters.
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "create",
      "version": "0.1.0",
      "key": "< your API key >",
      "token": "< your API token >",
      "properties": {
        "type": "embed",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "access": {
          "collections": [
            {
              "id": "<collection_id>",
              "inheritRights": "use"
            }
          ]
        },
        "parameter_overrides": {
          "Country": ["Spain"],
          "< parameter name >": [
            "< value to apply >",
            "< other value to apply >"
          ],
          "< parameter to clear >": {
            "clear": true
          }
        }
      }
    }
    EOF
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with a global filter. A global filter is a filter that has effect on every query referencing that dataset.
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","embed")
      .put("username", "< A unique and immutable identifier for your user >")
      .put("name", "< user name >")
      .put("email", "< user email >")
      .put("suborganization", "< a suborganization name >")
      .put("access", ImmutableList.of(
        ImmutableMap.of(
          "collections", ImmutableList.of(
            ImmutableMap.of(
              "id", "< collection id >",
              "inheritRights", "use"
            )
          )
        )
      ))
      .put("filters", ImmutableList.of(
        ImmutableMap.builder()
        .put("clause",       "where")
        .put("origin",       "global")
        .put("securable_id", "< dataset id of a dataset used in the dashboard >")
        .put("column_id",    "< column id of a column in a dataset used in the dashboard >")
        .put("expression",   "? = ?")
        .put("value",        "< value to be applied to the expression >")
        .build()
      ))
      .build()
    );
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with a global filter. A global filter is a filter that has effect on every query referencing that dataset.
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "embed";
    properties.username = "< A unique and immutable identifier for your user >";
    properties.name = "< user name >";
    properties.email = "< user email >";
    properties.suborganization = "< a suborganization name >";
    properties.access = new List<Object> {
      new {
        collections = new List<Object> {
          new {
            id = "< collection id >",
            inheritRights = "use"
          }
        }
      }
    };
    properties.filters = new List<dynamic> {
      new {
        clause = "where",
        origin = "global",
        securable_id = "< dataset id of a dataset used in the dashboard >",
        column_id = "< column id of a column in a dataset used in the dashboard >",
        expression = "? = ?",
        value = "< value to be applied to the expression >"
      }
    };
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with a global filter. A global filter is a filter that has effect on every query referencing that dataset.
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: '< Your API key >',
        api_token: '< Your API token >',
        host: '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >'
    });
    
    let promise = client.create('authorization', {
      type: 'embed',
      username: '< A unique and immutable identifier for your user >',
      name: '< user name >',
      email: '< user email >',
      suborganization: '< suborganization name >',
      access: {
        collections: [
          {
            id: '< collection id >',
            inheritRights: 'use'
          }
        ]
      },
      filters: [
        {
          clause: 'where',
          origin: 'global',
          securable_id: '< dataset id of a dataset used in the dashboard >',
          column_id: '< column id of a column in a dataset used in the dashboard >',  
          expression: '? = ?',
          value: '< value to be applied to the expression >'
        }
      ]
    });
    
    promise.then(function(result){
      // return the result to the client
    })
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with a global filter. A global filter is a filter that has effect on every query referencing that dataset.
    <?php
    $client = Luzmo::initialize('< your API key >', '< your API token >',
     '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >');
    
    
    $authorization = $client->create('authorization', array(
      'type' => 'embed',
      'username' => "< A unique and immutable identifier for your user >",
      'name' => "< user name >",
      'email' => "< user email >",
      'suborganization' => "< a suborganization name >",
      'access' => array (
        'collections' => array(
          array(
            'id' => "<collection_id>",
            'inheritRights' => "use"
          )
        )
      ),
      'filters' => array(
        array(
          'clause'       => 'where',
          'origin'       => 'global',
          'securable_id' => '< dataset id of a dataset used in the dashboard >',
          'column_id'    => '< column id of a column in a dataset used in the dashboard >',
          'expression'   => '? = ?',
          'value'        => '< value to be applied to the expression >'
        )
      ),
    ));
    ?>
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with a global filter. A global filter is a filter that has effect on every query referencing that dataset.
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "< your API key >",
      "token": "< your API token >",
      "properties":{
        "type": "embed",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "access": {
          "collections": [
            {
              "id": "<collection_id>",
              "inheritRights": "use"
            }
          ]
        },
        "filters": [
          {
            "clause": "where",
            "origin": "global",
            "securable_id": "< dataset id of a dataset used in the dashboard >",
            "column_id": "< column id of a column in a dataset used in the dashboard >",  
            "expression": "? = ?",
            "value": "< value to be applied to the expression >"
          }
        ]
      }
    }
    EOF
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with a chart filter. A chart filter is a filter that is only applied on the query for that specific widget in the specified dashboard.
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >", 
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","embed")
      .put("username", "< A unique and immutable identifier for your user >")
      .put("name", "< user name >")
      .put("email", "< user email >")
      .put("suborganization", "< a suborganization name >")
      .put("access", ImmutableList.of(
        ImmutableMap.of(
          "collections", ImmutableList.of(
            ImmutableMap.of(
              "id", "< collection id >",
              "inheritRights", "use"
            )
          )
        )
      ))
      .put("filters", ImmutableList.of(
        ImmutableMap.builder()
        .put("clause",       "where")
        .put("origin",       "chart")
        .put("securable_id", "< dataset id of a dataset used in the dashboard >")
        .put("column_id",    "< column id of a column in a dataset used in the dashboard >")
        .put("chart_id",     "< chart id of an object contained in the dashboard >")
        .put("expression",   "? = ?")
        .put("value",        "< value to be applied to the expression >")
        .build()
      ))
      .build()
    );
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with a chart filter. A chart filter is a filter that is only applied on the query for that specific widget in the specified dashboard.
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "embed";
    properties.username = "< A unique and immutable identifier for your user >";
    properties.name = "< user name >";
    properties.email = "< user email >";
    properties.suborganization = "< a suborganization name >";
    properties.access = new List<Object> {
      new {
        collections = new List<Object> {
          new {
            id = "< collection id >",
            inheritRights = "use"
          }
        }
      }
    };
    properties.filters = new List<dynamic> {
      new {
        clause = "where",
        origin = "chart",
        securable_id = "< dataset id of a dataset used in the dashboard >",
        column_id = "< column id of a column in a dataset used in the dashboard >",
        chart_id = "< chart id of an object contained in the dashboard >",
        expression = "? = ?",
        value = "< value to be applied to the expression >"
      }
    };
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with a chart filter. A chart filter is a filter that is only applied on the query for that specific widget in the specified dashboard.
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: '< Your API key >',
        api_token: '< Your API token >',
        host: '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >'
    });
    
    let promise = client.create('authorization', {
      type: 'embed',
      username: '< A unique and immutable identifier for your user >',
      name: '< user name >',
      email: '< user email >',
      suborganization: '< suborganization name >',
      access: {
        collections: [
          {
            id: '< collection id >',
            inheritRights: 'use'
          }
        ]
      },
      filters: [
        {
          clause: 'where',
          origin: 'chart',
          securable_id: '< dataset id of a dataset used in the dashboard >',
          column_id: '< column id of a column in a dataset used in the dashboard >',  
          chart_id: '< chart id of an object contained in the dashboard >',
          expression: '? = ?',
          value: '< value to be applied to the expression >'
        }
      ]
    });
    
    promise.then(function(result){
      // return the result to the client
    })
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with a chart filter. A chart filter is a filter that is only applied on the query for that specific widget in the specified dashboard.
    <?php
    $client = Luzmo::initialize('< your API key >', '< your API token >',
     '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >');
    
    
    $authorization = $client->create('authorization', array(
      'type' => 'embed',
      'username' => "< A unique and immutable identifier for your user >",
      'name' => "< user name >",
      'email' => "< user email >",
      'suborganization' => "< a suborganization name >",
      'access' => array (
        'collections' => array(
          array(
            'id' => "<collection_id>",
            'inheritRights' => "use"
          )
        )
      ),
      'filters' => array(
        array(
          'clause'       => 'where',
          'origin'       => 'chart',
          'securable_id' => '< dataset id of a dataset used in the dashboard >',
          'column_id'    => '< column id of a column in a dataset used in the dashboard >',  
          'chart_id'     => '< chart id of an object contained in the dashboard >',
          'expression'   => '? = ?',
          'value'        => '< value to be applied to the expression >'
        )
      ),                      
    ));
    ?>
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with a chart filter. A chart filter is a filter that is only applied on the query for that specific widget in the specified dashboard.
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "< your API key >",
      "token": "< your API token >",
      "properties":{
        "type": "embed",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "access": {
          "collections": [
            {
              "id": "<collection_id>",
              "inheritRights": "use"
            }
          ]
        },
        "filters": [
          {
            clause: "where",
            origin: "chart",
            securable_id: "< dataset id of a dataset used in the dashboard >",
            column_id: "< column id of a column in a dataset used in the dashboard >",  
            chart_id: "< chart id of an object contained in the dashboard >",
            expression: "? = ?",
            value: "< value to be applied to the expression >"
          }
        ]
      }
    }
    EOF
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with an initialization filter. An initialization filter is a type of filter that initializes a preselection in a certain filter object (slider, search and select box, ...) in an embedded dashboard. This means that the specified filter will be applied when the dashboard loads, but it can still be modified afterwards by user selection.
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >", 
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","sso")
      .put("expiry", "24 hours")
      .put("inactivity_interval", "10 minutes")
      .put("username", "< A unique and immutable identifier for your user >")
      .put("name", "< user name >")
      .put("email", "< user email >")
      .put("suborganization", "< a suborganization name >")
      .put("integration_id", "< integration id >")
      .put("role", "viewer")
      .put("filters", ImmutableList.of(
        ImmutableMap.builder()
        .put("clause",       "where")
        .put("origin",       "initialization")
        .put("chart_id",     "< chart id of a filter object contained in the dashboard >")
        .put("expression",   "? = ?")
        .put("value",        "< value to be applied to the expression >")
        .build()
      ))
      .build()
    );
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with an initialization filter. An initialization filter is a type of filter that initializes a preselection in a certain filter object (slider, search and select box, ...) in an embedded dashboard. This means that the specified filter will be applied when the dashboard loads, but it can still be modified afterwards by user selection.
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "sso";
    properties.expiry = "24 hours";
    properties.inactivity_interval = "10 minutes";
    properties.username = "< A unique and immutable identifier for your user >";
    properties.name = "< user name >";
    properties.email = "< user email >";
    properties.suborganization = "< a suborganization name >";
    properties.integration_id = "< integration id >";
    properties.role = "viewer";
    properties.filters = new List<dynamic> {
      new {
        clause = "where",
        origin = "initialization",
        chart_id = "< chart id of a filter object contained in the dashboard >",
        expression = "? = ?",
        value = "< value to be applied to the expression >"
      }
    };
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with an initialization filter. An initialization filter is a type of filter that initializes a preselection in a certain filter object (slider, search and select box, ...) in an embedded dashboard. This means that the specified filter will be applied when the dashboard loads, but it can still be modified afterwards by user selection.
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: '< Your API key >',
        api_token: '< Your API token >',
        host: '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >'
    });
    
    let promise = client.create('authorization', {
      type: 'sso',
      expiry: '24 hours',
      inactivity_interval: '10 minutes',
      username: "< A unique and immutable identifier for your user >",
      name: "< user name >",
      email: "< user email >",
      suborganization: "< a suborganization name >",
      integration_id: "< integration id >",
      role: "viewer",
        {
          clause: 'where',
          origin: 'initialization',
          chart_id: '< chart id of a filter object contained in the dashboard >',
          expression: '? = ?',
          value: '< value to be applied to the expression >'
        }
      ]
    });
    
    promise.then(function(result){
      // return the result to the client
    })
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with an initialization filter. An initialization filter is a type of filter that initializes a preselection in a certain filter object (slider, search and select box, ...) in an embedded dashboard. This means that the specified filter will be applied when the dashboard loads, but it can still be modified afterwards by user selection.
    <?php
    $client = Luzmo::initialize('< your API key >', '< your API token >',
     '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >');
    
    
    $authorization = $client->create('authorization', array(
      'type' => 'sso',
      'expiry' => '24 hours',
      'inactivity_interval' => '10 minutes',
      'username' => "< A unique and immutable identifier for your user >",
      'name' => "< user name >",
      'email' => "< user email >",
      'suborganization' => "< a suborganization name >",
      'integration_id' => "< integration id >",
      'role' => "viewer",
      'filters' => array(
        array(
          'clause'     => 'where',
          'origin'     => 'initialization',
          'chart_id'   => '< chart id of a filter object contained in the dashboard >',
          'expression' => '? = ?',
          'value'      => '< value to be applied to the expression >'
        )
      ),                      
    ));
    ?>
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with an initialization filter. An initialization filter is a type of filter that initializes a preselection in a certain filter object (slider, search and select box, ...) in an embedded dashboard. This means that the specified filter will be applied when the dashboard loads, but it can still be modified afterwards by user selection.
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "< your API key >",
      "token": "< your API token >",
      "properties":{
        "type": "sso",
        "expiry": "24 hours",
        "inactivity_interval": "10 minutes",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "integration_id": "< integration id >",
        "role": "viewer",
        "filters": [
          {
            clause: "where",
            origin: "initialization",
            chart_id: "< chart id of a filter object contained in the dashboard >",
            expression: "? = ?",
            value: "< value to be applied to the expression >"
          }
        ]
      }
    }
    EOF
    
         Embed token (client created with API token) An example showing how temporary Embed access can be granted with an initialization filter. In this case, the initialization filter is a type initializes a preselection in a certain chart widget (line chart, column chart, ...) in an embedded dashboard. This means that the specified filter will be applied when the dashboard loads, but it can still be modified afterwards by user selection. In this case you need to supply a column_id and securable_id of the column on which a filter selection can happen (e.g. the group-by slot, x-axis, etc.). Filter values always need to consist of an array.
    
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >", 
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","embed")
      .put("username", "< A unique and immutable identifier for your user >")
      .put("name", "< user name >")
      .put("email", "< user email >")
      .put("suborganization", "< a suborganization name >")
      .put("access", ImmutableList.of(
        ImmutableMap.of(
          "collections", ImmutableList.of(
            ImmutableMap.of(
              "id", "< collection id >",
              "inheritRights", "use"
            )
          )
        )
      ))
      .put("filters", ImmutableList.of(
        ImmutableMap.builder()
        .put("clause",       "where")
        .put("origin",       "initialization")
        .put("chart_id",     "< chart id of a chart object contained in the dashboard >")
        .put("expression",   "? = ?")
        .put("column_id",    "< id of the column you want to filter on (usually in category slot) >")
        .put("securable_id", "< id of the dataset that the column belongs to >")
        .put("value",        ImmutableList.of(
          "<value to be applied to the expression>"
        ))
        .build()
      ))
      .build()
    );
    
         Embed token (client created with API token) An example showing how temporary Embed access can be granted with an initialization filter. In this case, the initialization filter is a type initializes a preselection in a certain chart widget (line chart, column chart, ...) in an embedded dashboard. This means that the specified filter will be applied when the dashboard loads, but it can still be modified afterwards by user selection. In this case you need to supply a column_id and securable_id of the column on which a filter selection can happen (e.g. the group-by slot, x-axis, etc.). Filter values always need to consist of an array.
    
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "embed";
    properties.username = "< A unique and immutable identifier for your user >";
    properties.name = "< user name >";
    properties.email = "< user email >";
    properties.suborganization = "< a suborganization name >";
    properties.access = new List<Object> {
      new {
        collections = new List<Object> {
          new {
            id = "< collection id >",
            inheritRights = "use"
          }
        }
      }
    };
    properties.filters = new List<dynamic> {
      new {
        clause = "where",
        origin = "initialization",
        chart_id = "< chart id of a chart object contained in the dashboard >",
        expression = "? = ?",
        column_id = "< id of the column to apply the filter to (usually the category) >",
        securable_id = "< id of the dataset that the column belongs to >",
        value = new List<string> {
          "< value to be applied to the expression >"
        }
      }
    };
    
         Embed token (client created with API token) An example showing how temporary Embed access can be granted with an initialization filter. In this case, the initialization filter is a type initializes a preselection in a certain chart widget (line chart, column chart, ...) in an embedded dashboard. This means that the specified filter will be applied when the dashboard loads, but it can still be modified afterwards by user selection. In this case you need to supply a column_id and securable_id of the column on which a filter selection can happen (e.g. the group-by slot, x-axis, etc.). Filter values always need to consist of an array.
    
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: '< Your API key >',
        api_token: '< Your API token >',
        host: '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >'
    });
    
    let promise = client.create('authorization', {
      type: 'embed',
      username: '< A unique and immutable identifier for your user >',
      name: '< user name >',
      email: '< user email >',
      suborganization: '< suborganization name >',
      access: {
        collections: [
          {
            id: '< collection id >',
            inheritRights: 'use'
          }
        ]
      },
      filters: [
        {
          clause: 'where',
          origin: 'initialization',
          chart_id: '< chart id of a chart object contained in the dashboard >',
          expression: '? = ?',
          column_id: '< id of the column to apply the filter to (usually the category) >',
          securable_id: '< id of the dataset that the column belongs to >',
          value: [
            '< value to be applied to the expression >'
          ]
        }
      ]
    });
    
    promise.then(function(result){
      // return the result to the client
    })
    
         Embed token (client created with API token) An example showing how temporary Embed access can be granted with an initialization filter. In this case, the initialization filter is a type initializes a preselection in a certain chart widget (line chart, column chart, ...) in an embedded dashboard. This means that the specified filter will be applied when the dashboard loads, but it can still be modified afterwards by user selection. In this case you need to supply a column_id and securable_id of the column on which a filter selection can happen (e.g. the group-by slot, x-axis, etc.). Filter values always need to consist of an array.
    
    <?php
    $client = Luzmo::initialize('< your API key >', '< your API token >',
     '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >');
    
    
    $authorization = $client->create('authorization', array(
      'type' => 'embed',
      'username' => "< A unique and immutable identifier for your user >",
      'name' => "< user name >",
      'email' => "< user email >",
      'suborganization' => "< a suborganization name >",
      'access' => array (
        'collections' => array(
          array(
            'id' => "<collection_id>",
            'inheritRights' => "use"
          )
        )
      ),
      'filters' => array(
        array(
          'clause'       => 'where',
          'origin'       => 'initialization',
          'chart_id'     => '< chart id of a chart object contained in the dashboard >',
          'expression'   => '? = ?',
          'column_id'    => '< id of the column to apply the filter to (usually the category) >',
          'securable_id' => '< id of the dataset that the column belongs to >'
          'value'        => array(
            '< value to be applied to the expression >'
          )
        )
      ),                      
    ));
    ?>
    
       Embed token (client created with API token) An example showing how temporary Embed access can be granted with an initialization filter. In this case, the initialization filter is a type initializes a preselection in a certain chart widget (line chart, column chart, ...) in an embedded dashboard. This means that the specified filter will be applied when the dashboard loads, but it can still be modified afterwards by user selection. In this case you need to supply a column_id and securable_id of the column on which a filter selection can happen (e.g. the group-by slot, x-axis, etc.). Filter values always need to consist of an array.
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "< your API key >",
      "token": "< your API token >",
      "properties":{
        "type": "embed",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "access": {
          "collections": [
            {
              "id": "<collection_id>",
              "inheritRights": "use"
            }
          ]
        },
        "filters": [
          {
            clause: "where",
            origin: "initialization",
            chart_id: "< chart id of a chart object contained in the dashboard >",
            expression: "? = ?",
            column_id: '< id of the column to apply the filters to >',
            securable_id: '< id of the dataset that the column belongs to >',
            value: [
              "< value to be applied to the expression >"
            ]
          }
        ]
      }
    }
    EOF
    
       Embed tokenAn example showing how to apply theme overrides to an Embed token.
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >", 
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","embed")
      .put("username", "< A unique and immutable identifier for your user >")
      .put("name", "< user name >")
      .put("email", "< user email >")
      .put("suborganization", "< a suborganization name >")
      .put("access", ImmutableList.of(
        ImmutableMap.of(
          "collections", ImmutableList.of(
            ImmutableMap.of(
              "id", "< collection id >",
              "inheritRights", "use"
            )
          )
        )
      ))
      .put("theme", ImmutableMap.of(
          ... JSON theme definition ...
        )
      )
    ));
    System.out.println("Success! %s%n", authorization);
    
         Embed token   An example showing how to apply theme overrides to an Embed token.
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    dynamic theme = new ExpandoObject();
    
    // Create theme definition here
    // ...
    
    properties.type = "embed";
    properties.username = "< A unique and immutable identifier for your user >";
    properties.name = "< user name >";
    properties.email = "< user email >";
    properties.suborganization = "< a suborganization name >";
    properties.access = new List<Object> {
      new {
        collections = new List<Object> {
          new {
            id = "< collection id >",
            inheritRights = "use"
          }
        }
      }
    };
    properties.theme = theme;
    
    
    dynamic authorization = client.create("authorization",    properties);
    Console.WriteLine("Success!", authorization);
    
         Embed token   An example showing how to apply theme overrides to an Embed token.
    
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: '< Your API key >',
        api_token: '< Your API token >',
        host: '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >'
    });
    
    let promise = client.create('authorization', {
      type: 'embed',
      username: '< A unique and immutable identifier for your user >',
      name: '< user name >',
      email: '< user email >',
      suborganization: '< suborganization name >',
      access: {
        collections: [
          {
            id: '< collection id >',
            inheritRights: 'use'
          }
        ]
      },
      theme: { ... theme definition }
    })
      .then(function(authorization) {
        console.log('Success!', authorization);
      });
    
         Embed token  An example showing how to apply theme overrides to an Embed token.
    
    <?php
    $client = Luzmo::initialize('< your API key >', '< your API token >',
     '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >');
    
    
    $authorization = $client->create('authorization', array(
      'type' => 'embed',
      'username' => "< A unique and immutable identifier for your user >",
      'name' => "< user name >",
      'email' => "< user email >",
      'suborganization' => "< a suborganization name >",
      'access' => array (
        'collections' => array(
          array(
            'id' => "<collection_id>",
            'inheritRights' => "use"
          )
        )
      ),
      'theme' => array(
        ... JSON theme definition ...
      ),
      'metadata' => array (
        'internalid' => 'user19'
      )
    ));
    print("Success! { $authorization }");
    ?>
    
         Embed token   An example showing how to apply theme overrides to an Embed token.
    
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "< your API key >",
      "token": "< your API token >",
      "properties":{
        "type": "embed",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "access": {
          "collections": [
            {
              "id": "<collection_id>",
              "inheritRights": "use"
            }
          ]
        },
        "theme": {
          ... JSON theme definition ...
        },
        "metadata": {
          "internalid": "user19"
        }
      }
    }
    EOF
    
    
         Embed token  An example showing how to apply CSS overrides to an Embed token. Provided CSS is appended to the existing CSS overrides in the dashboard.
    
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >", 
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","embed")
      .put("username", "< A unique and immutable identifier for your user >")
      .put("name", "< user name >")
      .put("email", "< user email >")
      .put("suborganization", "< a suborganization name >")
      .put("access", ImmutableList.of(
        ImmutableMap.of(
          "collections", ImmutableList.of(
            ImmutableMap.of(
              "id", "< collection id >",
              "inheritRights", "use"
            )
          )
        )
      ))
      .put("css", "body { background-color: red !important; }")
    ));
    System.out.println("Success! %s%n", authorization);
    
         Embed token   An example showing how to apply CSS overrides to an Embed token. Provided CSS is appended to the existing CSS overrides in the dashboard.  
    
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "embed";
    properties.username = "< A unique and immutable identifier for your user >";
    properties.name = "< user name >";
    properties.email = "< user email >";
    properties.suborganization = "< a suborganization name >";
    properties.access = new List<Object> {
      new {
        collections = new List<Object> {
          new {
            id = "< collection id >",
            inheritRights = "use"
          }
        }
      }
    };
    properties.css = "body { background-color: red !important; }";
    
    dynamic authorization = client.create("authorization",    properties);
    Console.WriteLine("Success!", authorization);
    
         Embed token   An example showing how to apply CSS overrides to an Embed token. Provided CSS is appended to the existing CSS overrides in the dashboard.  
    
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: '< Your API key >',
        api_token: '< Your API token >',
        host: '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >'
    });
    
    let promise = client.create('authorization', {
      type: 'embed',
      username: '< A unique and immutable identifier for your user >',
      name: '< user name >',
      email: '< user email >',
      suborganization: '< suborganization name >',
      access: {
        collections: [
          {
            id: '< collection id >',
            inheritRights: 'use'
          }
        ]
      },
      css: 'body { background-color: red !important; }'
    })
      .then(function(authorization) {
        console.log('Success!', authorization);
      });
    
         Embed token  An example showing how to apply CSS overrides to an Embed token. Provided CSS is appended to the existing CSS overrides in the dashboard.
    
    <?php
    $client = Luzmo::initialize('< your API key >', '< your API token >',
     '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >');
    
    
    $authorization = $client->create('authorization', array(
      'type' => 'embed',
      'username' => "< A unique and immutable identifier for your user >",
      'name' => "< user name >",
      'email' => "< user email >",
      'suborganization' => "< a suborganization name >",
      'access' => array (
        'collections' => array(
          array(
            'id' => "<collection_id>",
            'inheritRights' => "use"
          )
        )
      ),
      'css' => 'body { background-color: red !important; }'
    ));
    print("Success! { $authorization }");
    ?>
    
         Embed token  An example showing how to apply CSS overrides to an Embed token. Provided CSS is appended to the existing CSS overrides in the dashboard.
    
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "< your API key >",
      "token": "< your API token >",
      "properties":{
        "type": "embed",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "access": {
          "collections": [
            {
              "id": "<collection_id>",
              "inheritRights": "use"
            }
          ]
        },
        "css": "body { background-color: red !important; }"
      }
    }
    EOF
    
    
         SSO token An example showing how to apply dataset connection overrides by overriding the host property of your standard connector (database) account.
    
    from luzmo.luzmo import Luzmo
    
    key = "Your Luzmo key"
    token = "Your Luzmo token"
    
    client = Luzmo(key, token, 
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >")
    
    authorization = client.create("authorization", {
        "type": "embed",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "access": {
          "collections": [
            {
              "id": "< collection id >",
              "inheritRights": "use"
            }
          ]
        },
        "account_overrides": { 
          "< Your account_id >" : {
            "host": "< The new database host to connect to. >"
          }
        }
    });
    
         Embed token An example showing how to apply dataset level overrides using account_overrides.
    
    import org.json.JSONObject;
    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.ImmutableMap;
    
    private Luzmo client = new Luzmo("< Your API key >","< Your API token >", 
    "< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >");
    
    private JSONObject authorization = client.create("authorization", ImmutableMap.builder()
      .put("type","embed")
      .put("username", "< A unique and immutable identifier for your user >")
      .put("name", "< user name >")
      .put("email", "< user email >")
      .put("suborganization", "< a suborganization name >")
      .put("access", ImmutableList.of(
        ImmutableMap.of(
          "collections", ImmutableList.of(
            ImmutableMap.of(
              "id", "< collection id >",
              "inheritRights", "use"
            )
          )
        )
      ))
      .put("account_overrides", ImmutableMap.of(
        ImmutableMap.of(
          "< account ID >" , ImmutableMap.of(
            "datasets", ImmutableMap.of(
              "< dataset ID >", ImmutableMap.of(
                "table": "< my new table name >"
              )
            )
          )
        )
      )
      .build()
    );
    
    System.out.println("Success! %s%n", authorization);
    
         Embed token An example showing how to apply dataset level overrides using account_overrides.
    
    Luzmo client = new Luzmo("< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >",
    "< Your API key >", "< Your API token >");
    
    dynamic properties = new ExpandoObject();
    properties.type = "embed";
    properties.username = "< A unique and immutable identifier for your user >";
    properties.name = "< user name >";
    properties.email = "< user email >";
    properties.suborganization = "< a suborganization name >";
    properties.access = new List<Object> {
      new {
        collections = new List<Object> {
          new {
            id = "< collection id >",
            inheritRights = "use"
          }
        }
      }
    };
    properties.account_overrides = new {
      < account ID > = new {
        datasets = new {
          < dataset ID > = new {
            table = "< my new table name >"
          }
        }
      }
    };
    
    dynamic authorization = client.create("authorization", properties);
    Console.WriteLine("Success!", authorization);
    
         Embed token An example showing how to apply dataset level overrides using account_overrides.
    
    const Luzmo = require('@luzmo/nodejs-sdk');
    var client = new Luzmo({
        api_key: '< Your API key >',
        api_token: '< Your API token >',
        host: '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >'
    });
    
    client.create('authorization', {
      type: 'embed',
      username: '< A unique and immutable identifier for your user >',
      name: '< user name >',
      email: '< user email >',
      suborganization: '< suborganization name >',
      access: {
        collections: [
          {
            id: '< collection id >',
            inheritRights: 'use'
          }
        ]
      },
      account_overrides: { 
        '< account ID >': {
          datasets: {
            '< dataset ID >': {
              table: '< my new table name >'
            }
          }
        }
      }
    });
    
         Embed token An example showing how to apply dataset level overrides using account_overrides.
    
    <?php
    $client = Luzmo::initialize('< your API key >', '< your API token >',
     '< https://api.luzmo.com (default) or https://api.us.luzmo.com/ or your VPC-specific address >');
    
    $authorization = $client->create('authorization', array(
      'type' => 'embed',
      'username' => "< A unique and immutable identifier for your user >",
      'name' => "< user name >",
      'email' => "< user email >",
      'suborganization' => "< a suborganization name >",
      'access' => array (
        'collections' => array(
          array(
            'id' => "<collection_id>",
            'inheritRights' => "use"
          )
        )
      ),
      'account_overrides' => array (
        '< account ID >' => array (
          'datasets' => array (
            '< dataset ID >' => array (
              'table' => '< my new table name >'
            )
          )
        )
      )
    ));
    ?>
    
         Embed token An example showing how to apply dataset level overrides using account_overrides.
    
    curl https://api.luzmo.com/0.1.0/authorization \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action":"create",
      "version":"0.1.0",
      "key": "< your API key >",
      "token": "< your API token >",
      "properties":{
        "type": "embed",
        "username": "< A unique and immutable identifier for your user >",
        "name": "< user name >",
        "email": "< user email >",
        "suborganization": "< a suborganization name >",
        "access": {
          "collections": [
            {
              "id": "<collection_id>",
              "inheritRights": "use"
            }
          ]
        },
        "account_overrides": { 
          "< account ID >": {
            "datasets": {
              "< dataset ID >": {
                "table": "< my new table name >"
              }
            }
          }
        }
      }
    }
    EOF
    
    
    Create
    can be executed by:
    Logged-in User

    There are 3 types of tokens that you can create programmatically or manually:

    Login tokens These are the tokens reserved for real users when you are manually authenticating to the platform. Via the API you will only come into contact with them when you create a new user programmatically. A new user result will contain a login token, this login token can be exchanged to an API token.

    programmatic: the only way to create a new login token is to create a new user. Create User

    manual: login tokens can't be created manually

    API tokens API tokens can be used to programmatically create and update entities, push new data points or create temporary tokens

    programmatic: use a valid 'login' token to create an authorization token of type 'api'

    manual: create on the Integration management page

    Embed tokens Embed authorizations can be used to temporarily delegate access to one or more datasets and dashboards to e.g. an end-user within your own SaaS product. They can only be created with a valid API authorization. Embed tokens can have access restrictions to limit which securables can be accessed (via Collections, as well as directly to one or more dashboards and/or datasets), which data filters are automatically applied to all queries, the range of IP addresses that can get access, ...

      programmatic: use a valid 'api' token to create an authorization of type 'embed'

      manual: you cannot create embed tokens via the UI

    The table above shows that there are two options to get started with an API token. Either you create a new user and use the login token to get a new API token or you request an API token via the Integration management page. Embed tokens can then be created using this API token.

    Action: Get

       Retrieve all authorizations (to which you have access) that give access to a certain securable (dataset or dashboard) 
    JSONObject data = client.get("authorization", 
      ImmutableMap.of(
        "where", ImmutableMap.of(
          "securables", ImmutableMap.of(
            "like", "%<dataset id>%"
          )
        )
      )
    );
    
       Retrieve all authorizations (to which you have access) that give access to a certain securable (dataset or dashboard) 
    dynamic query = new ExpandoObject();
    query.where = new {
      securables = new {
        like = "%<dataset id>%"
      }
    };
    dynamic data = client.get("authorization", query);
    
       Retrieve all authorizations (to which you have access) that give access to a certain securable (dataset or dashboard) 
    let authorizations = await client.get('authorization', {
        where: {
            securables: {
                like: '%<dataset id>%'
            }
        }
    });
    
       Retrieve all authorizations (to which you have access) that give access to a certain securable (dataset or dashboard) 
    <?php
    $user = $client->get('authorization', 
      array (
        'where' => array (
          'securables' => array (
            'like' => '%<dataset id>%'
          )
        )
      )
    );
    ?>
    
       Retrieve all authorizations (to which you have access) that give access to a certain securable (dataset or dashboard) 
    curl https://api.luzmo.com/0.1.0/authorization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
        "where": {
          "securables": {
            "like": "%<dataset id>%"
          }
        }
      }
    }
    EOF
    
       Retrieve all authorizations (to which you have access) that give access to a certain securable (dataset or dashboard) 
    data = client.get("authorization", {
      "where": {
        "securables": {
          "like": "%<dataset id>%"
        }
      }
    })
    
       Retrieve all authorization of a certain type (to which you have access) 
    JSONObject data = client.get("authorization", 
      ImmutableMap.of(
        "where", ImmutableMap.of(
          "type", "api"
        )
      )
    );
    
       Retrieve all authorization of a certain type (to which you have access) 
    dynamic query = new ExpandoObject();
    query.where = new {
      type = "api"
    };
    dynamic data = client.get("authorization", query);
    
       Retrieve all authorization of a certain type (to which you have access) 
    let authorizations = await client.get('authorization', {
        where: {
            type: 'api'
        }
    });
    
       Retrieve all authorization of a certain type (to which you have access) 
    <?php
    $user = $client->get('authorization', 
      array (
        'where' => array (
          'type' => 'api'
        )
      )
    );
    ?>
    
       Retrieve all authorization of a certain type (to which you have access) 
    curl https://api.luzmo.com/0.1.0/authorization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
          "type": "api"
        }
      }
    }
    EOF
    
       Retrieve all authorization of a certain type (to which you have access) 
    data = client.get("authorization", {
      "where": {
        "type": "api"
      }
    })
    
       Example of the return structure of an authorization. 
    {
     "count": 1,
     "rows": [
        {
          "id": "c6dcefe7-a0f8-4837-9050-ba4617691a28",
          "type": "api",
          "expiry": "9999-12-31T00:00:00.000Z",
          "ip": null,
          "securables": null,
          "filters": null,
          "screenmode": null,
          "width": null,
          "height": null,
          "user_id": "477086f8-2ad2-4e5f-8aaf-de209f69b9bb",
          "locale_id": null,
          "last_used_at": "2018-08-13T08:29:30.000Z",
          "created_at": "2018-08-13T08:29:30.099Z",
          "updated_at": "2018-08-13T08:29:30.099Z",
          "description": null,
          "deleted_at": null,
          "username": null,
          "name": null,
          "email": null,
          "metadata": null,
          "account_overrides": null
       }
      ]
    }
    
    Get
    can be executed by:
    Authorization Owner
    List
    can be executed by:
    Authorization Owner

    Authorization tokens can be fetched the same way as other resources types can be retrieved. However, you can only get the authorization tokens for which you are the entity owner (if you have created them, you are the entity owner by default), Besides of that you can not list login or temporary tokens, you can retrieve them if you know the specific id using a where clause.

    Action: Delete

       Deleting an authorization 
    client.delete("authorization", "<your authorization id>");
    
       Deleting an authorization 
    $client->delete("authorization", "<your authorization id>");
    
       Deleting an authorization 
    let promise = client.delete('authorization', '<your authorization id>');
    
       Deleting an authorization 
    <?php
    $client->delete('authorization', '<your authorization id>');
    ?>
    
       Deleting an authorization 
    curl https://api.luzmo.com/0.1.0/authorization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your authorization id>"
    }
    EOF
    
       Deleting an authorization 
    client.delete("authorization", "<your_authorization_id>")
    
    Delete
    can be executed by:
    Authorization Owner

    Delete is the same for each resource, the only parameters required are the resource type and the uuid of the entity you want to delete.

    Associations

    Authorizations are only connected to Locale and User. However, both associations are special cases since 'associate' or 'dissociate' are not available due to the immutability of authorizations.

    %3 <!-- User --> User User <!-- Authorization --> Authorization Authorization <!-- User->Authorization --> User->Authorization <!-- Locale --> Locale Locale <!-- Locale->Authorization --> Locale->Authorization

    Associate: Locale

       Example of the creation of an 'authorization' resource and immediately associating it to a locale using a locale_id 
    JSONObject authorization = client.create("authorization",
    
      ImmutableMap.of(
        "type" , "temporary",
        "securables" , ImmutableList.of(
          "< dashboard id >"
        )
      ));
    System.out.println("Success! %s%n", authorization);
    
       Example of the creation of an 'authorization' resource and immediately associating it to a locale using a locale_id 
    dynamic properties = new ExpandoObject();
    properties.type = "temporary";
    properties.securables = new List<Object> {
          "< dashboard id >"
        };
    
    dynamic authorization = client.create("authorization",    properties);
    Console.WriteLine("Success!", authorization);
    
       Example of the creation of an 'authorization' resource and immediately associating it to a locale using a locale_id 
    client.create('authorization',
      {
        type: 'temporary',
        securables: [
            '< dashboard id >'
        ]
    }
    
    )
      .then(function(authorization) {
        console.log('Success!', authorization);
      });
    
       Example of the creation of an 'authorization' resource and immediately associating it to a locale using a locale_id 
    <?php
    $authorization = $client->create('authorization',
    
      array (
        'type' => 'temporary',
        'securables' => array (
          '< dashboard id >'
        )
      )
    
    );
    print("Success! { $authorization }");
    ?>
    
       Example of the creation of an 'authorization' resource and immediately associating it to a locale using a locale_id 
    curl https://api.luzmo.com/0.1.0/authorization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "type": "temporary",
      "securables": [
        "< dashboard id >"
      ]
    }
    }
    EOF
    
    
    Authorization
    Locale
    Associate
    requires:
    Authorization Owner

    Connecting a locale to an authorization is implicit. Instead of creating an association, we set the locale_id directly in the properties which will create an association for us. By connecting a locale you can determine in which locale the user will see a dashboard when the token is used for embedding, to get more information on how to embed a dashboard refer to the Integration API

    Associate: User

       newly created associations are immediately associated with the user that created them, the response contains the user_id, this is the only way to associate users 
    JSONObject authorization = client.create("authorization",
    
      ImmutableMap.of(
        "type" , "temporary",
        "securables" , ImmutableList.of(
          "< dashboard id >"
        )
      ));
    System.out.printf("User id: %s%n", authorization.get("user_id"));
    
       newly created associations are immediately associated with the user that created them, the response contains the user_id, this is the only way to associate users 
    dynamic properties = new ExpandoObject();
    properties.type = "temporary";
    properties.securables = new List<Object> {
          "< dashboard id >"
        };
    
    dynamic authorization = client.create("authorization",    properties);
    
     Console.WriteLine("User id is {0}", authorization["user_id"]);
    
       newly created associations are immediately associated with the user that created them, the response contains the user_id, this is the only way to associate users 
    client.create('authorization',
      {
        type: 'temporary',
        securables: [
            '< dashboard id >'
        ]
    }
    
    )
      .then(function(authorization) {
        var user = authorization.user_id;
      });
    
       newly created associations are immediately associated with the user that created them, the response contains the user_id, this is the only way to associate users 
    <?php
    $authorization = $client->create('authorization',
    
      array (
        'type' => 'temporary',
        'securables' => array (
          '< dashboard id >'
        )
      )
    
    );
    print( $authorization['user_id'] );
    ?>
    
       newly created associations are immediately associated with the user that created them, the response contains the user_id, this is the only way to associate users 
    curl https://api.luzmo.com/0.1.0/authorization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "type": "temporary",
      "securables": [
        "< dashboard id >"
      ]
    }
    }
    EOF
    # result format of the authorization contains the user_id 
    {
     ... 
     "user_id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
      newly created associations are immediately associated with the user that created them, the response contains the user_id, this is the only way to associate users
    authorization = client.create("authorization",
    {
        "type": "temporary",
        "securables": ["< dashboard id >"]
    })
    print(authorization[user_id])
    
    Authorization
    User
    Associate
    requires:
    Authorization Owner

    When associating authorizations there are two things to keep in mind. First is that authorizations are immutable and thus the 'associate' call cannot be called directly. Secondly, the link between authorizations and users is implicit, while you can associate in the 'create' action as well, this is not possible for users. Authorizations are associated automatically. to the user who created them, you will never call the 'associate' call directly and cannot associate them to someone else than the creator.

    Column

    A column contains the metadata (type, name) of a specific column in a dataset.

    Properties

    Parameter
    Description
    id
    uuid
    Unique key of the column (automatically assigned)
    name
    localized
    Column name
    order
    integer
    Sorting order of this column (eg. 0, 1, 2). This is a required field.
    source_name
    string
    The original name of the column. This property will be set automatically when uploading a dataset or when creating a dataset via the data push API. You can set it manually when creating a column via API, but the value cannot be changed afterwards.
    type
    string
    Column type (numeric, datetime, hierarchy or spatial). Can be modified at any time with immediate effect for all historical and new data.
    subtype
    string
    For columns of type spatial: indicates the subtype of the column. Can be either topography or coordinates.
    format
    string
    Default formatting, used to present data in charts or tables.
    informat
    string
    Default informat, used to interpret raw input data. Can be modified at any time with immediate effect for all historical and new data.
    • For numeric type: numeric or percentage
    • For hierarchy type: hierarchy
    • For datetime type, either:
      • YYYY-MM-DD HH:mm:ss.SSS (ISO-style)
      • MM-DD-YYYY HH:mm:ss.SSS (US-style)
      • DD-MM-YYYY HH:mm:ss.SSS (EU-style)
      • X (UNIX timestamp, seconds since 1/1/1970)
      • x (UNIX timestamp, milliseconds since 1/1/1970)
      The actual data can have a different input format (eg. different separators, named months, ...). The informat only indicates the order of parsing.
    hierarchy_enabled
    boolean
    When this boolean is set, hierarchies can be used in the dashboard editor and dashboards. If you are experimenting with Hierarchies you can keep this disabled until you want them to be visible/usable. If you only use hierarchies to override colors/names/ordering, keep it disabled. More information can be found in Hierarchy
    colors_enabled
    boolean
    When this boolean is set, colors set via the hierarchy endpoint will override colors in the dashboard. This allows you to add colors to data values to make sure that the dashboard colors are data driven. More information can be found in Hierarchy
    ordering_enabled
    boolean
    (Coming soon) You can set a custom order for values via the hierarchy which can be disabled/enabled using this boolean. These can then be used to override ordering in the dashboard. This feature is currently in progress Hierarchy
    color
    string
    Default color for the column, in hexadecimal string notation, eg. #45AB7C
    isLabel
    boolean
    Whether this column contains labels used for topographic features (eg. municipality names). Defaults to false.
    minBound
    datetime
    (Read-only) Smallest datetime over all rows
    maxBound
    datetime
    (Read-only) Largest datetime over all rows
    cardinality
    integer
    (Read-only) Number of distinct values within this column. Note: this value is approximate to within 1.625%.
    lowestLevel
    integer
    (Datetime only) Most precise datetime level used in the source data (1 - year, 9 - millisecond). The dashboard editor will only allow these levels to be used as slots.
    minimum
    integer
    (Read-only, numeric only) Smallest value over all rows
    maximum
    integer
    (Read-only, numeric only) Largest value over all rows
    expression
    string
    Derived column expression. Must be a valid expression.
    version
    integer
    (Read-only) Version indicator, increments on each change
    width
    integer
    Data table column header width (in pixels). Defaults to 170.

    Actions

    Create
    Get
    List
    Delete
    Update
    Associate
    Dissociate

    Action: Create

       Creating a column of type hierarchy, note that you need to provide a unique order index. In this case the order is 0 since we want our first column to appear first. 
    JSONObject column = client.create("column",
    
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "Burrito name"
        ),
        "type" , "hierarchy",
        "order" , "0",
        "format" , "",
        "informat" , "hierarchy",
        "color" , "#a945aa"
      ));
    System.out.println("Success! %s%n", column);
    
       Creating a column of type hierarchy, note that you need to provide a unique order index. In this case the order is 0 since we want our first column to appear first. 
    dynamic properties = new ExpandoObject();
    properties.name = new {
          en = "Burrito name"
        };
    properties.type = "hierarchy";
    properties.order = "0";
    properties.format = "";
    properties.informat = "hierarchy";
    properties.color = "#a945aa";
    
    dynamic column = client.create("column",    properties);
    Console.WriteLine("Success!", column);
    
       Creating a column of type hierarchy, note that you need to provide a unique order index. In this case the order is 0 since we want our first column to appear first. 
    client.create('column',
      {
        name: {
            en: 'Burrito name'
        },
        type: 'hierarchy',
        order: 0,
        format: '',
        informat: 'hierarchy',
        color: '#a945aa'
    }
    
    )
      .then(function(column) {
        console.log('Success!', column);
      });
    
       Creating a column of type hierarchy, note that you need to provide a unique order index. In this case the order is 0 since we want our first column to appear first. 
    <?php
    $column = $client->create('column',
    
      array (
        'name' => array (
          'en' => 'Burrito name'
        ),
        'type' => 'hierarchy',
        'order' => '0',
        'format' => '',
        'informat' => 'hierarchy',
        'color' => '#a945aa'
      )
    
    );
    print("Success! { $column }");
    ?>
    
       Creating a column of type hierarchy, note that you need to provide a unique order index. In this case the order is 0 since we want our first column to appear first. 
    curl https://api.luzmo.com/0.1.0/column  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "name": {
        "en": "Burrito name"
      },
      "type": "hierarchy",
      "order": 0,
      "format": "",
      "informat": "hierarchy",
      "color": "#a945aa"
    }
    }
    EOF
    
    
       Creating a date column, note that we use 1 as order since 0 is already taken and orders need to be unique. If we would use an overlapping index with the first column, the resulting dataset will not work properly. 
    JSONObject column = client.create("column",
    
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "Burrito production date"
        ),
        "type" , "datetime",
        "order" , "1",
        "format" , "%d-%m-%Y",
        "informat" , "YYYY-MM-DD HH:mm:ss.SSS"
      ));
    System.out.println("Success! %s%n", column);
    
       Creating a date column, note that we use 1 as order since 0 is already taken and orders need to be unique. If we would use an overlapping index with the first column, the resulting dataset will not work properly. 
    dynamic properties = new ExpandoObject();
    properties.name = new {
          en = "Burrito production date"
        };
    properties.type = "datetime";
    properties.order = "1";
    properties.format = "%d-%m-%Y";
    properties.informat = "YYYY-MM-DD HH:mm:ss.SSS";
    
    dynamic column = client.create("column",    properties);
    Console.WriteLine("Success!", column);
    
       Creating a date column, note that we use 1 as order since 0 is already taken and orders need to be unique. If we would use an overlapping index with the first column, the resulting dataset will not work properly. 
    client.create('column',
      {
        name: {
            en: 'Burrito production date'
        },
        type: 'datetime',
        order: 1,
        format: '%d-%m-%Y',
        informat: 'YYYY-MM-DD HH:mm:ss.SSS'
    }
    
    )
      .then(function(column) {
        console.log('Success!', column);
      });
    
       Creating a date column, note that we use 1 as order since 0 is already taken and orders need to be unique. If we would use an overlapping index with the first column, the resulting dataset will not work properly. 
    <?php
    $column = $client->create('column',
    
      array (
        'name' => array (
          'en' => 'Burrito production date'
        ),
        'type' => 'datetime',
        'order' => '1',
        'format' => '%d-%m-%Y',
        'informat' => 'YYYY-MM-DD HH:mm:ss.SSS'
      )
    
    );
    print("Success! { $column }");
    ?>
    
       Creating a date column, note that we use 1 as order since 0 is already taken and orders need to be unique. If we would use an overlapping index with the first column, the resulting dataset will not work properly. 
    curl https://api.luzmo.com/0.1.0/column  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "name": {
        "en": "Burrito production date"
      },
      "type": "datetime",
      "order": 1,
      "format": "%d-%m-%Y",
      "informat": "YYYY-MM-DD HH:mm:ss.SSS"
    }
    }
    EOF
    
    
    Create
    can be executed by:
    Logged-in User

    Any user with an API token can create a column. In order to use the column you will have to associate it to a dataset later on.

    Action: Update

       Example of updating the order of a column to put it in front, make sure however that order 0 is not taken yet! Else you have to move that column first. 
    JSONObject column = client.update("column", "<your column id>", 
      ImmutableMap.of(
        "order" , "0"
      ));
    
       Example of updating the order of a column to put it in front, make sure however that order 0 is not taken yet! Else you have to move that column first. 
    dynamic properties = new ExpandoObject();
    properties.order = "0";
    
    dynamic column = client.update("column", "<your column id>", );
    
       Example of updating the order of a column to put it in front, make sure however that order 0 is not taken yet! Else you have to move that column first. 
    client.update('column',
      '<your column id>',
      {
        order: 0
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Example of updating the order of a column to put it in front, make sure however that order 0 is not taken yet! Else you have to move that column first. 
    <?php
    $user = $client->update('column', '<your column id>', 
      array (
        'order' => '0'
      ));
    ?>
    
       Example of updating the order of a column to put it in front, make sure however that order 0 is not taken yet! Else you have to move that column first. 
    curl https://api.luzmo.com/0.1.0/column  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your column id>",
      "properties": {
      "order": 0
    }
    }
    EOF
    
       Example of updating the order of a column to put it in front, make sure however that order 0 is not taken yet! Else you have to move that column first. 
    column = client.update("column", "<your_column_id>", {
        "order": 0
    })
    
       Example where we change the UI representation of the date format 
    JSONObject column = client.update("column", "<your column id>", 
      ImmutableMap.of(
        "format" , "DD-MM-YYYY"
      ));
    
       Example where we change the UI representation of the date format 
    dynamic properties = new ExpandoObject();
    properties.format = "DD-MM-YYYY";
    
    dynamic column = client.update("column", "<your column id>", );
    
       Example where we change the UI representation of the date format 
    client.update('column',
      '<your column id>',
      {
        format: 'DD-MM-YYYY'
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Example where we change the UI representation of the date format 
    <?php
    $user = $client->update('column', '<your column id>', 
      array (
        'format' => 'DD-MM-YYYY'
      ));
    ?>
    
       Example where we change the UI representation of the date format 
    curl https://api.luzmo.com/0.1.0/column  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your column id>",
      "properties": {
      "format": "DD-MM-YYYY"
    }
    }
    EOF
    
       Example where we change the UI representation of the date format 
    column = client.update("column", "<your_column_id>", {
        "format": "DD-MM-YYYY"
    })
    
    Update
    can be executed by:
    Securable Modifier

    Only users who have write access to the dataset to which the column is associated can update the column.

    Action: Get

       Retrieve a dataset and the columns that belong to it 
    JSONObject data = client.get("securable", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "type" , "dataset",
          "id" , "<id of your dataset>"
        ),
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "Column"
          )
        )
      ));
    
    
       Retrieve a dataset and the columns that belong to it 
    dynamic query = new ExpandoObject();
    query.where = new {
          type = "dataset",
          id = "<id of your dataset>"
        };
    query.include = new List<Object> {
    
          new {
            model = "Column"
          }
        };
    
    dynamic data = client.get("securable",     query);
    
    
       Retrieve a dataset and the columns that belong to it 
    client.get('securable', {
        where: {
            type: 'dataset',
            id: '<id of your dataset>'
        },
        include: [
            {
                model: 'Column'
            }
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Retrieve a dataset and the columns that belong to it 
    <?php
    $user = $client->get('securable', 
      array (
        'where' => array (
          'type' => 'dataset',
          'id' => '<id of your dataset>'
        ),
        'include' => array (
    
          array (
            'model' => 'Column'
          )
        )
      ));
    
    ?>
    
       Retrieve a dataset and the columns that belong to it 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "type": "dataset",
        "id": "<id of your dataset>"
      },
      "include": [
        {
          "model": "Column"
        }
      ]
    }
    }
    EOF
    
    
       Retrieve a specific column and the dataset it is linked to 
    JSONObject data = client.get("column", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "id" , "<id of your column>"
        ),
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "Securable"
          )
        )
      ));
    
    
       Retrieve a specific column and the dataset it is linked to 
    dynamic query = new ExpandoObject();
    query.where = new {
          id = "<id of your column>"
        };
    query.include = new List<Object> {
    
          new {
            model = "Securable"
          }
        };
    
    dynamic data = client.get("column",     query);
    
    
       Retrieve a specific column and the dataset it is linked to 
    client.get('column', {
        where: {
            id: '<id of your column>'
        },
        include: [
            {
                model: 'Securable'
            }
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Retrieve a specific column and the dataset it is linked to 
    <?php
    $user = $client->get('column', 
      array (
        'where' => array (
          'id' => '<id of your column>'
        ),
        'include' => array (
    
          array (
            'model' => 'Securable'
          )
        )
      ));
    
    ?>
    
       Retrieve a specific column and the dataset it is linked to 
    curl https://api.luzmo.com/0.1.0/column  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "id": "<id of your column>"
      },
      "include": [
        {
          "model": "Securable"
        }
      ]
    }
    }
    EOF
    
    
       Retrieve a specific column and the dataset it is linked to 
    data = client.get("column", {
        "where": {
          "id": "<id of your column>"
        },
        "include": [{
          "model": "Securable"
        }]
    })
    
    
       Example of the return structure of the query above 
    {
      "count": 1,
      "rows": [
        {
          "id": "6ef3f802-7b17-4ac6-af2b-e86e7c058cd9",
          "name": {
            "en": "Acquisition"
          },
          "order": 4,
          "type": "hierarchy",
          "format": "",
          "informat": "hierarchy",
          "color": null,
          "minBound": null,
          "maxBound": null,
          "lowestLevel": 0,
          "highestLevel": 0,
          "minimum": null,
          "maximum": null,
          "created_at": "2018-08-30T11:44:20.234Z",
          "updated_at": "2018-08-30T11:44:20.923Z",
          "securable_id": "b06511f3-8cae-48f4-858a-ca409c065640",
          "expression": null,
          "width": 170,
          "source_name": null,
          "derivation": null,
          "version": 3,
          "cardinality": 9,
          "isLabel": false,
          "aggregation_type": "sum",
          "aggregation_id": null,
          "subtype": null,
          "hierarchy_enabled": false,
          "ordering_enabled": false,
          "colors_enabled": true
        },
        {
          ...
        },
        ...
      ]
    }
    
    Get
    can be executed by:
    Securable Reader
    List
    can be executed by:
    Securable Reader

    Only users who have read access to the dataset to which the column is associated can retrieve the columns of that dataset.

    Action: Delete

       Delete the column 
    client.delete("column", "<your column id>");
    
       Delete the column 
    $client->delete("column", "<your column id>");
    
       Delete the column 
    let promise = client.delete('column', '<your column id>');
    
       Delete the column 
    <?php
    $client->delete('column', '<your column id>');
    ?>
    
       Delete the column 
    curl https://api.luzmo.com/0.1.0/column  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your column id>"
    }
    EOF
    
       Delete the column 
    client.delete("column", "<your_column_id>")
    
    Delete
    can be executed by:
    Securable Modifier

    Delete a column by providing the id of the group.

    Associations

    %3 <!-- Dashboard --> Dashboard Dashboard <!-- Securable --> Securable Securable <!-- Dashboard->Securable --> Dashboard->Securable <!-- Dataset --> Dataset Dataset <!-- Dataset->Securable --> Dataset->Securable <!-- Column --> Column Column <!-- Securable->Column --> Securable->Column <!-- Column->Column --> Column->Column <!-- HierarchyLevel --> HierarchyLevel HierarchyLevel <!-- HierarchyLevel->Column --> HierarchyLevel->Column

    Associate: Column

       Link one dataset to another by associating their columns 
    client.associate("column", "<id of column 1>", "Joins", "<id of column 2>",
        ImmutableMap.of(
            "type", "lookup"
        )
    );
    
       Link one dataset to another by associating their columns 
    dynamic properties = new ExandoObject();
    properties.type = "lookup"; 
    
    client.associate("column", "<id of column 1>", "Joins", "<id of column 2>", properties);
    
       Link one dataset to another by associating their columns 
    let promise = client.associate('column', '<id of column 1>', { role: 'Joins', id: '<id of column 2>' }, {
        type: 'lookup'
    });
    
       Link one dataset to another by associating their columns 
    <?php
    $client->associate('column', '<id of column 1>', 'Joins', '<id of col 2>', , 
        array (
        'type' => 'lookup'
    ));
    ?>
    
       Link one dataset to another by associating their columns 
    curl https://api.luzmo.com/0.1.0/column  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<id of col 1>",
      "properties": {
          "type": "lookup"
      },
      "resource": {
        "role": "Joins",
        "id": "<id of col 2>"
      }
    }
    EOF
    
    Column
    Column

    In Luzmo you can link two datasets to create a join between them. You can create joins via API by associating the columns of the 2 datasets to link. Make sure the direction of the link between the datasets is many-to-one. Joins with multiple criteria can be set by just associating more than one set of columns.

    Associate: Dataset

       Add a column to your dataset (you have to create the column first) 
    client.associate("securable", "<your securable id>", "Columns", "<  column id>");
    
       Add a column to your dataset (you have to create the column first) 
    
    client.associate("securable", "<your securable id>", "Columns", "<  column id>");
    
       Add a column to your dataset (you have to create the column first) 
    let promise = client.associate('securable', '<your securable id>', {
        role: 'Columns',
        id: '<  column id>'
    });
    
       Add a column to your dataset (you have to create the column first) 
    <?php
    $client->associate('securable', '<your securable id>', 'Columns', '<  column id>', );
    ?>
    
       Add a column to your dataset (you have to create the column first) 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
        "role": "Columns",
        "id": "<  column id>"
      }
    }
    EOF
    
       Add a column to your dataset (you have to create the column first) 
    client.associate("securable", "<your_securable_id>", {"role":"Columns","id":"<  column id>"})
    
    Dataset
    Column
    Associate
    requires:
    Securable Modifier

    Columns contain the information of a column (not the data) within your datasets. When preparing your columns, be careful that when you upload data with the 'data' endpoint that the amount of columns corresponds to the data structure you will upload.

    Associate: HierarchyLevel

       Add a hierarchylevel to a column 
    client.associate("hierarchylevel", "<your hierarchylevel id>", "Column", "<column id>");
    
       Add a hierarchylevel to a column 
    
    client.associate("hierarchylevel", "<your hierarchylevel id>", "Column", "<column id>");
    
       Add a hierarchylevel to a column 
    let promise = client.associate('hierarchylevel', '<your hierarchylevel id>', {
        role: 'Column',
        id: '<column id>'
    });
    
       Add a hierarchylevel to a column 
    <?php
    $client->associate('hierarchylevel', '<your hierarchylevel id>', 'Column', '<column id>', );
    ?>
    
       Add a hierarchylevel to a column 
    curl https://api.luzmo.com/0.1.0/hierarchylevel  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your hierarchylevel id>",
      "resource": {
        "role": "Columns",
        "id": "<column id>"
      }
    }
    EOF
    
       Add a hierarchylevel to a column 
    client.associate("hierarchylevel", "<your_hierarchylevel_id>", {"role":"Columns","id":"<column id>"})
    
    Column
    HierarchyLevel

    In Luzmo all columns which deal with text values are of type hierarchy. On such a hierarchy column you can build a hierarchy out of your existing data values. To do so you first need to create hierarchy levels and associate them with a column.

    Dissociate

       Dissociate a column from a securable 
    client.dissociate("column", "<your column id>", "Securables", "<id of your securable>");
    
       Dissociate a column from a securable 
    client.dissociate("column", "<your column id>", "Securables", "<id of your securable>");
    
       Dissociate a column from a securable 
    let promise = client.dissociate('column', '<your column id>', {
        role: 'Securables',
        id: '<id of your securable>'
    });
    
       Dissociate a column from a securable 
    <?php
    $client->associate('column', '<your column id>', "Securables", "<id of your securable>");
    ?>
    
       Dissociate a column from a securable 
    curl https://api.luzmo.com/0.1.0/column  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your column id>",
      "resource": {
      "role": "Securables",
      "id": "<id of your securable>"
    }
    }
    EOF
    
       Dissociate a column from a securable 
    client.dissociate("column", "<your_column_id>", {"role":"Securables","id":"<id of your securable>"})
    
       Dissociate a hierarchylevel from a column 
    client.dissociate("column", "<your column id>", "HierarchyLevels", "<id of your hierarchylevel>");
    
       Dissociate a hierarchylevel from a column 
    client.dissociate("column", "<your column id>", "HierarchyLevels", "<id of your hierarchylevel>");
    
       Dissociate a hierarchylevel from a column 
    let promise = client.dissociate('column', '<your column id>', {
        role: 'HierarchyLevels',
        id: '<id of your hierarchylevel>'
    });
    
       Dissociate a hierarchylevel from a column 
    <?php
    $client->associate('column', '<your column id>', "HierarchyLevels", "<id of your hierarchylevel>");
    ?>
    
       Dissociate a hierarchylevel from a column 
    curl https://api.luzmo.com/0.1.0/column  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your column id>",
      "resource": {
      "role": "HierarchyLevels",
      "id": "<id of your hierarchylevel>"
    }
    }
    EOF
    
       Dissociate a hierarchylevel from a column 
    client.dissociate("column", "<your_column_id>", {"role":"HierarchyLevels","id":"<id of your hierarchylevel>"})
    

    Dissociating is similar for all resources. To break the link between two resources, simply provide the resource names and ids. Be careful that the 'role' of a resource is uppercase and usually plural. Dissociating can be done in both directions.

    Country

    Countries simply have a name and an id where the id is the two-letter country code (ISO) in capitals. By default, all countries are listed in the Luzmo platform. The only use for countries is to provide information on where your users are located to the platform which can be done by associating a country to the user or to the organization. Since countries are managed by Luzmo, you can not create, delete or update them.

    Properties

    Parameter
    Description
    id
    uuid
    Unique key of the country (automatically assigned)
    name
    string
    Name of the country

    Actions

    Get
    List
    Associate
    Dissociate

    Action: Get & List

       Get a list of all countries 
    JSONObject data = client.get("country", 
      ImmutableMap.of(
    
      ));
    
    
       Get a list of all countries 
    dynamic query = new ExpandoObject();
    
    dynamic data = client.get("country",     query);
    
    
       Get a list of all countries 
    client.get('country', {})
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Get a list of all countries 
    <?php
    $user = $client->get('country', 
      array (
    
      ));
    
    ?>
    
       Get a list of all countries 
    curl https://api.luzmo.com/0.1.0/country  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {}
    }
    EOF
    
    
       Get a list of all countries 
    data = client.get("country", {
    
    })
    
    
    Get
    can be executed by:
    Anonymous
    Logged-in User
    List
    can be executed by:
    Anonymous
    Logged-in User

    Any user can retrieve countries.

    Associations

    %3 <!-- User --> User User <!-- Country --> Country Country <!-- User->Country --> User->Country <!-- Organization --> Organization Organization <!-- Organization->Country --> Organization->Country

    Associate: Organization

       Link an organization to a country 
    client.associate("organization", "<your organization id>", "Countries", "FR");
    
       Link an organization to a country 
    
    client.associate("organization", "<your organization id>", "Countries", "FR");
    
       Link an organization to a country 
    let promise = client.associate('organization', '<your organization id>', {
        role: 'Countries',
        id: 'FR'
    });
    
       Link an organization to a country 
    <?php
    $client->associate('organization', '<your organization id>', 'Countries', 'FR', );
    ?>
    
       Link an organization to a country 
    curl https://api.luzmo.com/0.1.0/organization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your organization id>",
      "resource": {
        "role": "Countries",
        "id": "FR"
      }
    }
    EOF
    
       Link an organization to a country 
    client.associate("organization", "<your_organization_id>", {"role":"Countries","id":"FR"})
    
    Organization
    Country
    Associate
    requires:
    Organization Owner
    and
    Logged-in User

    Associating an organization with a country simply gives us the information we need about your company. The association between country and organization serves as a default for the users of your organization which can be overridden by associating a country to a user directly.

    Associate: User

       Set the country of residence for a user 
    client.associate("country", "<your country id>", "Users", "< your user id>");
    
       Set the country of residence for a user 
    
    client.associate("country", "<your country id>", "Users", "< your user id>");
    
       Set the country of residence for a user 
    let promise = client.associate('country', '<your country id>', {
        role: 'Users',
        id: '< your user id>'
    });
    
       Set the country of residence for a user 
    <?php
    $client->associate('country', '<your country id>', 'Users', '< your user id>', );
    ?>
    
       Set the country of residence for a user 
    curl https://api.luzmo.com/0.1.0/country  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your country id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      }
    }
    EOF
    
       Set the country of residence for a user 
    client.associate("country", "<your_country_id>", {"role":"Users","id":"< your user id>"})
    
    User
    Country
    Associate
    requires:
    Logged-in User
    and
    User Owner

    Users can be associated to countries. This simply informs the platform on the country of residence of the user. Countries can also be associated to organizations which serve as a default for the users of that organization. Just like locale, a country associated with user directly will take priority.

    Dashboard

    Dashboards can also be created, retrieved and updated programmatically or can be associated programmatically. The dashboard definition itself is configured via a json object in the contents property. This json object defines per view modus which visualization elements that are contained within the dashboard and what position and data connections each of them have. It is important to notice that the structure of this json evolves as we add new visualization types or adapt existing ones. That is why the json starts by declaring the version of the dashboard config. This makes sure that we are backward compatible with dashboard configurations that are created according to an older structure. Although it is possible, typically users do not create a dashboard from scratch. If you want to learn more about this structure, we advice to make a dashboard via the UI and retrieve it via the API to see what it looks like. A common use case is to create dashboards via the editor and add a logo or change colors programmatically.

    Properties

    Parameter
    Description
    id
    uuid
    Unique key of the dashboard (automatically assigned)
    contents
    object
    Json object that describes the structure of the dashboard. Important to notice is that these objects have versions. In case you adapt or create a dashboard via the API, it is important to set this version number.
    type
    string
    Type of the securable, either dataset or dashboard
    subtype
    string
    (Read-only) Creation type of the securable. Defaults to api
    name
    localized
    Title of the dataset or dashboard, shown in the dataset or dashboard header
    subtitle
    localized
    Secondary title of the dashboard, shown in the dashboard header
    description
    localized
    Long-form description of the dataset or dashboard, shown in the dataset or dashboard listings
    css
    string
    CSS code that overrides styling in the dashboard. Example: .pivottable-value { font-size: 18px; }. Defaults to null.
    modified_at
    datetime
    (Read-only) Last modification date of the dataset or dashboard.

    Actions

    Create
    Get
    List
    Delete
    Update
    Associate
    Dissociate

    Action: Create

       Dashboards are securables and are therefore created using the 'securable' resource with type 'dashboard'. The example below will create an empty dashboard with the screenmodes 'desktop', 'tablet' & 'mobile'. 
    JSONObject securable = client.create("securable",
    
      ImmutableMap.of(
        "type" , "dashboard",
        "contents" , ImmutableMap.of(
          "version" , "0.1.48",
          "syncScreenModes" , true,
          "datasetLinks" , ImmutableMap.of(),
          "views" , ImmutableList.of(
            ImmutableMap.of(
              "screenModus" , "desktop",
              "options" , ImmutableMap.of(
                "share" , ImmutableMap.of(
                  "poweredBy" , false
                ),
                "theme" , ImmutableMap.of(
                  "id" , "default" // or "default_dark"
                )
              ),
              "filters" , ImmutableList.of(),
              "items" , ImmutableList.of()
            },
            ImmutableMap.of(
              "screenModus" , "tablet",
              "options" , ImmutableMap.of(
                "share" , ImmutableMap.of(
                  "poweredBy" , false
                ),
                "theme" , ImmutableMap.of(
                  "id" , "default" // or "default_dark"
                )
              ),
              "filters" , ImmutableList.of(),
              "items" , ImmutableList.of()
            ),
            ImmutableMap.of(
              "screenModus" , "mobile",
              "options" , ImmutableMap.of(
                "share" , ImmutableMap.of(
                  "poweredBy" , false
                ),
                "theme" , ImmutableMap.of(
                  "id" , "default" // or "default_dark"
                )
              ),
              "filters" , ImmutableList.of(),
              "items" , ImmutableList.of()
            }
          ),
          "parameters" , ImmutableList.of(),
          "timezone" , ImmutableMap.of(
            "type" , "fixed",
            "id" , "Europe/Brussels" // A valid id from IANA timezone database
          )
        ),
        "name" , ImmutableMap.of(
          "en" , "An empty Dashboard"
        )
      ));
    System.out.println("Success! %s%n", securable);
    
       Dashboards are securables and are therefore created using the 'securable' resource with type 'dashboard'. The example below will create an empty dashboard with the screenmodes 'desktop', 'tablet' & 'mobile'. 
    dynamic properties = new ExpandoObject();
    properties.type = "dashboard";
    properties.contents = new {
          version = "0.1.48",
          syncScreenModes = true,
          datasetLinks = new{},
          views = new List<Object>{
            new{
              screenModus = "desktop",
              options = new{
                share = new{
                  poweredBy = false
                },
                theme = new{
                  id = "default" // or "default_dark"
                }
              },
              filters = new List<Object>{},
              items = new List<Object>{}
            },
            new{
              screenModus = "tablet",
              options = new{
                share = new{
                  poweredBy = false
                },
                theme = new{
                  id = "default" // or "default_dark"
                }
              },
              filters = new List<Object>{},
              items = new List<Object>{}
            },
            new{
              screenModus = "mobile",
              options = new{
                share = new{
                  poweredBy = false
                },
                theme = new{
                  id = "default" // or "default_dark"
                }
              },
              filters = new List<Object>{},
              items = new List<Object>{}
            }
          },
          parameters = new List<Object>{},
          timezone = new{
            type = "fixed",
            id = "Europe/Brussels" // A valid id from IANA timezone database
          }
        };
    properties.name = new {
          en = "An empty Dashboard"
        };
    
    dynamic securable = client.create("securable",    properties);
    Console.WriteLine("Success!", securable);
    
       Dashboards are securables and are therefore created using the 'securable' resource with type 'dashboard'. The example below will create an empty dashboard with the screenmodes 'desktop', 'tablet' & 'mobile'. 
    client.create('securable',
      {
        type: 'dashboard',
        contents: {
          version: "0.1.48",
          syncScreenModes: true,
          datasetLinks: {},
          views: [
            {
              screenModus: "desktop",
              options: {
                share: {
                  poweredBy: false
                },
                theme: {
                  id: "default" // or "default_dark"
                }
              },
              filters: [],
              items: []
            },
            {
              screenModus: "tablet",
              options: {
                share: {
                  poweredBy: false
                },
                theme: {
                  id: "default" // or "default_dark"
                }
              },
              filters: [],
              items: []
            },
            {
              screenModus: "mobile",
              options: {
                share: {
                  poweredBy: false
                },
                theme: {
                  id: "default" // or "default_dark"
                }
              },
              filters: [],
              items: []
            }
          ],
          parameters: [],
          timezone: {
            type: "fixed",
            id: "Europe/Brussels" // A valid id from IANA timezone database
          }
        },
        name: {
            en: 'An empty Dashboard'
        }
    }
    
    )
      .then(function(securable) {
        console.log('Success!', securable);
      });
    
       Dashboards are securables and are therefore created using the 'securable' resource with type 'dashboard'. The example below will create an empty dashboard with the screenmodes 'desktop', 'tablet' & 'mobile'. 
    <?php
    $securable = $client->create('securable',
    
      array (
        'type' => 'dashboard',
        'contents' => array(
          'version' => '0.1.48',
          'syncScreenModes' => true,
          'datasetLinks' => array(),
          'views' => array(
            array(
              'screenModus' => 'desktop',
              'options' => array(
                'share' => array(
                  'poweredBy' => false
                ),
                'theme' => array(
                  'id' => 'default' // or 'default_dark'
                )
              ),
              'filters' => array(),
              'items' => array()
            ),
            array(
              'screenModus' => 'tablet',
              'options' => array(
                'share' => array(
                  'poweredBy' => false
                ),
                'theme' => array(
                  'id' => 'default' // or 'default_dark'
                )
              ),
              'filters' => array(),
              'items' => array()
            ),
            array(
              'screenModus' => 'mobile',
              'options' => array(
                'share' => array(
                  'poweredBy' => false
                ),
                'theme' => array(
                  'id' => 'default' // or 'default_dark'
                )
              ),
              'filters' => array(),
              'items' => array()
            )
          ),
          'parameters' => array(),
          'timezone' => array(
            'type' => 'fixed',
            'id' => 'Europe/Brussels' // A valid id from IANA timezone database
          ),
        'name' => array (
          'en' => 'An empty Dashboard'
        )
      )
    
    );
    print("Success! { $securable }");
    ?>
    
       Dashboards are securables and are therefore created using the 'securable' resource with type 'dashboard'. The example below will create an empty dashboard with the screenmodes 'desktop', 'tablet' & 'mobile'. 
    curl https://api.luzmo.com/0.1.0/securable \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "type": "dashboard",
        "contents": {
          "version": "0.1.48",
          "syncScreenModes": true,
          "datasetLinks": {},
          "views": [
            {
              "screenModus": "desktop",
              "options": {
                "share": {
                  "poweredBy": false
                },
                "theme": {
                  "id": "default" // or "default_dark"
                }
              },
              "filters": [],
              "items": []
            },
            {
              "screenModus": "tablet",
              "options": {
                "share": {
                  "poweredBy": false
                },
                "theme": {
                  "id": "default" // or "default_dark"
                }
              },
              "filters": [],
              "items": []
            },
            {
              "screenModus": "mobile",
              "options": {
                "share": {
                  "poweredBy": false
                },
                "theme": {
                  "id": "default" // or "default_dark"
                }
              },
              "filters": [],
              "items": []
            }
          ],
          "parameters": [],
          "timezone": {
            "type": "fixed",
            "id": "Europe/Brussels" // A valid id from IANA timezone database
          }
        },
        "name": {
          "en": "An empty Dashboard"
        }
      }
    }
    EOF
    
    
       Dashboards are securables and are therefore created using the 'securable' resource using the type 'dashboard'. When a Dashboard is created it is automatically linked to the user that created it 
    securable = client.create("securable",
    {
        "type": "dashboard",
        "contents": "{..dashboard contents..}",
        "name": {
          "en": "My new Dashboard"
        }
    })
    print("Success! ", securable)
    
    Create
    can be executed by:
    Logged-in User

    Any user with an API token can create a dashboard. The user that creates the dashboard will be automatically associated as the owner.

    Note that a dashboard requires a minimum structure. The code example provides the default structure (we left out the 'largeScreen' view since it has an identical structure).

    Action: Update

       You can make minor changes and update the contents of a dashboard or simply update the name 
    JSONObject securable = client.update("securable", "<your securable id>", 
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "Our Product Dashboard"
        ),
        "contents" , ImmutableMap.of(
          "version" , "0.1.48",
          "syncScreenModes" , true,
          "views" , ImmutableList.of(
            "view properties as shown in create"
          )
        )
      ));
    
       You can make minor changes and update the contents of a dashboard or simply update the name 
    dynamic properties = new ExpandoObject();
    properties.name = new {
          en = "Our Product Dashboard"
        };
    properties.contents = new {
          version = "0.1.17",
          syncScreenModes = true,
          views = new List<Object> {
            "view properties as shown in create"
          }
        };
    
    dynamic securable = client.update("securable", "<your securable id>", );
    
       You can make minor changes and update the contents of a dashboard or simply update the name 
    client.update('securable',
      '<your securable id>',
      {
        name: {
            en: 'Our Product Dashboard'
        },
        contents: {
            version: '0.1.17',
            syncScreenModes: true,
            views: [
                'view properties as shown in create'
            ]
        }
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       You can make minor changes and update the contents of a dashboard or simply update the name 
    <?php
    $user = $client->update('securable', '<your securable id>', 
      array (
        'name' => array (
          'en' => 'Our Product Dashboard'
        ),
        'contents' => array (
          'version' => '0.1.17',
          'syncScreenModes' => true,
          'views' => array (
            'view properties as shown in create'
          )
        )
      ));
    ?>
    
       You can make minor changes and update the contents of a dashboard or simply update the name 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "properties": {
      "name": {
        "en": "Our Product Dashboard"
      },
      "contents": {
        "version": "0.1.17",
        "syncScreenModes": true,
        "views": [
          "view properties as shown in create"
        ]
      }
    }
    }
    EOF
    
    Update
    can be executed by:
    Securable Modifier

    Only users who have edit rights to the dashboard can update the dashboard.

    Action: Get & List

       Retrieve a dashboard by id 
    JSONObject data = client.get("securable", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "id" , "<your dashboard id>"
        )
      ));
    
    
       Retrieve a dashboard by id 
    dynamic query = new ExpandoObject();
    query.where = new {
          id = "<your dashboard id>"
        };
    
    dynamic data = client.get("securable",     query);
    
    
       Retrieve a dashboard by id 
    client.get('securable', {
        where: {
            id: '<your dashboard id>'
        }
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Retrieve a dashboard by id 
    <?php
    $user = $client->get('securable', 
      array (
        'where' => array (
          'id' => '<your dashboard id>'
        )
      ));
    
    ?>
    
       Retrieve a dashboard by id 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "id": "<your dashboard id>"
      }
    }
    }
    EOF
    
    
       Retrieve a dashboard by id 
    data = client.get("securable", {
        "where": {
          "id": "<your dashboard id>"
        }
    })
    
    
       Retrieve all dashboards for a certain user id (to which you also have read access) 
    JSONObject data = client.get("securable", 
      ImmutableMap.of(
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "User",
            "where" , ImmutableMap.of(
              "id" , "< your user id >"
            ),
            "jointype" , "inner"
          )
        )
      )
    );
    
    
       Retrieve all dashboards for a certain user id (to which you also have read access) 
    dynamic query = new ExpandoObject();
    query.include = new List<Object> { 
      new {
        model = "User",
        where = new {
          id = "< your user id >"
        },
        jointype = "inner"
      }
    };
    
    dynamic data = client.get("securable",     query);
    
    
       Retrieve all dashboards for a certain user id (to which you also have read access) 
    client.get('securable', {
        include: [
            {
                model: 'User',
                where: {
                    id: '< your user id >'
                },
                jointype: 'inner'
            }
        ]
    }).then(function(data) {
        console.log('Success!', data);
    });
    
       Retrieve all dashboards for a certain user id (to which you also have read access) 
    <?php
    $user = $client->get('securable', 
      array (
        'include' => array (
    
          array (
            'model' => 'User',
            'where' => array (
              'id' => '< your user id >'
            ),
            'jointype' => 'inner'
          )
        )
      )
    );
    
    ?>
    
       Retrieve all dashboards for a certain user id (to which you also have read access) 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "include": [
        {
          "model": "User",
          "where": {
            "id": "< your user id >"
          },
          "jointype": "inner"
        }
      ]
    }
    }
    EOF
    
       Retrieve all dashboard-ids with a certain tag 
    JSONObject data = client.get("securable", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "type" , "dashboard"
        ),
        "public" , false,
        "attributes" , ImmutableList.of(
          "name",
          "id"
        ),
        "include" , ImmutableList.of(
          ImmutableMap.of(
            "model" , "Tag",
            "where" , ImmutableMap.of(
              "tag" , "< your tag >"
            ),
            "jointype" , "inner"
          )
        )
      )
    );
    
       Retrieve all dashboard-ids with a certain tag 
    dynamic query = new ExpandoObject(); 
    query.where = new {
      type = "dashboard"
    };  
    query.options = new {
      public = false
    };
    query.attributes = new List<String> {
      "id",
      "name"
    };
    query.include = new List<Object> {
        new {
            model = "Tag",
            where = new {
              tag = "< your tag >"
            },
            jointype = "inner"
        }
    };
    
    dynamic data = client.get("securable", query);
    
       Retrieve all dashboard-ids with a certain tag 
    client.get('securable', {
        where: {
            type: 'dashboard'
        },
        options: {
            public: false
        },
        attributes: ['name', 'id'],
        include: [
            {
                model: 'Tag',
                where: {
                    tag: '< your tag >'
                },
                jointype: 'inner'
            }
        ]
    }).then(function(data) {
        console.log('Success!', data);
    });
    
       Retrieve all dashboard-ids with a certain tag 
    <?php
      $user = $client->get('securable', 
        array (
          'where' => array (
            'type' => 'dashboard'
          ),
          'options' => array (
            'public' => false
          ),
          'attributes' => array (
            'name',
            'id'
          ),
          'include' => array (
            array (
              'model' => 'Tag',
              'where' => array (
                'tag' => '< your tag >'
              ),
              'jointype' => 'inner'
            )
          )
        )
      );
    ?>
    
       Retrieve all dashboard-ids with a certain tag 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
        "where": {
          "type": "dashboard"
        },
        "options": {
          "public": false
        },
        "attributes": ["name", "id"],
        "include": [
          {
            "model": "Tag",
            "where": {
              "tag": "< your tag >"
            },
            "jointype": "inner"
          }
        ]
      }
    }
    EOF
    
       Retrieve all dashboard-ids which have all tags associated 
    JSONObject data = client.get("securable", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "type" , "dashboard"
        ),
        "public" , false,
        "attributes" , ImmutableList.of(
          "name",
          "id"
        ),
        "search" , ImmutableMap.of(
          "match_types" , ImmutableList.of(
            "tag"
          ),
          "keyphrase", "< tag 1 >, < tag 2 >"
        )
      )
    );
    
       Retrieve all dashboard-ids which have all tags associated 
    dynamic query = new ExpandoObject(); 
    query.where = new {
      type = "dashboard"
    };  
    query.options = new {
      public = false
    };
    query.attributes = new List<String> {
      "id",
      "name"
    };
    query.search = new {
      match_types = new List<String> {
        "tag"
      },
      keyphrase = "< tag 1 >, < tag 2 >"
    };
    
    dynamic data = client.get("securable", query);
    
       Retrieve all dashboard-ids which have all tags associated 
    client.get('securable', {
        where: {
            type: 'dashboard'
        },
        options: {
            public: false
        },
        attributes: ['name', 'id'],
        search: {
            match_types: ['Tag'],
            keyphrase: '< tag 1 >, < tag 2 >'
        }
    }).then(function(data) {
        console.log('Success!', data);
    });
    
       Retrieve all dashboard-ids which have all tags associated 
    <?php
    $user = $client->get('securable', 
      array (
        'where' => array (
          'type' => 'dashboard'
        ),
        'options' => array (
          'public' => false
        ),
        'attributes' => array (
          'name',
          'id'
        ),
        'search' => array (
          'match_types' => array (
            'Tag'
          ),
          'keyphrase' => '< tag 1 >, < tag 2 >'
        )
      )
    );
    
    ?>
    
       Retrieve all dashboard-ids which have all tags associated 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
        "where": {
          "type": "dashboard"
        },
        "options": {
          "public": false
        },
        "attributes": ["name", "id"],
        "search": {
          "match_types": ["Tag"],
          "keyphrase": "< tag 1 >, < tag 2 >"
        }
      }
    }
    EOF
    
    
    Get
    can be executed by:
    Securable Reader
    List
    can be executed by:
    Securable Reader

    Dashboards can be retrieved, this is an easy way to see the structure of a dashboard and make minor changes via the API.

    Action: Delete

       Delete a dashboard 
    client.delete("securable", "<your securable id>");
    
       Delete a dashboard 
    $client->delete("securable", "<your securable id>");
    
       Delete a dashboard 
    let promise = client.delete('securable', '<your securable id>');
    
       Delete a dashboard 
    <?php
    $client->delete('securable', '<your securable id>');
    ?>
    
       Delete a dashboard 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>"
    }
    EOF
    
       Delete a dashboard 
    client.delete("securable", "<your_securable_id>")
    
    Delete
    can be executed by:
    Securable Owner

    Delete a dashboard by providing the id of the dashboard.

    Associations

    Note that associations listed in the schema are the same for dataset and dashboard. Some associations only make sense for one of the two (e.g. Thumbnail does nothing for a Dataset) or have different significations.

    %3 <!-- Removed the Plugin association --> <!-- Dashboard --> Dashboard Dashboard <!-- Securable --> Securable Securable <!-- Dashboard->Securable --> Dashboard->Securable <!-- Dataset --> Dataset Dataset <!-- Dataset->Securable --> Dataset->Securable <!-- Securable->Securable --> Securable->Securable <!-- Column --> Column Column <!-- Securable->Column --> Securable->Column <!-- User --> User User <!-- User->Securable --> User->Securable <!-- Thumbnail --> Thumbnail Thumbnail <!-- Thumbnail->Securable --> Thumbnail->Securable <!-- Tag --> Tag Tag <!-- Tag->Securable --> Tag->Securable <!-- Share --> Share Share <!-- Share->Securable --> Share->Securable <!-- Group --> Group Group <!-- Group->Securable --> Group->Securable <!-- Schedule --> Schedule Schedule <!-- Schedule->Securable --> Schedule->Securable

    Associate: Group

       Link a user to a group and set him as member of that group 
    client.associate("group", "<your group id>", "Users", "< your user id>", 
      ImmutableMap.of(
        "flagMember" , true,
        "flagOwn" , false
      ) );
    
       Link a user to a group and set him as member of that group 
    dynamic properties = new ExpandoObject();
    properties.flagMember = true;
    properties.flagOwn = false;
    
    client.associate("group", "<your group id>", "Users", "< your user id>",     properties );
    
       Link a user to a group and set him as member of that group 
    let promise = client.associate('group', '<your group id>', {
        role: 'Users',
        id: '< your user id>'
    },
    {
        flagMember: true,
        flagOwn: false
    });
    
       Link a user to a group and set him as member of that group 
    <?php
    $client->associate('group', '<your group id>', 'Users', '< your user id>', , 
      array (
        'flagMember' => true,
        'flagOwn' => false
      ) );
    ?>
    
       Link a user to a group and set him as member of that group 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      },
      "properties": {
        "flagMember": true,
        "flagOwn": false
      }
    }
    EOF
    
       Link a user to a group and set him as member of that group 
    client.associate("group", "<your_group_id>", {"role":"Users","id":"< your user id>"}, {
        "flagMember": True,
        "flagOwn": False
    } )
    
       Link a group to a securable, and give read/use/write access to that group 
    client.associate("group", "<your group id>", "Securables", "< your securable (dashboard or dataset) id>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagModify" , true,
        "flagUse" , true,
        "flagOwn" , false
      ) );
    
       Link a group to a securable, and give read/use/write access to that group 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagModify = true;
    properties.flagUse = true;
    properties.flagOwn = false;
    
    client.associate("group", "<your group id>", "Securables", "< your securable (dashboard or dataset) id>",     properties );
    
       Link a group to a securable, and give read/use/write access to that group 
    let promise = client.associate('group', '<your group id>', {
        role: 'Securables',
        id: '< your securable (dashboard or dataset) id>'
    }, 
    {
        flagRead: true,
        flagModify: true,
        flagUse: true,
        flagOwn: false
    });
    
       Link a group to a securable, and give read/use/write access to that group 
    <?php
    $client->associate('group', '<your group id>', 'Securables', '< your securable (dashboard or dataset) id>', , 
      array (
        'flagRead' => true,
        'flagModify' => true,
        'flagUse' => true,
        'flagOwn' => false
      ) );
    ?>
    
       Link a group to a securable, and give read/use/write access to that group 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
        "role": "Securables",
        "id": "< your securable (dashboard or dataset) id>"
      },
      "properties": {
        "flagRead": true,
        "flagModify": true,
        "flagUse": true,
        "flagOwn": false
      }
    }
    EOF
    
       Link a group to a securable, and give read/use/write access to that group 
    client.associate("group", "<your_group_id>", {"role":"Securables","id":"< your securable (dashboard or dataset) id>"}, {
        "flagRead": True,
        "flagModify": True,
        "flagUse": True,
        "flagOwn": False
    } )
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    client.associate("group", "<your group id>", "Securables", "< id of the public group>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagModify" , false,
        "flagUse" , false,
        "flagOwn" , false,
        "published" , false
      ) );
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagModify = false;
    properties.flagUse = false;
    properties.flagOwn = false;
    properties.published = false;
    
    client.associate("group", "<your group id>", "Securables", "< id of the public group>",     properties );
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    let promise = client.associate('group', '<your group id>', {
        role: 'Securables',
        id: '< id of the public group>'
    },
    {
        flagRead: true,
        flagModify: false,
        flagUse: false,
        flagOwn: false,
        published: false
    });
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    <?php
    $client->associate('group', '<your group id>', 'Securables', '< id of the public group>', , 
      array (
        'flagRead' => true,
        'flagModify' => false,
        'flagUse' => false,
        'flagOwn' => false,
        'published' => false
      ) );
    ?>
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
        "role": "Securables",
        "id": "< id of the public group>"
      },
      "properties": {
        "flagRead": true,
        "flagModify": false,
        "flagUse": false,
        "flagOwn": false,
        "published": false
      }
    }
    EOF
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    client.associate("group", "<your_group_id>", {"role":"Securables","id":"< id of the public group>"}, {
        "flagRead": True,
        "flagModify": False,
        "flagUse": False,
        "flagOwn": False,
        "published": False
    } )
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    client.associate("group", "<your group id>", "Securables", "< id of the public group>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagModify" , false,
        "flagUse" , true,
        "flagOwn" , false,
        "published" , true
      ) );
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagModify = false;
    properties.flagUse = true;
    properties.flagOwn = false;
    properties.published = true;
    
    client.associate("group", "<your group id>", "Securables", "< id of the public group>",     properties );
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    let promise = client.associate('group', '<your group id>', {
        role: 'Securables',
        id: '< id of the public group>'
    },
    {
        flagRead: true,
        flagModify: false,
        flagUse: true,
        flagOwn: false,
        published: true
    });
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    <?php
    $client->associate('group', '<your group id>', 'Securables', '< id of the public group>', , 
      array (
        'flagRead' => true,
        'flagModify' => false,
        'flagUse' => true,
        'flagOwn' => false,
        'published' => true
      ) );
    ?>
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
        "role": "Securables",
        "id": "< id of the public group>"
      },
      "properties": {
        "flagRead": true,
        "flagModify": false,
        "flagUse": true,
        "flagOwn": false,
        "published": true
      }
    }
    EOF
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    client.associate("group", "<your_group_id>", {"role":"Securables","id":"< id of the public group>"}, {
        "flagRead": True,
        "flagModify": False,
        "flagUse": True,
        "flagOwn": False,
        "published": True
    } )
    
    Group
    Securable
    flagRead
    Grant the right to view the dashboard
    flagUse
    Right required for example to duplicate the dashboard
    flagModify
    Right to modify the dashboard
    flagOwn
    Right to delete the dashboard, or to modify the access rights e.g. by associating the dashboard with users (multiple users can be owner)
    published
    The dataset/dashboard will be listed in the public datasets/dashboards on Luzmo. This is a useful feature if you are providing open data for the public. To avoid mistakes, this feature is only enabled for clients that specifically ask for this.
    Associate
    requires:
    Group Owner
    and
    Securable Owner

    Groups can be used to give a group of users access to securables (dashboards or datasets). In order to do so, the group has to be associated with the securables to give access. Several flags on the association you to control the type of access. An association without providing flags will not have effect.

    Associate: Schedule

       Link a dashboard to a schedule 
    client.associate("securable", "<your securable id>", "Schedule", "< your schedule id>");
    
       Link a dashboard to a schedule 
    
    client.associate("securable", "<your securable id>", "Schedule", "< your schedule id>");
    
       Link a dashboard to a schedule 
    let promise = client.associate('securable', '<your securable id>', {
        role: 'Schedule',
        id: '< your schedule id>'
    });
    
       Link a dashboard to a schedule 
    <?php
    $client->associate('securable', '<your securable id>', 'Schedule', '< your schedule id>', );
    ?>
    
       Link a dashboard to a schedule 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
        "role": "Schedule",
        "id": "< your schedule id>"
      }
    }
    EOF
    
       Link a dashboard to a schedule 
    client.associate("securable", "<your_securable_id>", {"role":"Schedule","id":"< your schedule id>"})
    
    Dashboard
    Schedule
    Associate
    requires:
    Securable Modifier
    and
    Securable Modifier

    Scheduling a dashboard allows you to send automatic exports.

    Associate: Share

       Link a share to a dashboard
    client.associate("securable", "<your securable id>", "Shares", "< your share id>");
    
       Link a user to a dashboard
    dynamic properties = new ExpandoObject();
    
    client.associate("securable", "<your securable id>", "Shares", "< your share id>");
    
       Link a share to a dashboard
    let promise = client.associate('securable', '<your securable id>', {
        role: 'Shares',
        id: '< your share id>'
    } );
    
       Link a share to a dashboard
    <?php
    $client->associate('securable', '<your securable id>', 'Shares', '< your share id>');
    ?>
    
       Link a share to a dashboard
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
        "role": "Shares",
        "id": "< your share id>"
      }
    }
    EOF
    
       Link a user to a share 
    client.associate("securable", "<your_securable_id>", {"role":"Shares","id":"< your share id>"})
    
    Dashboard
    Share
    Associate
    requires:
    Share Owner
    and
    Securable Owner

    Creating a share and associating it to a dashboard makes it possible to share private links with users.

    Associate: User

       Link a user to a dashboard in order to make that dashboard readable by the user 
    client.associate("securable", "< your dashboard id >", "Users", "< a user id >", 
      ImmutableMap.of(
        "flagRead" , true
      ) );
    
       Link a user to a dashboard in order to make that dashboard readable by the user 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    
    client.associate("securable", "< your dashboard id >", "Users", "< a user id >",     properties );
    
       Link a user to a dashboard in order to make that dashboard readable by the user 
    let promise = client.associate('securable', '< your dashboard id >', {
        role: 'Users',
        id: '< a user id >'
    },
    {
        flagRead: true
    });
    
       Link a user to a dashboard in order to make that dashboard readable by the user 
    <?php
    $client->associate('securable', '< your dashboard id >', 'Users', '< a user id >', , 
      array (
        'flagRead' => true
      ) );
    ?>
    
       Link a user to a dashboard in order to make that dashboard readable by the user 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "< your dashboard id >",
      "resource": {
        "role": "Users",
        "id": "< a user id >"
      },
      "properties": {
        "flagRead": true
      }
    }
    EOF
    
       Link a user to a dashboard in order to make that dashboard readable by the user 
    client.associate("securable", "< your dashboard id >", {"role":"Users","id":"< a user id >"}, {
        "flagRead": True
    } )
    
       Link a user to a dashboard and give him all the rights (making him also owner of the dashboard) 
    client.associate("securable", "< your dashboard id >", "Users", "< a user id >", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagOwn" , true,
        "flagUse" , true,
        "flagModify" , true
      ) );
    
       Link a user to a dashboard and give him all the rights (making him also owner of the dashboard) 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagOwn = true;
    properties.flagUse = true;
    properties.flagModify = true;
    
    client.associate("securable", "< your dashboard id >", "Users", "< a user id >",     properties );
    
       Link a user to a dashboard and give him all the rights (making him also owner of the dashboard) 
    let promise = client.associate('securable', '< your dashboard id >', {
        role: 'Users',
        id: '< a user id >'
    },
    {
        flagRead: true,
        flagOwn: true,
        flagUse: true,
        flagModify: true
    });
    
       Link a user to a dashboard and give him all the rights (making him also owner of the dashboard) 
    <?php
    $client->associate('securable', '< your dashboard id >', 'Users', '< a user id >', , 
      array (
        'flagRead' => true,
        'flagOwn' => true,
        'flagUse' => true,
        'flagModify' => true
      ) );
    ?>
    
       Link a user to a dashboard and give him all the rights (making him also owner of the dashboard) 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "< your dashboard id >",
      "resource": {
        "role": "Users",
        "id": "< a user id >"
      },
        "properties": {
        "flagRead": true,
        "flagOwn": true,
        "flagUse": true,
        "flagModify": true
      }
    }
    EOF
    
       Link a user to a dashboard and give him all the rights (making him also owner of the dashboard) 
    client.associate("securable", "< your dashboard id >", {"role":"Users","id":"< a user id >"}, {
        "flagRead": True,
        "flagOwn": True,
        "flagUse": True,
        "flagModify": True
    } )
    
    User
    Securable
    flagRead
    Grant the right to view the dashboard
    flagUse
    Right requires for example to duplicate the dashboard
    flagModify
    Right to modify the dashboard
    flagOwn
    Right to delete the dashboard, or to modify the access rights e.g. by associating the dashboard with users (multiple users can be owner)
    Associate
    requires:
    Securable Owner
    and
    Logged-in User

    A user can be linked to a dashboard to give him access to that dashboard. To start associating, note that a dashboard is a subclass of securable so we use securable in the calls. The association has flag properties to define what kind of access the user will receive. In order to start associating dashboards with users, you already need to be resource owner of the dashboard. That means that you either created the dashboard or received access from someone that associated you with the dashboard using the flagOwn = true property. That way it is possible to set multiple owners for a dashboard.

    Dissociate

       Dissociate a user and a dashboard 
    client.dissociate("securable", "<your securable id>", "Users", "< your user id>");
    
       Dissociate a user and a dashboard 
    client.dissociate("securable", "<your securable id>", "Users", "< your user id>");
    
       Dissociate a user and a dashboard 
    let promise = client.dissociate('securable', '<your securable id>', {
        role: 'Users',
        id: '< your user id>'
    });
    
       Dissociate a user and a dashboard 
    <?php
    $client->associate('securable', '<your securable id>', "Users", "< your user id>");
    ?>
    
       Dissociate a user and a dashboard 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
      "role": "Users",
      "id": "< your user id>"
    }
    }
    EOF
    
       Dissociate a user and a dashboard 
    client.dissociate("securable", "<your_securable_id>", {"role":"Users","id":"< your user id>"})
    
       Dissociate a group and dashboard (the group will no longer have access except if a user is directly associated) 
    client.dissociate("securable", "<your securable id>", "Groups", "< your group id>");
    
       Dissociate a group and dashboard (the group will no longer have access except if a user is directly associated) 
    client.dissociate("securable", "<your securable id>", "Groups", "< your group id>");
    
       Dissociate a group and dashboard (the group will no longer have access except if a user is directly associated) 
    let promise = client.dissociate('securable', '<your securable id>', {
        role: 'Groups',
        id: '< your group id>'
    });
    
       Dissociate a group and dashboard (the group will no longer have access except if a user is directly associated) 
    <?php
    $client->associate('securable', '<your securable id>', "Groups", "< your group id>");
    ?>
    
       Dissociate a group and dashboard (the group will no longer have access except if a user is directly associated) 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
      "role": "Groups",
      "id": "< your group id>"
    }
    }
    EOF
    
       Dissociate a group and dashboard (the group will no longer have access except if a user is directly associated) 
    client.dissociate("securable", "<your_securable_id>", {"role":"Groups","id":"< your group id>"})
    

    Dissociating is similar for all resources. To break the link between two resources, simply provide the resource names and ids. Be careful that the 'role' of a resource is uppercase and usually plural. Dissociating can be done in both directions.

    Dataset

    Contains the metadata associated with a single dataset.

    The creating user is automatically given owner rights on the dataset. Any user can create new datasets. Only users with modify rights (either directly granted or via one or more groups) can update the dataset. This endpoint only creates datasets, to push data to the datasets you first have to add columns to the dataset with the column endpoint (Column) and then use the data endpoint to push data to the dataset.

    Properties

    Parameter
    Description
    id
    uuid
    Unique key of the dataset (automatically assigned)
    type
    string
    Type of the securable, either dataset or dashboard
    subtype
    string
    (Read-only) Creation type of the securable. Defaults to api
    name
    localized
    Title of the dataset or dashboard, shown in the dataset or dashboard header
    subtitle
    localized
    Secondary title of the dashboard, shown in the dashboard header
    description
    localized
    Long-form description of the dataset or dashboard, shown in the dataset or dashboard listings
    cache
    integer
    Defaults to 0. Number of seconds queries to this dataset are cached in Luzmo's caching layer. Use 0 to disable caching for this dataset entirely. Note that queries might still not be cached if there are other uncached data connectors or datasets called in a query. You can invalidate the cache before the expiry time by calling the update method on the data endpoint.
    rows
    integer
    (Read-only) Total number of rows accessible within this dataset.
    modified_at
    datetime
    (Read-only) Last modification date of the dataset or dashboard.

    Actions

    Create
    Get
    List
    Delete
    Update
    Associate
    Dissociate

    Action: Create

       Creation of a dataset 
    JSONObject securable = client.create("securable",
    
      ImmutableMap.of(
        "type" , "dataset",
        "name" , ImmutableMap.of(
          "en" , "<title of your dataset>"
        ),
        "subtitle" , ImmutableMap.of(
          "en" , "<subtitle of your dataset>"
        ),
        "description" , ImmutableMap.of(
          "en" , "<description of your dataset>"
        )
      ));
    System.out.println("Success! %s%n", securable);
    
       Creation of a dataset 
    dynamic properties = new ExpandoObject();
    properties.type = "dataset";
    properties.name = new {
          en = "<title of your dataset>"
        };
    properties.subtitle = new {
          en = "<subtitle of your dataset>"
        };
    properties.description = new {
          en = "<description of your dataset>"
        };
    
    dynamic securable = client.create("securable",    properties);
    Console.WriteLine("Success!", securable);
    
       Creation of a dataset 
    client.create('securable',
      {
        type: 'dataset',
        name: {
            en: '<title of your dataset>'
        },
        subtitle: {
            en: '<subtitle of your dataset>'
        },
        description: {
            en: '<description of your dataset>'
        }
    }
    
    )
      .then(function(securable) {
        console.log('Success!', securable);
      });
    
       Creation of a dataset 
    <?php
    $securable = $client->create('securable',
    
      array (
        'type' => 'dataset',
        'name' => array (
          'en' => '<title of your dataset>'
        ),
        'subtitle' => array (
          'en' => '<subtitle of your dataset>'
        ),
        'description' => array (
          'en' => '<description of your dataset>'
        )
      )
    
    );
    print("Success! { $securable }");
    ?>
    
       Creation of a dataset 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "type": "dataset",
      "name": {
        "en": "<title of your dataset>"
      },
      "subtitle": {
        "en": "<subtitle of your dataset>"
      },
      "description": {
        "en": "<description of your dataset>"
      }
    }
    }
    EOF
    
    
       Creation of a dataset 
    securable = client.create("securable",
    {
        "type": "dataset",
        "name": {
          "en": "<title of your dataset>"
        },
        "subtitle": {
          "en": "<subtitle of your dataset>"
        },
        "description": {
          "en": "<description of your dataset>"
        }
    })
    print("Success! ", securable)
    
    Create
    can be executed by:
    Logged-in User

    Any user with an API token can create a dataset. The user that creates the dataset will be automatically associated as the owner. Note that the creation of a dataset simply creates a securable of a certain type with properties such as name, title and description. To actually add data to the dataset you also have to create columns, associate them to the dataset and push data to the dataset.

    Action: Update

       Update the name of a dataset 
    JSONObject securable = client.update("securable", "<your securable id>", 
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "<new title of your dataset>"
        )
      ));
    
       Update the name of a dataset 
    dynamic properties = new ExpandoObject();
    properties.name = new {
          en = "<new title of your dataset>"
        };
    
    dynamic securable = client.update("securable", "<your securable id>", );
    
       Update the name of a dataset 
    client.update('securable',
      '<your securable id>',
      {
        name: {
            en: '<new title of your dataset>'
        }
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Update the name of a dataset 
    <?php
    $user = $client->update('securable', '<your securable id>', 
      array (
        'name' => array (
          'en' => '<new title of your dataset>'
        )
      ));
    ?>
    
       Update the name of a dataset 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "properties": {
      "name": {
        "en": "<new title of your dataset>"
      }
    }
    }
    EOF
    
       Update the name of a dataset 
    securable = client.update("securable", "<your_securable_id>", {
        "name": {
          "en": "<new title of your dataset>"
        }
    })
    
    Update
    can be executed by:
    Securable Modifier

    Only the owner of the dataset can update the dataset. Other users can be made owner by associating them with the dataset and using the 'flagOwner'.

    Action: Get

       Retrieve all datasets together with the users and groups that have access (only users and groups that you can access) 
    JSONObject data = client.get("securable", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "type" , "dataset"
        ),
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "Group",
            "include" , ImmutableList.of(
    
              ImmutableMap.of(
                "model" , "User"
              )
            )
          ),
    
          ImmutableMap.of(
            "model" , "User"
          )
        )
      ));
    
    
       Retrieve all datasets together with the users and groups that have access (only users and groups that you can access) 
    dynamic query = new ExpandoObject();
    query.where = new {
          type = "dataset"
        };
    query.include = new List<Object> {
    
          new {
            model = "Group",
            include = new List<Object> {
    
              new {
                model = "User"
              }
            }
          },
    
          new {
            model = "User"
          }
        };
    
    dynamic data = client.get("securable",     query);
    
    
       Retrieve all datasets together with the users and groups that have access (only users and groups that you can access) 
    client.get('securable', {
        where: {
            type: 'dataset'
        },
        include: [
            {
                model: 'Group',
                include: [
                    {
                        model: 'User'
                    }
                ]
            },
            {
                model: 'User'
            }
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Retrieve all datasets together with the users and groups that have access (only users and groups that you can access) 
    <?php
    $user = $client->get('securable', 
      array (
        'where' => array (
          'type' => 'dataset'
        ),
        'include' => array (
    
          array (
            'model' => 'Group',
            'include' => array (
    
              array (
                'model' => 'User'
              )
            )
          ),
    
          array (
            'model' => 'User'
          )
        )
      ));
    
    ?>
    
       Retrieve all datasets together with the users and groups that have access (only users and groups that you can access) 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "type": "dataset"
      },
      "include": [
        {
          "model": "Group",
          "include": [
            {
              "model": "User"
            }
          ]
        },
        {
          "model": "User"
        }
      ]
    }
    }
    EOF
    
    
       Retrieve all datasets together with the users and groups that have access (only users and groups that you can access) 
    data = client.get("securable", {
        "where": {
          "type": "dataset"
        },
        "include": [{
          "model": "Group",
          "include": [{
            "model": "User"
          }]
        },{
          "model": "User"
        }]
    })
    
    
       Example of the return structure of a dataset. 
    {
      "count": 1,
      "rows": [
        {
          "id": "8bbbb0b6-d71b-464d-8cf4-ddce01fa1354",
          "type": "dataset",
          "subtype": "api",
          "name": {
            "en": "NameOfDataset"
          },
          "description": null,
          "contents": null,
          "css": null,
          "rows": 0,
          "featured": false,
          "created_at": "2018-08-29T12:08:37.828Z",
          "updated_at": "2018-08-29T12:08:38.135Z",
          "source_id": null,
          "modified_at": "2018-08-29T12:08:38.113Z",
          "modifier_id": "f803b836-53e7-43b4-ac2b-621f28398dd4",
          "owner_id": "f803b836-53e7-43b4-ac2b-621f28398dd4",
          ...
          "cache": 0,
          "groups": [
            {
              "id": "0e4a3317-e993-42fb-b9bf-d13de1206c42",
              ...
              "groupAccessRight": {
                "flagRead": true,
                "flagUse": false,
                "flagModify": false,
                "flagOwn": false,
                "published": false,
                "filters": null,
                "created_at": "2018-08-29T12:08:45.980Z",
                "updated_at": "2018-08-29T12:08:45.980Z",
                "group_id": "0e4a3317-e993-42fb-b9bf-d13de1206c42",
                "securable_id": "8bbbb0b6-d71b-464d-8cf4-ddce01fa1354"
              },
              "users": [
                {
                  "name": "Mr Unit McTestFace1",
                  ...
                  "groupRole": {
                    "flagMember": true,
                    "flagOwn": false,
                    "created_at": "2018-08-29T12:08:37.159Z",
                    "updated_at": "2018-08-29T12:08:45.000Z",
                    "user_id": "12e28199-705c-4df6-b8f0-b5a496b40371",
                    "group_id": "0e4a3317-e993-42fb-b9bf-d13de1206c42"
                  }
                },
                {
                  "name": "Mr Unit McTestFace2",
                  ....
                  "groupRole": {
                    "flagMember": true,
                    "flagOwn": true,
                    "created_at": "2018-08-29T12:08:37.142Z",
                    "updated_at": "2018-08-29T12:08:37.142Z",
                    "user_id": "f803b836-53e7-43b4-ac2b-621f28398dd4",
                    "group_id": "0e4a3317-e993-42fb-b9bf-d13de1206c42"
                  }
                }
              ]
            }
          ],
          "users": [
            {
              "name": "Mr Unit McTestFace",
              ...
              "userAccessRight": {
                "flagRead": true,
                "flagUse": true,
                "flagModify": true,
                "flagOwn": true,
                "filters": null,
                "created_at": "2018-08-29T12:08:37.848Z",
                "updated_at": "2018-08-29T12:08:37.848Z",
                "user_id": "f803b836-53e7-43b4-ac2b-621f28398dd4",
                "securable_id": "8bbbb0b6-d71b-464d-8cf4-ddce01fa1354"
              }
            },
            ...
          ]
        }
      ]
    }
    
    Get
    can be executed by:
    Securable Reader
    List
    can be executed by:
    Securable Reader

    Only users who have read access to the dataset can retrieve the dataset.

    Action: Delete

       Delete a dataset 
    client.delete("securable", "<your securable id>");
    
       Delete a dataset 
    $client->delete("securable", "<your securable id>");
    
       Delete a dataset 
    let promise = client.delete('securable', '<your securable id>');
    
       Delete a dataset 
    <?php
    $client->delete('securable', '<your securable id>');
    ?>
    
       Delete a dataset 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>"
    }
    EOF
    
       Delete a dataset 
    client.delete("securable", "<your_securable_id>")
    
    Delete
    can be executed by:
    Securable Owner

    Delete a dataset by providing the id of the group.

    Associations

    Note that associations listed in the schema are the same for dataset and dashboard. Some associations only make sense for one of the two (e.g. Thumbnail does nothing for a Dataset) or have different significations.

    %3 <!-- Removed the Plugin association --> <!-- Dashboard --> Dashboard Dashboard <!-- Securable --> Securable Securable <!-- Dashboard->Securable --> Dashboard->Securable <!-- Dataset --> Dataset Dataset <!-- Dataset->Securable --> Dataset->Securable <!-- Securable->Securable --> Securable->Securable <!-- Column --> Column Column <!-- Securable->Column --> Securable->Column <!-- User --> User User <!-- User->Securable --> User->Securable <!-- Thumbnail --> Thumbnail Thumbnail <!-- Thumbnail->Securable --> Thumbnail->Securable <!-- Tag --> Tag Tag <!-- Tag->Securable --> Tag->Securable <!-- Share --> Share Share <!-- Share->Securable --> Share->Securable <!-- Group --> Group Group <!-- Group->Securable --> Group->Securable <!-- Schedule --> Schedule Schedule <!-- Schedule->Securable --> Schedule->Securable

    Associate: Column

       Add a column to your dataset (you have to create the column first) 
    client.associate("securable", "<your securable id>", "Columns", "<  column id>");
    
       Add a column to your dataset (you have to create the column first) 
    
    client.associate("securable", "<your securable id>", "Columns", "<  column id>");
    
       Add a column to your dataset (you have to create the column first) 
    let promise = client.associate('securable', '<your securable id>', {
        role: 'Columns',
        id: '<  column id>'
    });
    
       Add a column to your dataset (you have to create the column first) 
    <?php
    $client->associate('securable', '<your securable id>', 'Columns', '<  column id>', );
    ?>
    
       Add a column to your dataset (you have to create the column first) 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
        "role": "Columns",
        "id": "<  column id>"
      }
    }
    EOF
    
       Add a column to your dataset (you have to create the column first) 
    client.associate("securable", "<your_securable_id>", {"role":"Columns","id":"<  column id>"})
    
    Dataset
    Column
    Associate
    requires:
    Securable Modifier

    Columns contain the information of a column (not the data) within your datasets. When preparing your columns, be careful that when you upload data with the 'data' endpoint that the amount of columns corresponds to the data structure you will upload.

    Associate: Group

       Link a group to a securable, and give read/use/write access to that group 
    client.associate("group", "<your group id>", "Securables", "< your securable (dashboard or dataset) id>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagModify" , true,
        "flagUse" , true,
        "flagOwn" , false
      ) );
    
       Link a group to a securable, and give read/use/write access to that group 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagModify = true;
    properties.flagUse = true;
    properties.flagOwn = false;
    
    client.associate("group", "<your group id>", "Securables", "< your securable (dashboard or dataset) id>",     properties );
    
       Link a group to a securable, and give read/use/write access to that group 
    let promise = client.associate('group', '<your group id>', {
        role: 'Securables',
        id: '< your securable (dashboard or dataset) id>'
    },
    {
        flagRead: true,
        flagModify: true,
        flagUse: true,
        flagOwn: false
    });
    
       Link a group to a securable, and give read/use/write access to that group 
    <?php
    $client->associate('group', '<your group id>', 'Securables', '< your securable (dashboard or dataset) id>', , 
      array (
        'flagRead' => true,
        'flagModify' => true,
        'flagUse' => true,
        'flagOwn' => false
      ) );
    ?>
    
       Link a group to a securable, and give read/use/write access to that group 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
        "role": "Securables",
        "id": "< your securable (dashboard or dataset) id>"
      },
      "properties": {
        "flagRead": true,
        "flagModify": true,
        "flagUse": true,
        "flagOwn": false
      }
    }
    EOF
    
       Link a group to a securable, and give read/use/write access to that group 
    client.associate("group", "<your_group_id>", {"role":"Securables","id":"< your securable (dashboard or dataset) id>"}, {
        "flagRead": True,
        "flagModify": True,
        "flagUse": True,
        "flagOwn": False
    } )
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    client.associate("group", "<id of the public group>", "Securables", "< your securable (dataset or dashboard) id>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagModify" , false,
        "flagUse" , false,
        "flagOwn" , false,
        "published" , false
      ) );
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagModify = false;
    properties.flagUse = false;
    properties.flagOwn = false;
    properties.published = false;
    
    client.associate("group", "<id of the public group>", "Securables", "< your securable (dataset or dashboard) id>",     properties );
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    let promise = client.associate('group', '<id of the public group>', {
        role: 'Securables',
        id: '< your securable (dataset or dashboard) id>'
    },
    {
        flagRead: true,
        flagModify: false,
        flagUse: false,
        flagOwn: false,
        published: false
    });
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    <?php
    $client->associate('group', '<id of the public group>', 'Securables', '< your securable (dataset or dashboard) id>', , 
      array (
        'flagRead' => true,
        'flagModify' => false,
        'flagUse' => false,
        'flagOwn' => false,
        'published' => false
      ) );
    ?>
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<id of the public group>",
      "resource": {
        "role": "Securables",
        "id": "< your securable (dataset or dashboard) id>"
      },
      "properties": {
        "flagRead": true,
        "flagModify": false,
        "flagUse": false,
        "flagOwn": false,
        "published": false
      }
    }
    EOF
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    client.associate("group", "<your_group_id>", {"role":"Securables","id":"< id of the public group>"}, {
        "flagRead": True,
        "flagModify": False,
        "flagUse": False,
        "flagOwn": False,
        "published": False
    } )
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    client.associate("group", "<id of the public group>", "Securables", "< your securable (dataset or dashboard) id>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagModify" , false,
        "flagUse" , true,
        "flagOwn" , false,
        "published" , true
      ) );
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagModify = false;
    properties.flagUse = true;
    properties.flagOwn = false;
    properties.published = true;
    
    client.associate("group", "<id of the public group>", "Securables", "< your securable (dataset or dashboard) id>",     properties );
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    let promise = client.associate('group', '<id of the public group>', {
        role: 'Securables',
        id: '< your securable (dataset or dashboard) id>'
    },
    {
        flagRead: true,
        flagModify: false,
        flagUse: true,
        flagOwn: false,
        published: true
    });
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    <?php
    $client->associate('group', '<id of the public group>', 'Securables', '< your securable (dataset or dashboard) id>', , 
      array (
        'flagRead' => true,
        'flagModify' => false,
        'flagUse' => true,
        'flagOwn' => false,
        'published' => true
      ) );
    ?>
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<id of the public group>",
      "resource": {
        "role": "Securables",
        "id": "< your securable (dataset or dashboard) id>"
      },
      "properties": {
        "flagRead": true,
        "flagModify": false,
        "flagUse": true,
        "flagOwn": false,
        "published": true
      }
    }
    EOF
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    client.associate("group", "<your_group_id>", {"role":"Securables","id":"< id of the public group>"}, {
        "flagRead": True,
        "flagModify": False,
        "flagUse": True,
        "flagOwn": False,
        "published": True
    } )
    
    Group
    Securable
    flagRead
    Grant the right to query the dataset
    flagUse
    Right required to use the dataset in the dashboard editor to create dashboards with it
    flagModify
    Right to modify the dataset, e.g. add a derived column
    flagOwn
    Right to delete the dataset, or to modify the access rights e.g. by associating the dataset with users (multiple users can be owner)
    published
    The dataset/dashboard will be listed in the public datasets/dashboards on Luzmo. This is a useful feature if you are providing open data for the public. To avoid mistakes, this feature is only enabled for clients that specifically ask for this.
    Associate
    requires:
    Group Owner
    and
    Securable Owner

    Groups can be used to give a group of users access to securables (dashboards or datasets). In order to do so, the group has to be associated with the securables to give access. Several flags on the association you to control the type of access. An association without providing flags will not have effect.

    Associate: Schedule

       Associate a schedule with a securable in order to start synchronizing the securable. 
    client.associate("schedule", "<your schedule id>", "Securables", "<dataset id>");
    
       Associate a schedule with a securable in order to start synchronizing the securable. 
    
    client.associate("schedule", "<your schedule id>", "Securables", "<dataset id>");
    
       Associate a schedule with a securable in order to start synchronizing the securable. 
    let promise = client.associate('schedule', '<your schedule id>', {
        role: 'Securables',
        id: '<dataset id>'
    });
    
       Associate a schedule with a securable in order to start synchronizing the securable. 
    <?php
    $client->associate('schedule', '<your schedule id>', 'Securables', '<dataset id>', );
    ?>
    
       Associate a schedule with a securable in order to start synchronizing the securable. 
    curl https://api.luzmo.com/0.1.0/schedule  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your schedule id>",
      "resource": {
        "role": "Securables",
        "id": "<dataset id>"
      }
    }
    EOF
    
       Associate a schedule with a securable in order to start synchronizing the securable. 
    client.associate("schedule", "<your_schedule_id>", {"role":"Securables","id":"<dataset id>"})
    
    Dataset
    Schedule
    Associate
    requires:
    Securable Modifier

    Schedules are used to schedule synchronization for datasets coming from Webservice connectors (e.g. Google Drive, Asana, etc.). To start scheduling a specific dataset, you need to link the schedule to the dataset by associating them.

    Associate: User

       Link a user to a dataset in order to make that dataset readable by the user 
    client.associate("securable", "<your securable id>", "Users", "< your user id>", 
      ImmutableMap.of(
        "flagRead" , true
      ));
    
       Link a user to a dataset in order to make that dataset readable by the user 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    
    client.associate("securable", "<your securable id>", "Users", "< your user id>",     properties );
    
       Link a user to a dataset in order to make that dataset readable by the user 
    let promise = client.associate('securable', '<your securable id>', {
        role: 'Users',
        id: '< your user id>'
    },
    {
        flagRead: true
    });
    
       Link a user to a dataset in order to make that dataset readable by the user 
    <?php
    $client->associate('securable', '<your securable id>', 'Users', '< your user id>', , 
      array (
        'flagRead' => true
      ));
    ?>
    
       Link a user to a dataset in order to make that dataset readable by the user 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      },
      "properties": {
        "flagRead": true
      }
    }
    EOF
    
       Link a user to a dataset in order to make that dataset readable by the user 
    client.associate("securable", "<your_securable_id>", {"role":"Users","id":"< your user id>"}, {
        "flagRead": True
    } )
    
       Link a user to a dataset and give him all the rights (making him also owner of the dataset) 
    client.associate("securable", "<your securable id>", "Users", "< your user id>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagOwn" , true,
        "flagUse" , true,
        "flagModify" , true
      ));
    
       Link a user to a dataset and give him all the rights (making him also owner of the dataset) 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagOwn = true;
    properties.flagUse = true;
    properties.flagModify = true;
    
    client.associate("securable", "<your securable id>", "Users", "< your user id>",     properties );
    
       Link a user to a dataset and give him all the rights (making him also owner of the dataset) 
    let promise = client.associate('securable', '<your securable id>', {
        role: 'Users',
        id: '< your user id>'
    },
    {
        flagRead: true,
        flagOwn: true,
        flagUse: true,
        flagModify: true
    });
    
       Link a user to a dataset and give him all the rights (making him also owner of the dataset) 
    <?php
    $client->associate('securable', '<your securable id>', 'Users', '< your user id>', , 
      array (
        'flagRead' => true,
        'flagOwn' => true,
        'flagUse' => true,
        'flagModify' => true
      ));
    ?>
    
       Link a user to a dataset and give him all the rights (making him also owner of the dataset) 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      },
      "properties": {
        "flagRead": true,
        "flagOwn": true,
        "flagUse": true,
        "flagModify": true
      }
    }
    EOF
    
       Link a user to a dataset and give him all the rights (making him also owner of the dataset) 
    client.associate("securable", "<your_securable_id>", {"role":"Users","id":"< your user id>"}, {
        "flagRead": True,
        "flagOwn": True,
        "flagUse": True,
        "flagModify": True
    } )
    
       Link a user to a dataset, give him use rights and apply some filters 
    client.associate("securable", "<your securable id>", "Users", "< your user id>", 
      ImmutableMap.of(
        "flagRead", true,
        "flagUse" , true,
        "filters", ImmutableList.of(
          ImmutableMap.of(
            "clause", "where",
            "origin", "global",
            "securable_id", "< dataset id >",
            "column_id", "< column id of a column in the dataset >",
            "expression", "? = ?",
            "value", "< value to be applied to the expression >"
          )
        )
      ) 
    );
    
       Link a user to a dataset, give him use rights and apply some filters 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagUse = true;
    
    properties.filters = new List<dynamic> {
      new {  
        clause = "where";
        origin = "global";
        securable_id = "< dataset id >";
        column_id = "< column id of a column in the dataset >";
        expression = "? = ?";
        value = "< value to be applied to the expression >";
      }
    };
    
    client.associate("securable", "<your securable id>", "Users", "< your user id>",   properties );
    
       Link a user to a dataset, give him use rights and apply some filters
    let promise = client.associate('securable', '<your securable id>', {
      role: 'Users',
      id: '< your user id>'
    },
    {
      flagRead: true,
      flagUse: true,
      filters: [
        {
          clause: 'where',
          origin: 'global',
          securable_id: '< dataset id >',
          column_id: '< column id of a column used in the dataset >',  
          expression: '? = ?',
          value: '< value to be applied to the expression >'
        }  
      ]
    });
    
       Link a user to a dataset, give him use rights and apply some filters 
    <?php
    $client->associate('securable', '<your securable id>', 'Users', '< your user id>', , 
      array (
        'flagRead' => true,
        'flagUse' => true,
        'filters' => array(
          'clause'       => 'where',
          'origin'       => 'global',
          'securable_id' => '< dataset id >',
          'column_id'    => '< column id of a column used in the dataset >',
          'expression'   => '? = ?',
          'value'        => '< value to be applied to the expression >'
        )
      ) );
    ?>
    
       Link a user to a dataset, give him use rights and apply some filters
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      },
      "properties": {
        "flagRead": true,
        "flagUse": true,
        "filters": [
            {
              "clause": "where",
              "origin": "global",
              "securable_id": "< dataset id >",
              "column_id": "< column id of a column used in the dataset >",  
              "expression": "? = ?",
              "value": "< value to be applied to the expression >"
            }
          ]
      }
    }
    EOF
    
    User
    Securable
    flagRead
    Grant the right to query the dataset
    flagUse
    Right required to use the dataset in the dashboard editor to create dashboards with it
    flagModify
    Right to modify the dataset, e.g. add a derived column
    flagOwn
    Right to delete the dataset, or to modify the access rights e.g. by associating the dataset with users (multiple users can be owner)
    Associate
    requires:
    Securable Owner
    and
    Logged-in User

    A user can be linked to a securable to give him access to that dataset. To start associating, note that a dataset is a subclass of securable so we use securable in the calls. The association has flag properties to define what kind of access the user will receive. In order to start associating dashboards with users, you already need to be resource owner. That means that you either created the dashboard or received access from someone that associated you with the dashboard using the flagOwn = true property. That way it is possible to set multiple owners for a dataset. In addition to setting ownership properties, you can supply filters when associating a dataset to a user. When a user opens or uses the dataset, these filters will be applied. The syntax is identical to creating an authorization with filters.

    Dissociate

       Remove a column 
    client.dissociate("securable", "<your securable id>", "Columns", "<  column id>");
    
       Remove a column 
    client.dissociate("securable", "<your securable id>", "Columns", "<  column id>");
    
       Remove a column 
    let promise = client.dissociate('securable', '<your securable id>', {
        role: 'Columns',
        id: '<  column id>'
    });
    
       Remove a column 
    <?php
    $client->associate('securable', '<your securable id>', "Columns", "<  column id>");
    ?>
    
       Remove a column 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
      "role": "Columns",
      "id": "<  column id>"
    }
    }
    EOF
    
       Remove a column 
    client.dissociate("securable", "<your_securable_id>", {"role":"Columns","id":"<  column id>"})
    
       Revoke access for a user (he might still have access through other ways such as a group or the organization) 
    client.dissociate("securable", "<your securable id>", "Users", "< user id >");
    
       Revoke access for a user (he might still have access through other ways such as a group or the organization) 
    client.dissociate("securable", "<your securable id>", "Users", "< user id >");
    
       Revoke access for a user (he might still have access through other ways such as a group or the organization) 
    let promise = client.dissociate('securable', '<your securable id>', {
        role: 'Users',
        id: '< user id >'
    });
    
       Revoke access for a user (he might still have access through other ways such as a group or the organization) 
    <?php
    $client->associate('securable', '<your securable id>', "Users", "< user id >");
    ?>
    
       Revoke access for a user (he might still have access through other ways such as a group or the organization) 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
      "role": "Users",
      "id": "< user id >"
    }
    }
    EOF
    
       Revoke access for a user (he might still have access through other ways such as a group or the organization) 
    client.dissociate("securable", "<your_securable_id>", {"role":"Users","id":"< user id >"})
    

    Dissociating is similar for all resources. To break the link between two resources, simply provide the resource names and ids. Be careful that the 'role' of a resource is uppercase and usually plural. Dissociating can be done in both directions.

    EmbedFilterGroup

    Embed filters are used to set up (parameterized) filters on one or more datasets, which will always be applied when those datasets are queried in an embedded context. For each organization you can only have a single embedFilterGroup. Via our UI, the Embed filter group is automatically created when an organization owner user has set up the first embed filter.
    The (parameterized) dataset filters are specified on the association between the embed filter group and a dataset (see below). To override the default parameter value(s) (or clear the parameterized filter(s)), you should use the parameter_overrides property in the Authorization request (see Authorization resource properties);

    Actions

    Create
    Get
    List
    Associate
    Dissociate

    Action: Create

       Creating a group 
    JSONObject embedfiltergroup = client.create("embedfiltergroup",
        ImmutableMap.of()
      );
    System.out.println("Success! %s%n", embedfiltergroup);
    
       Creating a group 
    dynamic properties = new ExpandoObject();
    
    dynamic embedfiltergroup = client.create("embedfiltergroup",    properties);
    Console.WriteLine("Success!", embedfiltergroup);
    
       Creating a group 
    client.create('embedfiltergroup', {})
      .then(function(embedfiltergroup) {
        console.log('Success!', embedfiltergroup);
      });
    
       Creating a group 
    <?php
    $embedfiltergroup = $client->create('embedfiltergroup', array ())
    
    );
    print("Success! { $embedfiltergroup }");
    ?>
    
       Creating a group 
    curl https://api.luzmo.com/0.1.0/embedfiltergroup  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {}
    }
    }
    EOF
    
    
       Creating a group 
    embedfiltergroup = client.create("embedfiltergroup", {})
    print("Success! ", embedfiltergroup)
    
    Create
    can be executed by:
    Organization Owner

    Only organization owners can create a group. an organization can only have one embedfiltergroup.

    Action: Get

       Getting an embedfiltergroup 
    JSONObject data = client.get("embedfiltergroup", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "id" , "<your embedfiltergroup id>"
        )
      ));
    
    
        Getting an embedfiltergroup  
    dynamic query = new ExpandoObject();
    query.where = new {
          id = "<your embedfiltergroup id>"
        };
    
    dynamic data = client.get("embedfiltergroup",  query);
    
    
       Getting an embedfiltergroup  
    client.get('embedfiltergroup', {
        where: {
            id: '<your embedfiltergroup id>'
        }
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Getting an embedfiltergroup 
    <?php
    $user = $client->get('embedfiltergroup', 
      array (
        'where' => array (
          'id' => '<your embedfiltergroup id>'
        )
      ));
    
    ?>
    
       Getting an embedfiltergroup  
    curl https://api.luzmo.com/0.1.0/embedfiltergroup  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "id": "<your embedfiltergroup id>"
      }
    }
    }
    EOF
    
    
       Getting an embedfiltergroup  
    data = client.get("embedfiltergroup", {
        "where": {
          "id": "<your embedfiltergroup id>"
        }
    })
    
    
    Get
    can be executed by:
    Organization Owner
    List
    can be executed by:
    Organization Owner

    Associations

    EmbedFilterGroups are explicitly connected to securables and implicitly connected to the organization and the user who first created it.

       Example query to associate an embedfiltergroup with a dataset securable, including a parameterized filter 
    client.associate("embedfiltergroup", "<your embed filter group id >", "Securables", "< your dataset id >",
      ImmutableMap.of(
        "filters", ImmutableList.of(
          ImmutableMap.of(
            "clause", "where",
            "origin", "global",
            "securable_id", "< dataset id >",
            "column_id", "< column id of a column in the dataset >",
            "expression", "? in ?",
            "value", ImmutableMap.of(
              parameter: "metadata.< parameter name >",
              type: "array[hierarchy]",
              value: ImmutableList.of(
                "< default parameter value >"
              )
            )
          )
        )
      )
    );
    
       Example query to associate an embedfiltergroup with securable, including a parameterized filter 
    dynamic properties = new ExpandoObject();
    
    properties.filters = new List<dynamic> {
      new {  
        clause = "where";
        origin = "global";
        securable_id = "< dataset id >";
        column_id = "< column id of a column in the dataset >";
        expression = "? in ?";
        value = new {
          parameter: "metadata.< parameter name >",
          type: "array[hierarchy]",
          value: new List<String> {
            "< default parameter value >"
          }
        };
      }
    };
    
    client.associate("embedfiltergroup", "< your embedfiltergroup id >", "Securables", "< your dataset id >",   properties );
    
       Example query to associate an embedfiltergroup with securable, including a parameterized filter 
    let promise = client.associate("embedfiltergroup", "< your embedfiltergroup id >", {
      role: "Securables",
      id: "< your dataset id >"
    },
    {
      filters: [
        {
          clause: "where",
          origin: "global",
          securable_id: "< dataset id >",
          column_id: "< column id of a column used in the dataset >",  
          expression: "? in ?",
          value: {
            parameter: "metadata.< parameter name >",
            type: "array[hierarchy]",
            value: ["< default parameter value >"]
          }
        }  
      ]
    });
    
       Example query to associate an embedfiltergroup with securable, including a parameterized filter 
    <?php
    $client->associate("embedfiltergroup", "< your embedfiltergroup id >", "Securables", "< your dataset id >", ,
      array (
        "filters" => array(
          array(
            "clause"       => "where",
            "origin"       => "global",
            "securable_id" => "< dataset id >",
            "column_id"    => "< column id of a column used in the dataset >",
            "expression"   => "? in ?",
            "value"        => array(
              "parameter" => "metadata.< parameter name >",
              "type" => "array[hierarchy]",
              "value" => array("< default parameter value >")
            )
          )
        )
      ) );
    ?>
    
       Example query to associate an embedfiltergroup with securable, including a parameterized filter 
    curl https://api.luzmo.com/0.1.0/embedfiltergroup  \
    -H "Content-Type: application/json"  \
    -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "< your embedfiltergroup id >",
      "resource": {
        "role": "Securables",
        "id": "< your dataset id >"
      },
      "properties": {
        "filters": [
            {
              "clause": "where",
              "origin": "global",
              "securable_id": "< dataset id >",
              "column_id": "< column id of a column used in the dataset >",  
              "expression": "? in ?",
              "value": {
                "parameter": "metadata.< parameter name >",
                "type": "array[hierarchy]",
                "value": ["< default parameter value >"]
              }
            }
          ]
      }
    }
    EOF
    
       Example query to associate an embedfiltergroup with securable, including a parameterized filter 
    client.associate("embedfiltergroup", "< your embedfiltergroup id >", {
      "role": "Securables",
      "id": "< your dataset id >"
    },
    {
      "filters": [
        {
          "clause": "where",
          "origin": "global",
          "securable_id": "< dataset id >",
          "column_id": "< column id of a column used in the dataset >",  
          "expression": "? in ?",
          "value": {
            "parameter": "metadata.< parameter name >",
            "type": "array[hierarchy]",
            "value": ["< default parameter value >"]
          }
        }  
      ]
    });
    

    Dissociate

    EmbedFilterGroups are explicitly connected to securables and implicitly connected to the organization and the user who first created it. you can dissociate an embedfiltergroup from a securable by calling the dissociate method with the embedfiltergroup id and the securable id.

    Group

    Division or group within or across the bounds of organizations. Groups have administrators and members and can be assigned access rights to datasets or dashboards.

    The creating user of a group is automatically given group owner rights. Groups can be created by any user. Only group owners can update or delete a group, or associate or dissociate new group members.

    Properties

    Parameter
    Description
    id
    uuid
    Unique key of the group (automatically assigned)
    name
    localized
    Name of the group

    Actions

    Create
    Get
    List
    Delete
    Update
    Associate
    Dissociate

    Action: Create

       Creating a group 
    JSONObject group = client.create("group",
    
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "< group name in English ›",
          "fr" , "< group name in French >"
        )
      ));
    System.out.println("Success! %s%n", group);
    
       Creating a group 
    dynamic properties = new ExpandoObject();
    properties.name = new {
          en = "< group name in English ›",
          fr = "< group name in French >"
        };
    
    dynamic group = client.create("group",    properties);
    Console.WriteLine("Success!", group);
    
       Creating a group 
    client.create('group',
      {
        name: {
            en: '< group name in English ›',
            fr: '< group name in French >'
        }
    }
    
    )
      .then(function(group) {
        console.log('Success!', group);
      });
    
       Creating a group 
    <?php
    $group = $client->create('group',
    
      array (
        'name' => array (
          'en' => '< group name in English ›',
          'fr' => '< group name in French >'
        )
      )
    
    );
    print("Success! { $group }");
    ?>
    
       Creating a group 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "name": {
        "en": "< group name in English ›",
        "fr": "< group name in French >"
      }
    }
    }
    EOF
    
    
       Creating a group 
    group = client.create("group",
    {
        "name": {
          "en": "< group name in English ›",
          "fr": "< group name in French >"
        }
    })
    print("Success! ", group)
    
    Create
    can be executed by:
    Logged-in User

    Any user with an API token can create a group. The group will be automatically linked to the user on creation (which will be the group owner). Creating a group does not necessarily require parameters but you can provide the group with a name. The name will be used in the interface.

    Action: Update

       Updating a group 
    JSONObject group = client.update("group", "<your group id>", 
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "< new group name in English >",
          "fr" , "< new group name in French >"
        )
      ));
    
       Updating a group 
    dynamic properties = new ExpandoObject();
    properties.name = new {
          en = "< new group name in English >",
          fr = "< new group name in French >"
        };
    
    dynamic group = client.update("group", "<your group id>", );
    
       Updating a group 
    client.update('group',
      '<your group id>',
      {
        name: {
            en: '< new group name in English >',
            fr: '< new group name in French >'
        }
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Updating a group 
    <?php
    $user = $client->update('group', '<your group id>', 
      array (
        'name' => array (
          'en' => '< new group name in English >',
          'fr' => '< new group name in French >'
        )
      ));
    ?>
    
       Updating a group 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "properties": {
      "name": {
        "en": "< new group name in English >",
        "fr": "< new group name in French >"
      }
    }
    }
    EOF
    
       Updating a group 
    group = client.update("group", "<your_group_id>", {
        "name": {
          "en": "< new group name in English >",
          "fr": "< new group name in French >"
        }
    })
    
    Update
    can be executed by:
    Group Owner

    Only the owner of the group can update the group. Other users can be made owner by associating them with the group and using the 'flagOwner'.

    Action: Get

       Getting a group together with its users and the securables it gives access to (Dashboards/Datasets) 
    JSONObject data = client.get("group", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "id" , "<your group id>"
        ),
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "User"
          ),
    
          ImmutableMap.of(
            "model" , "Securable"
          )
        )
      ));
    
    
       Getting a group together with its users and the securables it gives access to (Dashboards/Datasets) 
    dynamic query = new ExpandoObject();
    query.where = new {
          id = "<your group id>"
        };
    query.include = new List<Object> {
    
          new {
            model = "User"
          },
    
          new {
            model = "Securable"
          }
        };
    
    dynamic data = client.get("group",     query);
    
    
       Getting a group together with its users and the securables it gives access to (Dashboards/Datasets) 
    client.get('group', {
        where: {
            id: '<your group id>'
        },
        include: [
            {
                model: 'User'
            },
            {
                model: 'Securable'
            }
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Getting a group together with its users and the securables it gives access to (Dashboards/Datasets) 
    <?php
    $user = $client->get('group', 
      array (
        'where' => array (
          'id' => '<your group id>'
        ),
        'include' => array (
    
          array (
            'model' => 'User'
          ),
    
          array (
            'model' => 'Securable'
          )
        )
      ));
    
    ?>
    
       Getting a group together with its users and the securables it gives access to (Dashboards/Datasets) 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "id": "<your group id>"
      },
      "include": [
        {
          "model": "User"
        },
        {
          "model": "Securable"
        }
      ]
    }
    }
    EOF
    
    
       Getting a group together with its users and the securables it gives access to (Dashboards/Datasets) 
    data = client.get("group", {
        "where": {
          "id": "<your group id>"
        },
        "include": [{
          "model": "User"
        },{
          "model": "Securable"
        }]
    })
    
    
       Example of the return structure of the query above 
    {
       "count": 1,
       "rows": [
         {
           "id": "f5aff911-94fc-45f3-9de2-68e3a0a82334",
           "name": {
             "en": "MyGroup"
           },
           "created_at": "2018-08-28T10:12:23.625Z",
           "updated_at": "2018-08-28T10:12:23.625Z",
           "deleted_at": null,
           "public": false,
           "open": false,
           "users": [
             {
               "email": "someuser1@luzmo.com",
               "name": "Mr Unit McTestFace",
               "city": "SmallUnitVille",
               "country_id": null,
               "locale_id": "en",
               "created_at": "2018-08-28T10:12:22.563Z",
               "id": "a7a900a2-b14e-49cc-94ea-7b034407be86",
               "groupRole": {
                 "flagMember": true,
                 "flagOwn": true,
                 "created_at": "2018-08-28T10:12:23.631Z",
                 "updated_at": "2018-08-28T10:12:23.631Z",
                 "user_id": "a7a900a2-b14e-49cc-94ea-7b034407be86",
                 "group_id": "f5aff911-94fc-45f3-9de2-68e3a0a82334"
               }
             },
             {
               "email": "someuser2@luzmo.com",
               ...
               "groupRole": {
                 "flagMember": true,
                 "flagOwn": false,
                 ....
               }
             },
             {
               "email": "someuser3@luzmo.com",
               ....
               "groupRole": {
                 "flagMember": true,
                 "flagOwn": false,
                 ...
               }
             }
           ],
           "securables": [
             {
               "id": "c5f4a9ab-bace-485e-aeeb-a89ea76502b5",
               "type": "dataset",
               "subtype": "api",
               "name": {
                 "en": "SalesProfitCost2004.csv"
               },
               "description": null,
               ...
               "modifier_id": "a7a900a2-b14e-49cc-94ea-7b034407be86",
               "owner_id": "a7a900a2-b14e-49cc-94ea-7b034407be86",
               "groupAccessRight": {
                 "flagRead": true,
                 "flagUse": false,
                 ...
                 "published": false,
                 "filters": null,
                 ...
                 "group_id": "f5aff911-94fc-...",
                 "securable_id": "17866361-79f..."
               }
             },
             {
               "id": "17866361-79f7-4268-ba9f-a2eb5facd01d",
               ...
               "groupAccessRight": {
                 ...
               }
             }
           ]
         }
       ]
     }
    
    Get
    can be executed by:
    Group Member
    List
    can be executed by:
    Group Member

    Groups can only be retrieved by group members or owner. They are linked to Securables (Dashboard/Dataset) and users which can be included in the results. For example we could do a query to get all members of a group or retrieve all securables that a group has access to. Note that you will only receive the included entities to which you have access, for example you will only receive users in the group that are in your organization. Although you can add users outside of your organization to a group, you can not list their details.

    Action: Delete

       Delete a group using the id 
    client.delete("group", "<your group id>");
    
       Delete a group using the id 
    $client->delete("group", "<your group id>");
    
       Delete a group using the id 
    let promise = client.delete('group', '<your group id>');
    
       Delete a group using the id 
    <?php
    $client->delete('group', '<your group id>');
    ?>
    
       Delete a group using the id 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>"
    }
    EOF
    
       Delete a group using the id 
    client.delete("group", "<your_group_id>")
    
    Delete
    can be executed by:
    Group Owner

    Delete a group by providing the id of the group.

    Associations

    Groups are only connected to securables and users.

    %3 <!-- Dashboard --> Dashboard Dashboard <!-- Securable --> Securable Securable <!-- Dashboard->Securable --> Dashboard->Securable <!-- Dataset --> Dataset Dataset <!-- Dataset->Securable --> Dataset->Securable <!-- User --> User User <!-- Group --> Group Group <!-- User->Group --> User->Group <!-- Group->Securable --> Group->Securable

    Associate: Dashboard

       Link a user to a group and set him as member of that group 
    client.associate("group", "<your group id>", "Users", "< your user id>", 
      ImmutableMap.of(
        "flagMember" , true,
        "flagOwn" , false
      ) );
    
       Link a user to a group and set him as member of that group 
    dynamic properties = new ExpandoObject();
    properties.flagMember = true;
    properties.flagOwn = false;
    
    client.associate("group", "<your group id>", "Users", "< your user id>",     properties );
    
       Link a user to a group and set him as member of that group 
    let promise = client.associate('group', '<your group id>', {
        role: 'Users',
        id: '< your user id>'
    },
    {
        flagMember: true,
        flagOwn: false
    });
    
       Link a user to a group and set him as member of that group 
    <?php
    $client->associate('group', '<your group id>', 'Users', '< your user id>', , 
      array (
        'flagMember' => true,
        'flagOwn' => false
      ) );
    ?>
    
       Link a user to a group and set him as member of that group 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      },
      "properties": {
        "flagMember": true,
        "flagOwn": false
      }
    }
    EOF
    
       Link a user to a group and set him as member of that group 
    client.associate("group", "<your_group_id>", {"role":"Users","id":"< your user id>"}, {
        "flagMember": True,
        "flagOwn": False
    } )
    
       Link a group to a securable, and give read/use/write access to that group 
    client.associate("group", "<your group id>", "Securables", "< your securable (dashboard or dataset) id>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagModify" , true,
        "flagUse" , true,
        "flagOwn" , false
      ) );
    
       Link a group to a securable, and give read/use/write access to that group 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagModify = true;
    properties.flagUse = true;
    properties.flagOwn = false;
    
    client.associate("group", "<your group id>", "Securables", "< your securable (dashboard or dataset) id>",     properties );
    
       Link a group to a securable, and give read/use/write access to that group 
    let promise = client.associate('group', '<your group id>', {
        role: 'Securables',
        id: '< your securable (dashboard or dataset) id>'
    }, 
    {
        flagRead: true,
        flagModify: true,
        flagUse: true,
        flagOwn: false
    });
    
       Link a group to a securable, and give read/use/write access to that group 
    <?php
    $client->associate('group', '<your group id>', 'Securables', '< your securable (dashboard or dataset) id>', , 
      array (
        'flagRead' => true,
        'flagModify' => true,
        'flagUse' => true,
        'flagOwn' => false
      ) );
    ?>
    
       Link a group to a securable, and give read/use/write access to that group 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
        "role": "Securables",
        "id": "< your securable (dashboard or dataset) id>"
      },
      "properties": {
        "flagRead": true,
        "flagModify": true,
        "flagUse": true,
        "flagOwn": false
      }
    }
    EOF
    
       Link a group to a securable, and give read/use/write access to that group 
    client.associate("group", "<your_group_id>", {"role":"Securables","id":"< your securable (dashboard or dataset) id>"}, {
        "flagRead": True,
        "flagModify": True,
        "flagUse": True,
        "flagOwn": False
    } )
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    client.associate("group", "<your group id>", "Securables", "< id of the public group>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagModify" , false,
        "flagUse" , false,
        "flagOwn" , false,
        "published" , false
      ) );
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagModify = false;
    properties.flagUse = false;
    properties.flagOwn = false;
    properties.published = false;
    
    client.associate("group", "<your group id>", "Securables", "< id of the public group>",     properties );
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    let promise = client.associate('group', '<your group id>', {
        role: 'Securables',
        id: '< id of the public group>'
    },
    {
        flagRead: true,
        flagModify: false,
        flagUse: false,
        flagOwn: false,
        published: false
    });
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    <?php
    $client->associate('group', '<your group id>', 'Securables', '< id of the public group>', , 
      array (
        'flagRead' => true,
        'flagModify' => false,
        'flagUse' => false,
        'flagOwn' => false,
        'published' => false
      ) );
    ?>
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
        "role": "Securables",
        "id": "< id of the public group>"
      },
      "properties": {
        "flagRead": true,
        "flagModify": false,
        "flagUse": false,
        "flagOwn": false,
        "published": false
      }
    }
    EOF
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    client.associate("group", "<your_group_id>", {"role":"Securables","id":"< id of the public group>"}, {
        "flagRead": True,
        "flagModify": False,
        "flagUse": False,
        "flagOwn": False,
        "published": False
    } )
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    client.associate("group", "<your group id>", "Securables", "< id of the public group>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagModify" , false,
        "flagUse" , true,
        "flagOwn" , false,
        "published" , true
      ) );
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagModify = false;
    properties.flagUse = true;
    properties.flagOwn = false;
    properties.published = true;
    
    client.associate("group", "<your group id>", "Securables", "< id of the public group>",     properties );
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    let promise = client.associate('group', '<your group id>', {
        role: 'Securables',
        id: '< id of the public group>'
    },
    {
        flagRead: true,
        flagModify: false,
        flagUse: true,
        flagOwn: false,
        published: true
    });
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    <?php
    $client->associate('group', '<your group id>', 'Securables', '< id of the public group>', , 
      array (
        'flagRead' => true,
        'flagModify' => false,
        'flagUse' => true,
        'flagOwn' => false,
        'published' => true
      ) );
    ?>
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
        "role": "Securables",
        "id": "< id of the public group>"
      },
      "properties": {
        "flagRead": true,
        "flagModify": false,
        "flagUse": true,
        "flagOwn": false,
        "published": true
      }
    }
    EOF
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    client.associate("group", "<your_group_id>", {"role":"Securables","id":"< id of the public group>"}, {
        "flagRead": True,
        "flagModify": False,
        "flagUse": True,
        "flagOwn": False,
        "published": True
    } )
    
    Group
    Securable
    flagRead
    Grant the right to view the dashboard
    flagUse
    Right required for example to duplicate the dashboard
    flagModify
    Right to modify the dashboard
    flagOwn
    Right to delete the dashboard, or to modify the access rights e.g. by associating the dashboard with users (multiple users can be owner)
    published
    The dataset/dashboard will be listed in the public datasets/dashboards on Luzmo. This is a useful feature if you are providing open data for the public. To avoid mistakes, this feature is only enabled for clients that specifically ask for this.
    Associate
    requires:
    Group Owner
    and
    Securable Owner

    Groups can be used to give a group of users access to securables (dashboards or datasets). In order to do so, the group has to be associated with the securables to give access. Several flags on the association you to control the type of access. An association without providing flags will not have effect.

    Associate: Dataset

       Link a group to a securable, and give read/use/write access to that group 
    client.associate("group", "<your group id>", "Securables", "< your securable (dashboard or dataset) id>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagModify" , true,
        "flagUse" , true,
        "flagOwn" , false
      ) );
    
       Link a group to a securable, and give read/use/write access to that group 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagModify = true;
    properties.flagUse = true;
    properties.flagOwn = false;
    
    client.associate("group", "<your group id>", "Securables", "< your securable (dashboard or dataset) id>",     properties );
    
       Link a group to a securable, and give read/use/write access to that group 
    let promise = client.associate('group', '<your group id>', {
        role: 'Securables',
        id: '< your securable (dashboard or dataset) id>'
    },
    {
        flagRead: true,
        flagModify: true,
        flagUse: true,
        flagOwn: false
    });
    
       Link a group to a securable, and give read/use/write access to that group 
    <?php
    $client->associate('group', '<your group id>', 'Securables', '< your securable (dashboard or dataset) id>', , 
      array (
        'flagRead' => true,
        'flagModify' => true,
        'flagUse' => true,
        'flagOwn' => false
      ) );
    ?>
    
       Link a group to a securable, and give read/use/write access to that group 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
        "role": "Securables",
        "id": "< your securable (dashboard or dataset) id>"
      },
      "properties": {
        "flagRead": true,
        "flagModify": true,
        "flagUse": true,
        "flagOwn": false
      }
    }
    EOF
    
       Link a group to a securable, and give read/use/write access to that group 
    client.associate("group", "<your_group_id>", {"role":"Securables","id":"< your securable (dashboard or dataset) id>"}, {
        "flagRead": True,
        "flagModify": True,
        "flagUse": True,
        "flagOwn": False
    } )
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    client.associate("group", "<id of the public group>", "Securables", "< your securable (dataset or dashboard) id>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagModify" , false,
        "flagUse" , false,
        "flagOwn" , false,
        "published" , false
      ) );
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagModify = false;
    properties.flagUse = false;
    properties.flagOwn = false;
    properties.published = false;
    
    client.associate("group", "<id of the public group>", "Securables", "< your securable (dataset or dashboard) id>",     properties );
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    let promise = client.associate('group', '<id of the public group>', {
        role: 'Securables',
        id: '< your securable (dataset or dashboard) id>'
    },
    {
        flagRead: true,
        flagModify: false,
        flagUse: false,
        flagOwn: false,
        published: false
    });
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    <?php
    $client->associate('group', '<id of the public group>', 'Securables', '< your securable (dataset or dashboard) id>', , 
      array (
        'flagRead' => true,
        'flagModify' => false,
        'flagUse' => false,
        'flagOwn' => false,
        'published' => false
      ) );
    ?>
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<id of the public group>",
      "resource": {
        "role": "Securables",
        "id": "< your securable (dataset or dashboard) id>"
      },
      "properties": {
        "flagRead": true,
        "flagModify": false,
        "flagUse": false,
        "flagOwn": false,
        "published": false
      }
    }
    EOF
    
       Link the Public group to a securable, and give read access to everyone (necessary for private links) 
    client.associate("group", "<your_group_id>", {"role":"Securables","id":"< id of the public group>"}, {
        "flagRead": True,
        "flagModify": False,
        "flagUse": False,
        "flagOwn": False,
        "published": False
    } )
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    client.associate("group", "<id of the public group>", "Securables", "< your securable (dataset or dashboard) id>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagModify" , false,
        "flagUse" , true,
        "flagOwn" , false,
        "published" , true
      ) );
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagModify = false;
    properties.flagUse = true;
    properties.flagOwn = false;
    properties.published = true;
    
    client.associate("group", "<id of the public group>", "Securables", "< your securable (dataset or dashboard) id>",     properties );
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    let promise = client.associate('group', '<id of the public group>', {
        role: 'Securables',
        id: '< your securable (dataset or dashboard) id>'
    },
    {
        flagRead: true,
        flagModify: false,
        flagUse: true,
        flagOwn: false,
        published: true
    });
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    <?php
    $client->associate('group', '<id of the public group>', 'Securables', '< your securable (dataset or dashboard) id>', , 
      array (
        'flagRead' => true,
        'flagModify' => false,
        'flagUse' => true,
        'flagOwn' => false,
        'published' => true
      ) );
    ?>
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<id of the public group>",
      "resource": {
        "role": "Securables",
        "id": "< your securable (dataset or dashboard) id>"
      },
      "properties": {
        "flagRead": true,
        "flagModify": false,
        "flagUse": true,
        "flagOwn": false,
        "published": true
      }
    }
    EOF
    
       Link the Public group to a securable, and give read/use access to everyone and make sure it is listed in the public dashboards/datasets 
    client.associate("group", "<your_group_id>", {"role":"Securables","id":"< id of the public group>"}, {
        "flagRead": True,
        "flagModify": False,
        "flagUse": True,
        "flagOwn": False,
        "published": True
    } )
    
    Group
    Securable
    flagRead
    Grant the right to query the dataset
    flagUse
    Right required to use the dataset in the dashboard editor to create dashboards with it
    flagModify
    Right to modify the dataset, e.g. add a derived column
    flagOwn
    Right to delete the dataset, or to modify the access rights e.g. by associating the dataset with users (multiple users can be owner)
    published
    The dataset/dashboard will be listed in the public datasets/dashboards on Luzmo. This is a useful feature if you are providing open data for the public. To avoid mistakes, this feature is only enabled for clients that specifically ask for this.
    Associate
    requires:
    Group Owner
    and
    Securable Owner

    Groups can be used to give a group of users access to securables (dashboards or datasets). In order to do so, the group has to be associated with the securables to give access. Several flags on the association you to control the type of access. An association without providing flags will not have effect.

    Associate: User

       Link a user to a group and set him as member of that group 
    client.associate("group", "<your group id>", "Users", "< your user id>", 
      ImmutableMap.of(
        "flagMember" , true,
        "flagOwn" , false
      ));
    
       Link a user to a group and set him as member of that group 
    dynamic properties = new ExpandoObject();
    properties.flagMember = true;
    properties.flagOwn = false;
    
    client.associate("group", "<your group id>", "Users", "< your user id>",     properties );
    
       Link a user to a group and set him as member of that group 
    let promise = client.associate('group', '<your group id>', {
        role: 'Users',
        id: '< your user id>'
    },
    {
        flagMember: true,
        flagOwn: false
    });
    
       Link a user to a group and set him as member of that group 
    <?php
    $client->associate('group', '<your group id>', 'Users', '< your user id>', , 
      array (
        'flagMember' => true,
        'flagOwn' => false
      ) );
    ?>
    
       Link a user to a group and set him as member of that group 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      },
      "properties": {
        "flagMember": true,
        "flagOwn": false
      }
    }
    EOF
    
       Link a user to a group and set him as member of that group 
    client.associate("group", "<your_group_id>", {"role":"Users","id":"< your user id>"}, {
        "flagMember": True,
        "flagOwn": False
    } )
    
    User
    Group
    flagMember
    Make the user member of the group
    flagOwn
    Make the user owner of the group (there can be multiple owners)
    Associate
    requires:
    Group Owner
    and
    Logged-in User

    Groups can be used to give a group of users access to securables (dashboards or datasets). When associating a user with a group there are flags available that describe the kind of relation. Adding a user in a group without setting any flags will not have any effect. Only the owner of a group can add members to the group. The user who created the group automatically becomes an owner of the group.

    Dissociate

       Example query that removes a user from a group 
    client.dissociate("group", "<your group id>", "Users", "<user id>");
    
       Example query that removes a user from a group 
    client.dissociate("group", "<your group id>", "Users", "<user id>");
    
       Example query that removes a user from a group 
    let promise = client.dissociate('group', '<your group id>', {
        role: 'Users',
        id: '<user id>'
    });
    
       Example query that removes a user from a group 
    <?php
    $client->associate('group', '<your group id>', "Users", "<user id>");
    ?>
    
       Example query that removes a user from a group 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
      "role": "Users",
      "id": "<user id>"
    }
    }
    EOF
    
       Example query that removes a user from a group 
    client.dissociate("group", "<your_group_id>", {"role":"Users","id":"<user id>"})
    
       Example query removes access to a securable (dataset/dashboard) for a group 
    client.dissociate("group", "<your group id>", "Securables", "<securable id>");
    
       Example query removes access to a securable (dataset/dashboard) for a group 
    client.dissociate("group", "<your group id>", "Securables", "<securable id>");
    
       Example query removes access to a securable (dataset/dashboard) for a group 
    let promise = client.dissociate('group', '<your group id>', {
        role: 'Securables',
        id: '<securable id>'
    });
    
       Example query removes access to a securable (dataset/dashboard) for a group 
    <?php
    $client->associate('group', '<your group id>', "Securables", "<securable id>");
    ?>
    
       Example query removes access to a securable (dataset/dashboard) for a group 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
      "role": "Securables",
      "id": "<securable id>"
    }
    }
    EOF
    
       Example query removes access to a securable (dataset/dashboard) for a group 
    client.dissociate("group", "<your_group_id>", {"role":"Securables","id":"<securable id>"})
    

    Dissociating is similar for all resources. To break the link between two resources, simply provide the resource names and ids. Be careful that the 'role' of a resource is uppercase and usually plural. Dissociating can be done in both directions.

    HierarchyLevel

    In Luzmo all columns which deal with text values are of type hierarchy. On such a hierarchy column you can build a hierarchy out of your existing data values. To do so you first need to create hierarchy levels and associate them with a column. By associating hierarchy levels with a column we essentially define how many levels there are in the tree structure and define the metadata of these levels. Afterwards you can push hierarchy updates to the column to populate the tree structure using the hierarchy service.

    Properties

    Parameter
    Description
    id
    uuid
    Unique key of the level (automatically assigned)
    name
    string
    Name of the level
    color
    string
    The color of the level. At the moment this is not used extensively yet it will be used in the future
    level
    integer
    the level of the hierarchylevel. There should not be gaps in the levels of the hierarchylevels and there should not be doubles.

    Actions

    Create
    Get
    List
    Delete
    Update
    Associate
    Dissociate

    By default, a hierarchy column has two levels, the 'All' (not shown in editor when the hierarchy tree is disabled) level which contains the root node and the 'Values' level which contains all values.

    In the example of the hierarchy below (see screenshot) we associated two additional hierarchylevels with name Type and Taste with the column before we started pushing hierarchy updates. The final result that there are 4 levels now:

    All (root default), Type, Taste and Burrito (values default).

    In this case we used:

    All levels except the root level can be dragged on a visualization in the dashboard editor, note that you can set colors per HierarchyLevel. The tree structure will then be used to determine how the aggregations have to be done on that hierarchy level. Below is an example of an aggregation on the 'Type' hierarchy level.

    Action: Create

       Creating a hierarchy level that will sit in between the default two levels 
    JSONObject hierarchylevel = client.create("hierarchylevel",
    
      ImmutableMap.of(
        "level" , "1",
        "name" , ImmutableMap.of(
          "en" , "Name of level 1"
        ),
        "color" , "#ccc"
      ));
    System.out.println("Success! %s%n", hierarchylevel);
    
       Creating a hierarchy level that will sit in between the default two levels 
    dynamic properties = new ExpandoObject();
    properties.level = "1";
    properties.name = new {
          en = "Name of level 1"
        };
    properties.color = "#ccc";
    
    dynamic hierarchylevel = client.create("hierarchylevel",    properties);
    Console.WriteLine("Success!", hierarchylevel);
    
       Creating a hierarchy level that will sit in between the default two levels 
    client.create('hierarchylevel',
      {
        level: 1,
        name: {
            en: 'Name of level 1'
        },
        color: '#ccc'
    }
    
    )
      .then(function(hierarchylevel) {
        console.log('Success!', hierarchylevel);
      });
    
       Creating a hierarchy level that will sit in between the default two levels 
    <?php
    $hierarchylevel = $client->create('hierarchylevel',
    
      array (
        'level' => '1',
        'name' => array (
          'en' => 'Name of level 1'
        ),
        'color' => '#ccc'
      )
    
    );
    print("Success! { $hierarchylevel }");
    ?>
    
       Creating a hierarchy level that will sit in between the default two levels 
    curl https://api.luzmo.com/0.1.0/hierarchylevel  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "level": 1,
      "name": {
        "en": "Name of level 1"
      },
      "color": "#ccc"
    }
    }
    EOF
    
    
       Creating a hierarchy level that will sit in between the default two levels 
    hierarchylevel = client.create("hierarchylevel",
    {
        "level": 1,
        "name": {
          "en": "Name of level 1"
        },
        "color": "#ccc"
    })
    print("Success! ", hierarchylevel)
    
       Adding a level 1 without updating the existing level 1 (values) would be incorrect 
    JSONObject hierarchylevel = client.update("hierarchylevel", "<your hierarchylevel id>", 
      ImmutableMap.of(
        "level" , "2",
        "id" , "<id of the level to move>"
      ));
    
       Adding a level 1 without updating the existing level 1 (values) would be incorrect 
    dynamic properties = new ExpandoObject();
    properties.level = "2";
    properties.id = "<id of the level to move>";
    
    dynamic hierarchylevel = client.update("hierarchylevel", "<your hierarchylevel id>", );
    
       Adding a level 1 without updating the existing level 1 (values) would be incorrect 
    client.update('hierarchylevel',
      '<your hierarchylevel id>',
      {
        level: 2,
        id: '<id of the level to move>'
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Adding a level 1 without updating the existing level 1 (values) would be incorrect 
    <?php
    $user = $client->update('hierarchylevel', '<your hierarchylevel id>', 
      array (
        'level' => '2',
        'id' => '<id of the level to move>'
      ));
    ?>
    
       Adding a level 1 without updating the existing level 1 (values) would be incorrect 
    curl https://api.luzmo.com/0.1.0/hierarchylevel  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your hierarchylevel id>",
      "properties": {
      "level": 2,
      "id": "<id of the level to move>"
    }
    }
    EOF
    
    Create
    can be executed by:
    Logged-in User

    Any user with an API token can create a hierarchylevel. In order to use the hierarchylevel you will have to associate it to a column. Note that the level ids have to be correct and you need to take into account that there is a root level and a values level. For example, if you insert your first hierarchy level, it would have level 1 and the values level should be moved to level 2.

    Action: Update

       Example of changing the name of a level 
    JSONObject hierarchylevel = client.update("hierarchylevel", "<your hierarchylevel id>", 
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "Savory Burritos",
          "nl" , "Hartige Burritos",
          "fr" , "Burritos Relevé"
        ),
        "id" , "<id of the level>"
      ));
    
       Example of changing the name of a level 
    dynamic properties = new ExpandoObject();
    properties.name = new {
          en = "Savory Burritos",
          nl = "Hartige Burritos",
          fr = "Burritos Relevé"
        };
    properties.id = "<id of the level>";
    
    dynamic hierarchylevel = client.update("hierarchylevel", "<your hierarchylevel id>", );
    
       Example of changing the name of a level 
    client.update('hierarchylevel',
      '<your hierarchylevel id>',
      {
        name: {
            en: 'Savory Burritos',
            nl: 'Hartige Burritos',
            fr: 'Burritos Relevé'
        },
        id: '<id of the level>'
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Example of changing the name of a level 
    <?php
    $user = $client->update('hierarchylevel', '<your hierarchylevel id>', 
      array (
        'name' => array (
          'en' => 'Savory Burritos',
          'nl' => 'Hartige Burritos',
          'fr' => 'Burritos Relevé'
        ),
        'id' => '<id of the level>'
      ));
    ?>
    
       Example of changing the name of a level 
    curl https://api.luzmo.com/0.1.0/hierarchylevel  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your hierarchylevel id>",
      "properties": {
      "name": {
        "en": "Savory Burritos",
        "nl": "Hartige Burritos",
        "fr": "Burritos Relevé"
      },
      "id": "<id of the level>"
    }
    }
    EOF
    
       Example of changing the name of a level 
    hierarchylevel = client.update("hierarchylevel", "<your_hierarchylevel_id>", {
        "name": {
          "en": "Savory Burritos",
          "nl": "Hartige Burritos",
          "fr": "Burritos Relevé"
        },
        "id": "<id of the level>"
    })
    
    Update
    can be executed by:
    Securable Modifier

    Updating the hierarchylevels, if you update the 'level' make sure you update the other hierarchylevels so the level numbers follow up nicely.

    Action: Get

       get only the hierarchylevels for a specific column 
    JSONObject data = client.get("hierarchylevel", 
      ImmutableMap.of(
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "Column",
            "where" , ImmutableMap.of(
              "id" , "< your column id >"
            ),
            "jointype" , "inner"
          )
        )
      ));
    
    
       get only the hierarchylevels for a specific column 
    dynamic query = new ExpandoObject();
    query.include = new List<Object> {
    
          new {
            model = "Column",
            where = new {
              id = "< your column id >"
            },
            jointype = "inner"
          }
        };
    
    dynamic data = client.get("hierarchylevel",     query);
    
    
       get only the hierarchylevels for a specific column 
    client.get('hierarchylevel', {
        include: [
            {
                model: 'Column',
                where: {
                    id: '< your column id >'
                },
                jointype: 'inner'
            }
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       get only the hierarchylevels for a specific column 
    <?php
    $user = $client->get('hierarchylevel', 
      array (
        'include' => array (
    
          array (
            'model' => 'Column',
            'where' => array (
              'id' => '< your column id >'
            ),
            'jointype' => 'inner'
          )
        )
      ));
    
    ?>
    
       get only the hierarchylevels for a specific column 
    curl https://api.luzmo.com/0.1.0/hierarchylevel  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "include": [
        {
          "model": "Column",
          "where": {
            "id": "< your column id >"
          },
          "jointype": "inner"
        }
      ]
    }
    }
    EOF
    
    
       get only the hierarchylevels for a specific column 
    data = client.get("hierarchylevel", {
        "include": [{
          "model": "Column",
          "where": {
            "id": "< your column id >"
          },
          "jointype": "inner"
        }]
    })
    
    
       get all hierarchylevels to which you have access and add the dataset information 
    JSONObject data = client.get("hierarchylevel", 
      ImmutableMap.of(
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "Column"
          )
        )
      ));
    
    
       get all hierarchylevels to which you have access and add the dataset information 
    dynamic query = new ExpandoObject();
    query.include = new List<Object> {
    
          new {
            model = "Column"
          }
        };
    
    dynamic data = client.get("hierarchylevel",     query);
    
    
       get all hierarchylevels to which you have access and add the dataset information 
    client.get('hierarchylevel', {
        include: [
            {
                model: 'Column'
            }
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       get all hierarchylevels to which you have access and add the dataset information 
    <?php
    $user = $client->get('hierarchylevel', 
      array (
        'include' => array (
    
          array (
            'model' => 'Column'
          )
        )
      ));
    
    ?>
    
       get all hierarchylevels to which you have access and add the dataset information 
    curl https://api.luzmo.com/0.1.0/hierarchylevel  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "include": [
        {
          "model": "Column"
        }
      ]
    }
    }
    EOF
    
    
       get all hierarchylevels to which you have access and add the dataset information 
    data = client.get("hierarchylevel", {
        "include": [{
          "model": "Column"
        }]
    })
    
    
       Example of the return structure of a query of all levels when there is only one column with the 2 default hierarchylevels All & Values (Product type)
    {
      "count": 2,
      "rows": [
        {
          "id": "c25b2053-a44e-4748-8310-1a797f6d16ed",
          "level": 0,
          "name": {
            "nl": "Alle",
            "fr": "Tout",
            "en": "All"
          },
          "cardinality": 1,
          "created_at": "2018-08-30T08:05:38.381Z",
          "updated_at": "2018-08-30T08:05:38.381Z",
          "column_id": "c442c981-7bdf-4a53-929b-d39bf6256f8f",
          "color": null
        },
        {
          "id": "83a63a92-8cb3-4f87-9657-d7303c6e890a",
          "level": 1,
          "name": {
            "en": "Product type"
          },
          "cardinality": 0,
          "created_at": "2018-08-30T08:05:38.381Z",
          "updated_at": "2018-08-30T08:05:38.381Z",
          "column_id": "c442c981-7bdf-4a53-929b-d39bf6256f8f",
          "color": null
        }
      ]
    }
    
    Get
    can be executed by:
    Securable Reader
    List
    can be executed by:
    Securable Reader

    Users can only read hierarchylevels which are connected via columns to a dataset for which they have read access.

    Action: Delete

       Deleting a hierarchlevel (do not forget to update the levels of the other hierarchlevels) 
    client.delete("hierarchylevel", "<your hierarchylevel id>");
    
       Deleting a hierarchlevel (do not forget to update the levels of the other hierarchlevels) 
    $client->delete("hierarchylevel", "<your hierarchylevel id>");
    
       Deleting a hierarchlevel (do not forget to update the levels of the other hierarchlevels) 
    let promise = client.delete('hierarchylevel', '<your hierarchylevel id>');
    
       Deleting a hierarchlevel (do not forget to update the levels of the other hierarchlevels) 
    <?php
    $client->delete('hierarchylevel', '<your hierarchylevel id>');
    ?>
    
       Deleting a hierarchlevel (do not forget to update the levels of the other hierarchlevels) 
    curl https://api.luzmo.com/0.1.0/hierarchylevel  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your hierarchylevel id>"
    }
    EOF
    
       Deleting a hierarchlevel (do not forget to update the levels of the other hierarchlevels) 
    client.delete("hierarchylevel", "<your_hierarchylevel_id>")
    
    Delete
    can be executed by:
    Securable Modifier

    Delete a hierarchylevel by providing the id of the hierarchylevel. Make sure to update the levels of other hierarchies (at this point, this is not done automatically)

    Associations

    Hierarchies are always built for a specific column and are therefore only connected to columns.

    %3 <!-- Column --> Column Column <!-- HierarchyLevel --> HierarchyLevel HierarchyLevel <!-- HierarchyLevel->Column --> HierarchyLevel->Column

    Associate: Column

       Add a hierarchylevel to a column 
    client.associate("hierarchylevel", "<your hierarchylevel id>", "Column", "<column id>");
    
       Add a hierarchylevel to a column 
    
    client.associate("hierarchylevel", "<your hierarchylevel id>", "Column", "<column id>");
    
       Add a hierarchylevel to a column 
    let promise = client.associate('hierarchylevel', '<your hierarchylevel id>', {
        role: 'Column',
        id: '<column id>'
    });
    
       Add a hierarchylevel to a column 
    <?php
    $client->associate('hierarchylevel', '<your hierarchylevel id>', 'Column', '<column id>', );
    ?>
    
       Add a hierarchylevel to a column 
    curl https://api.luzmo.com/0.1.0/hierarchylevel  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your hierarchylevel id>",
      "resource": {
        "role": "Columns",
        "id": "<column id>"
      }
    }
    EOF
    
       Add a hierarchylevel to a column 
    client.associate("hierarchylevel", "<your_hierarchylevel_id>", {"role":"Columns","id":"<column id>"})
    
    Column
    HierarchyLevel

    In Luzmo all columns which deal with text values are of type hierarchy. On such a hierarchy column you can build a hierarchy out of your existing data values. To do so you first need to create hierarchy levels and associate them with a column.

    Dissociate

       Disconnect a hierarchylevel from a column 
    client.dissociate("hierarchylevel", "<your hierarchylevel id>", "Columns", "<column id>");
    
       Disconnect a hierarchylevel from a column 
    client.dissociate("hierarchylevel", "<your hierarchylevel id>", "Columns", "<column id>");
    
       Disconnect a hierarchylevel from a column 
    let promise = client.dissociate('hierarchylevel', '<your hierarchylevel id>', {
        role: 'Columns',
        id: '<column id>'
    });
    
       Disconnect a hierarchylevel from a column 
    <?php
    $client->associate('hierarchylevel', '<your hierarchylevel id>', "Columns", "<column id>");
    ?>
    
       Disconnect a hierarchylevel from a column 
    curl https://api.luzmo.com/0.1.0/hierarchylevel  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your hierarchylevel id>",
      "resource": {
      "role": "Columns",
      "id": "<column id>"
    }
    }
    EOF
    
       Disconnect a hierarchylevel from a column 
    client.dissociate("hierarchylevel", "<your_hierarchylevel_id>", {"role":"Columns","id":"<column id>"})
    

    Dissociating is similar for all resources. To break the link between two resources, simply provide the resource names and ids. Be careful that the 'role' of a resource is uppercase and usually plural. Dissociating can be done in both directions.

    Integration

    Integrations can be used to create collections of dashboards and datasets (by associating them to the Integration) and easily embed them. Each dashboard or dataset has its own access rights within this Integration.

    Next to that, dashboards associated to the Integration can be given a unique slug property to reference when embedding the dashboard using our embed libraries.

    Integrations can only be created and updated by Organization owners.

    Properties

    Parameter
    Description
    id
    string
    Unique key of the integration (automatically assigned).
    name
    localized
    Name of the integration.
    login_provider_url
    string
    If the authorization/session linked to this Integration has expired, the user will be redirected to this URL. (optional)

    Actions

    Create
    Get
    List
    Delete
    Update
    Associate
    Dissociate

    Action: Create

       Creating an Integration 
    JSONObject integration = client.create("integration",
    
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "< integration name in English ›",
          "fr" , "< integration name in French >"
        ),
        "login_provider_url": null
      ));
    
    System.out.println("Success! %s%n", integration);
    
       Creating an Integration 
    dynamic properties = new ExpandoObject();
    properties.name = new {
      en = "< integration name in English ›",
      fr = "< integration name in French >"
    };
    properties.login_provider_url = null;
    
    dynamic integration = client.create("integration", properties);
    Console.WriteLine("Success!", integration);
    
       Creating an Integration 
    client.create('integration',
      {
        name: {
            en: '< integration name in English ›',
            fr: '< integration name in French >'
        },
      login_provider_url: null
    }
    
    )
      .then(function(integration) {
        console.log('Success!', integration);
      });
    
       Creating an Integration 
    <?php
    $integration = $client->create('integration',
    
      array (
        'name' => array (
          'en' => '< integration name in English ›',
          'fr' => '< integration name in French >'
        ),
        'login_provider_url' => null
      )
    
    );
    print("Success! { $integration }");
    ?>
    
       Creating an Integration 
    curl https://api.luzmo.com/0.1.0/integration  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "name": {
          "en": "< integration name in English ›",
          "fr": "< integration name in French >"
        },
        "login_provider_url": null
      }
    }
    EOF
    
    
       Creating an Integration 
    integration = client.create("integration",
    {
        "name": {
          "en": "< integration name in English ›",
          "fr": "< integration name in French >"
        },
        "login_provider_url": null
    })
    print("Success!", integration)
    
    Create
    can be executed by:
    Organization Owner

    An Organization owner can create Integrations. Creating an Integration does not necessarily require parameters but you can provide the Integration with a name or login_provider_url.

    Action: Update

       Updating an Integration 
    JSONObject integration = client.update("integration", "<your integration id>", 
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "< new integration name in English >",
          "fr" , "< new integration name in French >"
        )
      ));
    
       Updating an Integration 
    dynamic properties = new ExpandoObject();
    properties.name = new {
      en = "< new integration name in English >",
      fr = "< new integration name in French >"
    };
    
    dynamic integration = client.update("integration", "<your integration id>", );
    
       Updating an Integration 
    client.update('integration',
      '<your integration id>',
      {
        name: {
            en: '< new integration name in English >',
            fr: '< new integration name in French >'
        }
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Updating an Integration 
    <?php
    $user = $client->update('integration', '<your integration id>', 
      array (
        'name' => array (
          'en' => '< new integration name in English >',
          'fr' => '< new integration name in French >'
        )
      ));
    ?>
    
       Updating an Integration 
    curl https://api.luzmo.com/0.1.0/integration  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your integration id>",
      "properties": {
      "name": {
        "en": "< new integration name in English >",
        "fr": "< new integration name in French >"
      }
    }
    }
    EOF
    
       Updating an Integration 
    integration = client.update("integration", "<your_integration_id>", {
        "name": {
          "en": "< new integration name in English >",
          "fr": "< new integration name in French >"
        }
    })
    
    Update
    can be executed by:
    Integration Owner

    Only the owner of the Integration can update it.

    Action: Get & List

       Getting an Integration together with the dashboards and datasets associated to it. Note: this automatically returns the IntegrationAccessRight as well.
    JSONObject data = client.get("integration", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "id" , "<your integration id>"
        ),
        "include" , ImmutableList.of(    
          ImmutableMap.of(
            "model" , "Securable",
            "attributes", ImmutableList.of("id", "name", "type")
          )
        )
      ));
    
    
       Getting an Integration together with the dashboards and datasets associated to it. Note: this automatically returns the IntegrationAccessRight as well.
    dynamic query = new ExpandoObject();
    query.where = new {
          id = "<your integration id>"
        };
    query.include = new List<Object> {     
          new {
            model = "Securable",
            attributes = new List<String> {
              "id", 
              "name",
              "type"
            }
          }
        };
    
    dynamic data = client.get("integration", query);
    
    
       Getting an Integration together with the dashboards and datasets associated to it. Note: this automatically returns the IntegrationAccessRight as well.
    client.get('integration', {
        where: {
            id: '<your integration id>'
        },
        include: [
            {
                model: 'Securable',
          attributes: ['id', 'name', 'type']
            }
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Getting an Integration together with the dashboards and datasets associated to it. Note: this automatically returns the IntegrationAccessRight as well.
    <?php
    $user = $client->get('integration', 
      array (
        'where' => array (
          'id' => '<your integration id>'
        ),
        'include' => array (
          array (
            'model' => 'Securable',
            'attributes' => array ( 'id', 'name', 'type' )
          )
        )
      ));
    
    ?>
    
       Getting an Integration together with the dashboards and datasets associated to it. Note: this automatically returns the IntegrationAccessRight as well.
    curl https://api.luzmo.com/0.1.0/integration  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "id": "<your integration id>"
      },
      "include": [
        {
          "model": "Securable",
          "attributes": ["id", "name", "type"]
        }
      ]
    }
    }
    EOF
    
    
       Getting an Integration together with the dashboards and datasets associated to it. Note: this automatically returns the IntegrationAccessRight as well.
    data = client.get("integration", {
        "where": {
          "id": "<your integration id>"
        },
        "include": [{
          "model": "Securable",
          "attributes": ["id", "name", "type"]
        }]
    })
    
    
       Example of the return structure of the query above for an Integration with one dashboard and one dataset associated to it. 
    {
      "count": 1,
      "rows": [
        {
          "id": "7d00f28c-64d6-467a-a101-2cc48f8b6f64",
          "name": {
            "en": "My demo integration"
          },
          "login_provider_url": null,
          "created_at": "2021-07-28T14:40:03.145Z",
          "updated_at": "2021-07-22T11:47:55.483Z",
          "user_id": "34b22f36-4904-497f-8acf-b0ba1d7e83cb",
          "securables": [
            {
              "id": "2fd38d4c-854b-4d79-bb75-2cf09b0b71a4",
              "name": {
                "en": "My example dataset"
              },
              "type": "dataset",
              "integrationAccessRight": {
                "flagRead": true,
                "flagUse": true,
                "flagModify": false,
                "filters": "[]",
                "slug": null,
                "created_at": "2021-07-28T14:40:03.194Z",
                "updated_at": "2021-07-28T14:40:03.194Z",
                "integration_id": "7d00f28c-64d6-467a-a101-2cc48f8b6f64",
                "securable_id": "2fd38d4c-854b-4d79-bb75-2cf09b0b71a4"
              }
            },
            {
              "id": "ac6a84a7-1019-4deb-8ed4-03a93e9565a8",
              "name": {
                "en": "My example dashboard"
              },
              "type": "dashboard",
              "integrationAccessRight": {
                "flagRead": true,
                "flagUse": true,
                "flagModify": true,
                "filters": "[]",
                "slug": "mydemoslug",
                "created_at": "2021-07-23T07:42:23.084Z",
                "updated_at": "2021-07-23T07:42:23.084Z",
                "integration_id": "7d00f28c-64d6-467a-a101-2cc48f8b6f64",
                "securable_id": "ac6a84a7-1019-4deb-8ed4-03a93e9565a8"
              }
            }
          ]
        }
      ]
    }
    
    Get
    can be executed by:
    Integration Viewer
    List
    can be executed by:
    Integration Viewer

    Integrations can be get or listed if the Integration is owned by the User, or if the User has access to the Integration via an Authorization associated to it (integration_id is set on the Authorization).

    Action: Delete

       Delete an Integration using the id 
    client.delete("integration", "<your integration id>");
    
       Delete an Integration using the id 
    $client->delete("integration", "<your integration id>");
    
       Delete an Integration using the id 
    let promise = client.delete('integration', '<your integration id>');
    
       Delete an Integration using the id 
    <?php
    $client->delete('integration', '<your integration id>');
    ?>
    
       Delete an Integration using the id 
    curl https://api.luzmo.com/0.1.0/integration  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your integration id>"
    }
    EOF
    
       Delete an Integration using the id 
    client.delete("integration", "<your_integration_id>")
    
    Delete
    can be executed by:
    Integration Owner

    Only the owner of the Integration can delete it.

    Associations

    Integrations can be associated to:

    Associate: Securables

       Link a dashboard to an Integration, giving read and use access and setting a slug. 
    client.associate("integration", "<your integration id>", "Securables", "< your securable (dashboard) id>", 
      ImmutableMap.of(
        "flagRead", true,
        "flagUse", true,
        "flagModify", false,
        "slug": "mydemoslug"
      ) );
    
       Link a dashboard to an Integration, giving read and use access and setting a slug. 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagUse = true;
    properties.flagModify = false;
    properties.slug = "mydemoslug";
    
    client.associate("integration", "<your integration id>", "Securables", "< your securable (dashboard) id>", properties );
    
       Link a dashboard to an Integration, giving read and use access and setting a slug. 
    let promise = client.associate('integration', '<your integration id>', {
        role: 'Securables',
        id: '< your securable (dashboard) id>'
    }, 
    {
      flagRead: true,
      flagUse: true,
      flagModify: false,
      slug: 'mydemoslug'
    });
    
       Link a dashboard to an Integration, giving read and use access and setting a slug. 
    <?php
    $client->associate('integration', '<your integration id>', 'Securables', '< your securable (dashboard) id>',
      array (
        'flagRead' => true,
        'flagUse' => true,
        'flagModify' => false,
        'slug' => 'mydemoslug'
      ) );
    ?>
    
       Link a dashboard to an Integration, giving read and use access and setting a slug. 
    curl https://api.luzmo.com/0.1.0/integration  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your integration id>",
      "resource": {
        "role": "Securables",
        "id": "< your securable (dashboard) id>"
      },
      "properties": {
        "flagRead": true,
        "flagUse": true,
        "flagModify": false,
        "slug": "mydemoslug"
      }
    }
    EOF
    
       Link a dashboard to an Integration, giving read and use access and setting a slug. 
    client.associate("integration", "<your_integration_id>", {"role":"Securables","id":"< your securable (dashboard) id>"}, {
        "flagRead": True,
        "flagUse": True,
        "flagModify": False,
        "slug": "mydemoslug"
    } )
    
    Integration
    Securables
    flagRead
    Grant the right to view the dashboard/dataset
    flagUse
    Right to use the dashboard/dataset (dashboard: make copies/variants; datasets: query the full dataset).
    flagModify
    Right to modify the dashboard/dataset
    filters
    Array of filters to be applied on the associated dataset. Only applicable when associating to a Securable of type 'dataset'.
    slug
    Unique alphanumeric lowercase string used to easily reference a dashboard. Only applicable when associating to a Securable of type 'dashboard'.
    Associate
    requires:
    Integration Owner

    Adding a dashboard or dataset (Securable) to an Integration can be done by associating it to the Integration.

    Associate: Users

       Link a User to an Integration. 
    client.associate("integration", "<your_integration_id>", "Users", "<user_id>");
    
       Link a User to an Integration. 
    client.associate("integration", "<your_integration_id>", "Users", "<user_id>" );
    
       Link a User to an Integration. 
    let promise = client.associate('integration', '<your_integration_id>', {
        role: 'Users',
        id: '<user_id>'
    });
    
       Link a User to an Integration. 
    <?php
    $client->associate('integration', '<your_integration_id>', 'Users', '<user_id>');
    ?>
    
       Link a User to an Integration. 
    curl https://api.luzmo.com/0.1.0/integration \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your_integration_id>",
      "resource": {
        "role": "Users",
        "id": "<user_id>"
      }
    }
    EOF
    
       Link a User to an Integration. 
    client.associate("integration", "<your_integration_id>", {"role": "Users", "id": "<user_id>"})
    
    Integration
    Users
    Associate
    requires:
    User Owner

    Sharing an Integration with a user can be done by associating the Integration with that user.

    Dissociate

       Dissociate a dashboard or dataset (Securable) from an Integration. 
    client.dissociate("integration", "<your integration id>", "Securables", "<securable id>");
    
       Dissociate a dashboard or dataset (Securable) from an Integration. 
    client.dissociate("integration", "<your integration id>", "Securables", "<securable id>");
    
       Dissociate a dashboard or dataset (Securable) from an Integration. 
    let promise = client.dissociate('integration', '<your integration id>', {
        role: 'Securables',
        id: '<securable id>'
    });
    
       Dissociate a dashboard or dataset (Securable) from an Integration. 
    <?php
    $client->associate('integration', '<your integration id>', "Securables", "<securable id>");
    ?>
    
       Dissociate a dashboard or dataset (Securable) from an Integration. 
    curl https://api.luzmo.com/0.1.0/integration  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your integration id>",
      "resource": {
        "role": "Securables",
        "id": "<securable id>"
      }
    }
    EOF
    
       Dissociate a dashboard or dataset (Securable) from an Integration. 
    client.dissociate("integration", "<your_integration_id>", {"role":"Securables","id":"<securable id>"})
    

    Dissociating is similar for all resources. To break the link between two resources, simply provide the resource names and ids. Be careful that the 'role' of a resource is uppercase and usually plural. Dissociating can be done in both directions.

    Locale

    Properties

    Parameter
    Description
    id
    string
    Unique key of the locale, this key equals the language code (en/fr/nl/..)
    description
    string
    Name of the language (locale)

    Actions

    Locale only supports retrieving and associating/dissociating since these entities are prepopulated.

    Get
    List
    Associate
    Dissociate

    Locale can be associated to entities such as Users, Organizations or Authorization tokens to set the default language for that specific entity. E.g. Associating a locale to a user will make sure that dashboards for that user are opened in a specific language. Associating a locale to an organization will set a default locale for all users in that organization.

    Action: Get

       Retrieve all locales 
    JSONObject data = client.get("locale", 
      ImmutableMap.of(
    
      ));
    
    
       Retrieve all locales 
    dynamic query = new ExpandoObject();
    
    dynamic data = client.get("locale",     query);
    
    
       Retrieve all locales 
    client.get('locale', {})
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Retrieve all locales 
    <?php
    $user = $client->get('locale', 
      array (
    
      ));
    
    ?>
    
       Retrieve all locales 
    curl https://api.luzmo.com/0.1.0/locale  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {}
    }
    EOF
    
    
       Retrieve all locales 
    data = client.get("locale", {
    
    })
    
    
       Retrieve the locale for your organization 
    JSONObject data = client.get("locale", 
      ImmutableMap.of(
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "Organization",
            "where" , ImmutableMap.of(
              "id" , "< your org id >"
            ),
            "jointype" , "inner"
          )
        )
      ));
    
    
       Retrieve the locale for your organization 
    dynamic query = new ExpandoObject();
    query.include = new List<Object> {
    
          new {
            model = "Organization",
            where = new {
              id = "< your org id >"
            },
            jointype = "inner"
          }
        };
    
    dynamic data = client.get("locale",     query);
    
    
       Retrieve the locale for your organization 
    client.get('locale', {
        include: [
            {
                model: 'Organization',
                where: {
                    id: '< your org id >'
                },
                jointype: 'inner'
            }
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Retrieve the locale for your organization 
    <?php
    $user = $client->get('locale', 
      array (
        'include' => array (
    
          array (
            'model' => 'Organization',
            'where' => array (
              'id' => '< your org id >'
            ),
            'jointype' => 'inner'
          )
        )
      ));
    
    ?>
    
       Retrieve the locale for your organization 
    curl https://api.luzmo.com/0.1.0/locale  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "include": [
        {
          "model": "Organization",
          "where": {
            "id": "< your org id >"
          },
          "jointype": "inner"
        }
      ]
    }
    }
    EOF
    
    
       Retrieve the locale for your organization 
    data = client.get("locale", {
        "include": [{
          "model": "Organization",
          "where": {
            "id": "< your org id >"
          },
          "jointype": "inner"
        }]
    })
    
    
       Example of the return structure of an authorization. 
    {
      "count": 4,
      "rows": [
        {
          "id": "nl",
          "description": "Nederlands",
          "created_at": "2014-12-14T23:00:00.000Z",
          "updated_at": "2014-12-14T23:00:00.000Z"
        },
        {
          "id": "fr",
          "description": "français",
          "created_at": "2014-12-14T23:00:00.000Z",
          "updated_at": "2014-12-14T23:00:00.000Z"
        },
        {
          "id": "en",
          "description": "English",
          "created_at": "2014-12-14T23:00:00.000Z",
          "updated_at": "2014-12-14T23:00:00.000Z"
        },
        {
          "id": "de",
          "description": "Deutsch",
          "created_at": "2014-12-14T23:00:00.000Z",
          "updated_at": "2014-12-14T23:00:00.000Z"
        }
      ]
    }
    
    Get
    can be executed by:
    Anonymous
    Logged-in User
    List
    can be executed by:
    Anonymous
    Logged-in User

    Each user can fetch locales of the platform.

    Associations

    Locale's can be associated to Users, Organizations, Shares & Authorization tokens. If a dashboard is accessed via a share or token the locale of that token/share will be used. If no locale is assigned via the token or share, the locale of the user will be used. And finally, if the user has no locale, the default locale of the organization to which the user belongs is used.

    %3 <!-- User --> User User <!-- Locale --> Locale Locale <!-- User->Locale --> User->Locale <!-- Authorization --> Authorization Authorization <!-- Locale->Authorization --> Locale->Authorization <!-- Organization --> Organization Organization <!-- Organization->Locale --> Organization->Locale <!-- Share --> Share Share <!-- Share->Locale --> Share->Locale

    Associate: Authorization

       Example of the creation of an 'authorization' resource and immediately associating it to a locale using a locale_id 
    JSONObject authorization = client.create("authorization",
    
      ImmutableMap.of(
        "type" , "temporary",
        "securables" , ImmutableList.of(
          "< dashboard id >"
        )
      ));
    System.out.println("Success! %s%n", authorization);
    
       Example of the creation of an 'authorization' resource and immediately associating it to a locale using a locale_id 
    dynamic properties = new ExpandoObject();
    properties.type = "temporary";
    properties.securables = new List<Object> {
          "< dashboard id >"
        };
    
    dynamic authorization = client.create("authorization",    properties);
    Console.WriteLine("Success!", authorization);
    
       Example of the creation of an 'authorization' resource and immediately associating it to a locale using a locale_id 
    client.create('authorization',
      {
        type: 'temporary',
        securables: [
            '< dashboard id >'
        ]
    }
    
    )
      .then(function(authorization) {
        console.log('Success!', authorization);
      });
    
       Example of the creation of an 'authorization' resource and immediately associating it to a locale using a locale_id 
    <?php
    $authorization = $client->create('authorization',
    
      array (
        'type' => 'temporary',
        'securables' => array (
          '< dashboard id >'
        )
      )
    
    );
    print("Success! { $authorization }");
    ?>
    
       Example of the creation of an 'authorization' resource and immediately associating it to a locale using a locale_id 
    curl https://api.luzmo.com/0.1.0/authorization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "type": "temporary",
      "securables": [
        "< dashboard id >"
      ]
    }
    }
    EOF
    
    
    Authorization
    Locale
    Associate
    requires:
    Authorization Owner

    Connecting a locale to an authorization is implicit. Instead of creating an association, we set the locale_id directly in the properties which will create an association for us. By connecting a locale you can determine in which locale the user will see a dashboard when the token is used for embedding, to get more information on how to embed a dashboard refer to the Integration API

    Associate: Organization

       Link an organization to a locale to set a default locale for the users 
    client.associate("organization", "<your organization id>", "Locales", "en");
    
       Link an organization to a locale to set a default locale for the users 
    
    client.associate("organization", "<your organization id>", "Locales", "en");
    
       Link an organization to a locale to set a default locale for the users 
    let promise = client.associate('organization', '<your organization id>', {
        role: 'Locales',
        id: 'en'
    });
    
       Link an organization to a locale to set a default locale for the users 
    <?php
    $client->associate('organization', '<your organization id>', 'Locales', 'en', );
    ?>
    
       Link an organization to a locale to set a default locale for the users 
    curl https://api.luzmo.com/0.1.0/organization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your organization id>",
      "resource": {
        "role": "Locales",
        "id": "en"
      }
    }
    EOF
    
       Link an organization to a locale to set a default locale for the users 
    client.associate("organization", "<your_organization_id>", {"role":"Locales","id":"en"})
    
    Organization
    Locale
    Associate
    requires:
    Organization Owner
    and
    Logged-in User

    By associating a locale with your organization you set that locale as the default for the users in your organization. When a user has an association to a locale as well it will overrule the one from the organization. When you view a dashboard, the locale of the organization and/or user is taken into account to set the language.

    Associate: Share

       Set the locale of a share. 
    client.associate("locale", "<your locale id>", "Shares", "< your share id>");
    
       Set the locale of a share. 
    
    client.associate("locale", "<your locale id>", "Shares", "< your share id>");
    
       Set the locale of a share. 
    let promise = client.associate('locale', '<your locale id>', {
        role: 'Shares',
        id: '< your share id>'
    });
    
       Set the locale of a share. 
    <?php
    $client->associate('locale', '<your locale id>', 'Shares', '< your share id>', );
    ?>
    
       Set the locale of a share. 
    curl https://api.luzmo.com/0.1.0/locale  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your locale id>",
      "resource": {
        "role": "Shares",
        "id": "< your share id>"
      }
    }
    EOF
    
       Set the locale of a share. 
    client.associate("locale", "<your_locale_id>", {"role":"Shares","id":"< your share id>"})
    
    Locale
    Share
    Associate
    requires:
    Logged-in User
    and
    Securable Owner

    A user is allowed to link a locale to a share in case the user is owner of the dashboard that is shared in the link. Associating a locale with the share will make sure that all users that open the dashboard via this link will see it in that specific locale. You can make multiple share links for a dashboard with different locales in case you need to send private links to a mixed audience.

    Associate: User

       Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. 
    client.associate("locale", "<your locale id>", "Users", "< your user id>");
    
       Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. 
    
    client.associate("locale", "<your locale id>", "Users", "< your user id>");
    
       Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. 
    let promise = client.associate('locale', '<your locale id>', {
        role: 'Users',
        id: '< your user id>'
    });
    
       Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. 
    <?php
      $client->associate('locale', '<your locale id>', 'Users', '< your user id>', );
    ?>
    
       Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. 
    curl https://api.luzmo.com/0.1.0/locale  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your locale id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      }
    }
    EOF
    
       Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. 
    client.associate("locale", "<your_locale_id>", {"role":"Users","id":"< your user id>"})
    
    User
    Locale
    Associate
    requires:
    User Owner
    and
    Logged-in User

    Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. The locale of the user needs to be changed by the entity owner. If you need to set the locale manually for each user you can use the login token when you created them to fetch an API token and set the locale for him.

    Dissociate

       Remove the default locale for an organization 
    client.dissociate("locale", "<your locale id>", "Organizations", "<your organization id>");
    
       Remove the default locale for an organization 
    client.dissociate("locale", "<your locale id>", "Organizations", "<your organization id>");
    
       Remove the default locale for an organization 
    let promise = client.dissociate('locale', '<your locale id>', {
        role: 'Organizations',
        id: '<your organization id>'
    });
    
       Remove the default locale for an organization 
    <?php
    $client->associate('locale', '<your locale id>', "Organizations", "<your organization id>");
    ?>
    
       Remove the default locale for an organization 
    curl https://api.luzmo.com/0.1.0/locale  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your locale id>",
      "resource": {
      "role": "Organizations",
      "id": "<your organization id>"
    }
    }
    EOF
    
       Remove the default locale for an organization 
    client.dissociate("locale", "<your_locale_id>", {"role":"Organizations","id":"<your organization id>"})
    
       Remove the user specific locale 
    client.dissociate("locale", "<your locale id>", "Users", "<your user id>");
    
       Remove the user specific locale 
    client.dissociate("locale", "<your locale id>", "Users", "<your user id>");
    
       Remove the user specific locale 
    let promise = client.dissociate('locale', '<your locale id>', {
        role: 'Users',
        id: '<your user id>'
    });
    
       Remove the user specific locale 
    <?php
    $client->associate('locale', '<your locale id>', "Users", "<your user id>");
    ?>
    
       Remove the user specific locale 
    curl https://api.luzmo.com/0.1.0/locale  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your locale id>",
      "resource": {
      "role": "Users",
      "id": "<your user id>"
    }
    }
    EOF
    
       Remove the user specific locale 
    client.dissociate("locale", "<your_locale_id>", {"role":"Users","id":"<your user id>"})
    

    Dissociating is similar for all resources. To break the link between two resources, simply provide the resource names and ids. Be careful that the 'role' of a resource is uppercase and usually plural. Dissociating can be done in both directions.

    Organization

    Each user belongs to precisely 1 organization (company or association). Billing plans and invoices are managed on the organization-level. Several things are restricted within an organization. For example a user can't list users from another organization and dashboards/datasets are by default not accessible to other users. However, in case it is necessary to share securables cross organization, securables can be associated directly to a user or group.

    Properties

    Parameter
    Description
    id
    uuid
    Unique key of the organization (automatically assigned)
    name
    localized
    Name of the organization.
    payment_method
    string
    Preferred payment method of the organization. Either creditcard, invoice_digital, invoice_paper. Updates to the payment method are applied starting from the next billing cycle.
    address_line_1
    string
    Address line 1
    address_line_2
    string
    Address line 2
    zipcode
    string
    ZIP code
    state
    string
    State
    city
    string
    City
    vat
    string
    VAT number (including country code). Must be a valid VAT number. Note that updates to the VAT number can impact your billing amount. The appropriate VAT percentage is applied to all charges to Belgian clients or to European clients without a valid VAT number.
    legal_name
    string
    Legal name of the organization.
    dpo_name
    string
    Name of the Data Protection Officer of the organization.
    dpo_address_line_1
    string
    Address line 1 of the Data Protection Officer of the organization.
    dpo_address_line_2
    string
    Address line 2 of the Data Protection Officer of the organization.
    dpo_email
    string
    Email address of the Data Protection Officer of the organization.
    dpo_phone
    string
    Phone number of the Data Protection Officer of the organization.
    dpa_signed_by
    string
    Name of the person who signed the Data Processing Agreement.
    dpa_signed_on
    datetime
    Date when the Data Processing Agreement was signed.
    dpa_text
    string
    Full text of the Data Processing Agreement.
    main_color
    string
    For white labeling: the main color code of the organization theme.
    accent_color
    string
    For white labeling: the secondary (accent) color code of the organization theme

    Actions

    Get
    List
    Delete
    Update
    Associate
    Dissociate

    Note that create is not directly available, an organization is made when a new user is created without an API token.

    Action: Create

       Example of the creation of a 'user' resource. If no API token is provided this will also create a new organization 
    JSONObject user = client.create("user",
    
      ImmutableMap.of(
        "email" , "example@luzmo.com",
        "password" , "your-password",
        "name" , "Sam Examplius"
      ));
    System.out.println("Success! %s%n", user);
    
       Example of the creation of a 'user' resource. If no API token is provided this will also create a new organization 
    dynamic properties = new ExpandoObject();
    properties.email = "example@luzmo.com";
    properties.password = "your-password";
    properties.name = "Sam Examplius";
    
    dynamic user = client.create("user",    properties);
    Console.WriteLine("Success!", user);
    
       Example of the creation of a 'user' resource. If no API token is provided this will also create a new organization 
    client.create('user',
      {
        email: 'example@luzmo.com',
        password: 'your-password',
        name: 'Sam Examplius'
    }
    
    )
      .then(function(user) {
        console.log('Success!', user);
      });
    
       Example of the creation of a 'user' resource. If no API token is provided this will also create a new organization 
    <?php
    $user = $client->create('user',
    
      array (
        'email' => 'example@luzmo.com',
        'password' => 'your-password',
        'name' => 'Sam Examplius'
      )
    
    );
    print("Success! { $user }");
    ?>
    
       Example of the creation of a 'user' resource. If no API token is provided this will also create a new organization 
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "email": "example@luzmo.com",
      "password": "your-password",
      "name": "Sam Examplius"
    }
    }
    EOF
    
    
       After creating a user, you can retrieve the new organization that is linked to the user 
    JSONObject data = client.get("user", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "id" , "<first user id>"
        ),
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "Organization"
          )
        )
      ));
    
    
       After creating a user, you can retrieve the new organization that is linked to the user 
    dynamic query = new ExpandoObject();
    query.where = new {
          id = "<first user id>"
        };
    query.include = new List<Object> {
    
          new {
            model = "Organization"
          }
        };
    
    dynamic data = client.get("user",     query);
    
    
       After creating a user, you can retrieve the new organization that is linked to the user 
    client.get('user', {
        where: {
            id: '<first user id>'
        },
        include: [
            {
                model: 'Organization'
            }
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       After creating a user, you can retrieve the new organization that is linked to the user 
    <?php
    $user = $client->get('user', 
      array (
        'where' => array (
          'id' => '<first user id>'
        ),
        'include' => array (
    
          array (
            'model' => 'Organization'
          )
        )
      ));
    
    ?>
    
       After creating a user, you can retrieve the new organization that is linked to the user 
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "id": "<first user id>"
      },
      "include": [
        {
          "model": "Organization"
        }
      ]
    }
    }
    EOF
    
    

    An organization can not be made explicitly. The first user that you make determines your organization. Every new user that is created via the API either creates a new organization (in case no API token was used to create the user) or is added to an existing organization by using an organization owner's API token. If you need to bootstrap an organization programmatically this means you have to:

    This mechanism can be used to create organizations for your clients or bootstrap your organization completely from code.

    Action: Update

       Update the name, address and payment method of an organization 
    JSONObject organization = client.update("organization", "<your organization id>", 
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "< organization name in English >",
          "fr" , "< organization name in French >"
        )
      ));
    
       Update the name, address and payment method of an organization 
    dynamic properties = new ExpandoObject();
    properties.name = new {
          en = "< organization name in English >",
          fr = "< organization name in French >"
        };
    
    dynamic organization = client.update("organization", "<your organization id>", );
    
       Update the name, address and payment method of an organization 
    client.update('organization',
      '<your organization id>',
      {
        name: {
            en: '< organization name in English >',
            fr: '< organization name in French >'
        }
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Update the name, address and payment method of an organization 
    <?php
    $user = $client->update('organization', '<your organization id>', 
      array (
        'name' => array (
          'en' => '< organization name in English >',
          'fr' => '< organization name in French >'
        )
      ));
    ?>
    
       Update the name, address and payment method of an organization 
    curl https://api.luzmo.com/0.1.0/organization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your organization id>",
      "properties": {
      "name": {
        "en": "< organization name in English >",
        "fr": "< organization name in French >"
      }
    }
    }
    EOF
    
       Update the name, address and payment method of an organization 
    organization = client.update("organization", "<your_organization_id>", {
        "name": {
          "en": "< organization name in English >",
          "fr": "< organization name in French >"
        }
    })
    
    Update
    can be executed by:
    Organization Owner

    Only the owner of the organization can update. The owner is the user that first created an account.

    Action: Get

       Simple query to get users of an organization and order them 
    JSONObject data = client.get("organization", 
      ImmutableMap.of(
        "attributes" , ImmutableList.of(
          "name"
        ),
        "where" , ImmutableMap.of(
          "id" , "< your organization id >"
        ),
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "User"
          )
        ),
        "order" , ImmutableList.of(
    
          ImmutableList.of(
    
            ImmutableMap.of(
              "model" , "User"
            ),
            "name",
            "asc"
          )
        )
      ));
    
    
       Simple query to get users of an organization and order them 
    dynamic query = new ExpandoObject();
    query.attributes = new List<Object> {
          "name"
        };
    query.where = new {
          id = "< your organization id >"
        };
    query.include = new List<Object> {
    
          new {
            model = "User"
          }
        };
    query.order = new List<Object> {
    
          new List<Object> {
    
            new {
              model = "User"
            },
            "name",
            "asc"
          }
        };
    
    dynamic data = client.get("organization",     query);
    
    
       Simple query to get users of an organization and order them 
    client.get('organization', {
        attributes: [
            'name'
        ],
        where: {
            id: '< your organization id >'
        },
        include: [
            {
                model: 'User'
            }
        ],
        order: [
            [
                {
                    model: 'User'
                },
                'name',
                'asc'
            ]
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Simple query to get users of an organization and order them 
    <?php
    $user = $client->get('organization', 
      array (
        'attributes' => array (
          'name'
        ),
        'where' => array (
          'id' => '< your organization id >'
        ),
        'include' => array (
    
          array (
            'model' => 'User'
          )
        ),
        'order' => array (
    
          array (
    
            array (
              'model' => 'User'
            ),
            'name',
            'asc'
          )
        )
      ));
    
    ?>
    
       Simple query to get users of an organization and order them 
    curl https://api.luzmo.com/0.1.0/organization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "attributes": [
        "name"
      ],
      "where": {
        "id": "< your organization id >"
      },
      "include": [
        {
          "model": "User"
        }
      ],
      "order": [
        [
          {
            "model": "User"
          },
          "name",
          "asc"
        ]
      ]
    }
    }
    EOF
    
    
       Simple query to get users of an organization and order them 
    data = client.get("organization", {
        "attributes": ["name"],
        "where": {
          "id": "< your organization id >"
        },
        "include": [{
          "model": "User"
        }],
        "order": [[{
          "model": "User"
        },"name","asc"]]
    })
    
    
       Example of the return structure of a query of all users within an organization, sorted on the user's name.
    {
     "count": 1,
     "rows": [
       {
          "id": "< your organization id >",
          "name": {
            "nl": "Jouw organisatie",
            "en": "Your organization",
            "fr": "Ton association"
          },
          "users": [
            {
              "email": "amy@test.com",
              "name": "Amy Evans",
              "city": null, 
              "country_id": null,
              "locale_id": "en", 
              "created_at": "2020-01-01T11:11:27.370Z",
              "flag_plan": "enterprise",
              "id": "b9c8c05a-4a76-11eb-b378-0242ac130002", 
              "organizationRole": {  
                "flagMember": true,  
                "flagEditor": true,  
                "flagOwn": false,  
                "created_at": "2020-01-01T11:11:27.649Z",
                "updated_at": "2020-09-19T15:44:32.513Z",
                "organization_id": "< your organization id >",  
                "user_id": "b9c8c05a-4a76-11eb-b378-0242ac130002"
              }
            },
            {
              "email": "david@test.com",
              "name": "David Contorence",
              "city": null, 
              "country_id": null,
              "locale_id": "en", 
              "created_at": "2020-01-01T11:11:27.370Z",
              "flag_plan": "enterprise",
              "id": "b33b2d5b-da2b-4eac-8bfd-846bd59f5b2d", 
              "organizationRole": {  
                "flagMember": true,  
                "flagEditor": true,  
                "flagOwn": false,  
                "created_at": "2020-01-08T13:34:17.461Z",
                "updated_at": "2020-11-10T09:31:17.117Z",
                "organization_id": "< your organization id >",  
                "user_id": "b33b2d5b-da2b-4eac-8bfd-846bd59f5b2d"
              }
            },
            {
              "email": "julia@test.com",
              "name": "Julia Robinson",
              "city": null, 
              "country_id": null,
              "locale_id": "en", 
              "created_at": "2020-01-01T11:11:27.370Z",
              "flag_plan": "enterprise",
              "id": "fc3801a2-cd12-4a9a-ae65-ba7e81b37a4b", 
              "organizationRole": {  
                "flagMember": true,  
                "flagEditor": true,  
                "flagOwn": false,  
                "created_at": "2019-11-10T10:14:42.355Z",
                "updated_at": "2020-05-29T08:32:25.412Z",
                "organization_id": "< your organization id >",  
                "user_id": "fc3801a2-cd12-4a9a-ae65-ba7e81b37a4b"
              }
            }   
          ]
         ]
      }
    
    Get
    can be executed by:
    Organization Member
    List
    can be executed by:
    Organization Member

    Retrieve your organization.

    Action: Delete

       Delete a group using the id 
    client.delete("organization", "<your organization id>");
    
       Delete a group using the id 
    $client->delete("organization", "<your organization id>");
    
       Delete a group using the id 
    let promise = client.delete('organization', '<your organization id>');
    
       Delete a group using the id 
    <?php
    $client->delete('organization', '<your organization id>');
    ?>
    
       Delete a group using the id 
    curl https://api.luzmo.com/0.1.0/organization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your organization id>"
    }
    EOF
    
       Delete a group using the id 
    client.delete("organization", "<your_organization_id>")
    
    Delete
    can be executed by:
    Organization Owner

    Delete an organization by providing the id of the organization.

    Associations

    Organizations their main connections are users and plugins. Besides of that you can also associate a default locale and a country to an organization and a thumbnail (logo of the organization) can be set.

    %3 <!-- User --> User User <!-- Organization --> Organization Organization <!-- User->Organization --> User->Organization <!-- Locale --> Locale Locale <!-- Country --> Country Country <!-- Organization->Locale --> Organization->Locale <!-- Organization->Country --> Organization->Country <!-- Thumbnail --> Thumbnail Thumbnail <!-- Thumbnail->Organization --> Thumbnail->Organization <!-- Plugin --> Plugin Plugin <!-- Plugin->Organization --> Plugin->Organization

    Associate: Country

       Link an organization to a country 
    client.associate("organization", "<your organization id>", "Countries", "FR");
    
       Link an organization to a country 
    
    client.associate("organization", "<your organization id>", "Countries", "FR");
    
       Link an organization to a country 
    let promise = client.associate('organization', '<your organization id>', {
        role: 'Countries',
        id: 'FR'
    });
    
       Link an organization to a country 
    <?php
    $client->associate('organization', '<your organization id>', 'Countries', 'FR', );
    ?>
    
       Link an organization to a country 
    curl https://api.luzmo.com/0.1.0/organization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your organization id>",
      "resource": {
        "role": "Countries",
        "id": "FR"
      }
    }
    EOF
    
       Link an organization to a country 
    client.associate("organization", "<your_organization_id>", {"role":"Countries","id":"FR"})
    
    Organization
    Country
    Associate
    requires:
    Organization Owner
    and
    Logged-in User

    Associating an organization with a country simply gives us the information we need about your company. The association between country and organization serves as a default for the users of your organization which can be overridden by associating a country to a user directly.

    Associate: Locale

       Link an organization to a locale to set a default locale for the users 
    client.associate("organization", "<your organization id>", "Locales", "en");
    
       Link an organization to a locale to set a default locale for the users 
    
    client.associate("organization", "<your organization id>", "Locales", "en");
    
       Link an organization to a locale to set a default locale for the users 
    let promise = client.associate('organization', '<your organization id>', {
        role: 'Locales',
        id: 'en'
    });
    
       Link an organization to a locale to set a default locale for the users 
    <?php
    $client->associate('organization', '<your organization id>', 'Locales', 'en', );
    ?>
    
       Link an organization to a locale to set a default locale for the users 
    curl https://api.luzmo.com/0.1.0/organization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your organization id>",
      "resource": {
        "role": "Locales",
        "id": "en"
      }
    }
    EOF
    
       Link an organization to a locale to set a default locale for the users 
    client.associate("organization", "<your_organization_id>", {"role":"Locales","id":"en"})
    
    Organization
    Locale
    Associate
    requires:
    Organization Owner
    and
    Logged-in User

    By associating a locale with your organization you set that locale as the default for the users in your organization. When a user has an association to a locale as well it will overrule the one from the organization. When you view a dashboard, the locale of the organization and/or user is taken into account to set the language.

    Associate: Plugin

       Link an organization to a plugin to make that plugin available to the organization 
    client.associate("organization", "<your organization id>", "Plugins", "< your plugin id>");
    
       Link an organization to a plugin to make that plugin available to the organization 
    
    client.associate("organization", "<your organization id>", "Plugins", "< your plugin id>");
    
       Link an organization to a plugin to make that plugin available to the organization 
    let promise = client.associate('organization', '<your organization id>', {
        role: 'Plugins',
        id: '< your plugin id>'
    });
    
       Link an organization to a plugin to make that plugin available to the organization 
    <?php
    $client->associate('organization', '<your organization id>', 'Plugins', '< your plugin id>', );
    ?>
    
       Link an organization to a plugin to make that plugin available to the organization 
    curl https://api.luzmo.com/0.1.0/organization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your organization id>",
      "resource": {
        "role": "Plugins",
        "id": "< your plugin id>"
      }
    }
    EOF
    
       Link an organization to a plugin to make that plugin available to the organization 
    client.associate("organization", "<your_organization_id>", {"role":"Plugins","id":"< your plugin id>"})
    
    Organization
    Plugin
    Associate
    requires:
    Organization Member
    and
    Plugin Owner

    By default, when you make a plugin via the API, the plugin is only associated to the user that created it. By associating the plugin to the organization you make it available to all users in the organization. Associating a plugin to an organization can be done by each organization member.

    Associate: Thumbnail

       Link an organization to a thumbnail to change the organizations Logo 
    client.associate("organization", "<your organization id>", "Thumbnails", "< your thumbnail id >");
    
       Link an organization to a thumbnail to change the organizations Logo 
    
    client.associate("organization", "<your organization id>", "Thumbnails", "< your thumbnail id >");
    
       Link an organization to a thumbnail to change the organizations Logo 
    let promise = client.associate('organization', '<your organization id>', {
        role: 'Thumbnails',
        id: '< your thumbnail id >'
    });
    
       Link an organization to a thumbnail to change the organizations Logo 
    <?php
    $client->associate('organization', '<your organization id>', 'Thumbnails', '< your thumbnail id >', );
    ?>
    
       Link an organization to a thumbnail to change the organizations Logo 
    curl https://api.luzmo.com/0.1.0/organization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your organization id>",
      "resource": {
        "role": "Thumbnails",
        "id": "< your thumbnail id >"
      }
    }
    EOF
    
       Link an organization to a thumbnail to change the organizations Logo 
    client.associate("organization", "<your_organization_id>", {"role":"Thumbnails","id":"< your thumbnail id >"})
    
    Organization
    Thumbnail
    Associate
    requires:
    Organization Owner

    It is possible to associate your organization to a thumbnail to change the Logo.

    Associate: User

       Example of creating a technical user. Make sure it is added to the correct organization by using the API token of an organization owner which has access to your organization's resources 
    JSONObject user = client.create("user",
    
      ImmutableMap.of(
        "name" , "New user of my organization",
        "email" , "user@organization.com",
        "password" , "... random password ..."
      ));
    System.out.println("Success! %s%n", user);
    
       Example of creating a technical user. Make sure it is added to the correct organization by using the API token of an organization owner which has access to your organization's resources 
    dynamic properties = new ExpandoObject();
    properties.name = "New user of my organization";
    properties.email = "user@organization.com";
    properties.password = "... random password ...";
    
    dynamic user = client.create("user",    properties);
    Console.WriteLine("Success!", user);
    
       Example of creating a technical user. Make sure it is added to the correct organization by using the API token of an organization owner which has access to your organization's resources 
    client.create('user',
      {
        name: 'New user of my organization',
        email: 'user@organization.com',
        password: '... random password ...'
    })
      .then(function(user) {
        console.log('Success!', user);
      });
    
       Example of creating a technical user. Make sure it is added to the correct organization by using the API token of an organization owner which has access to your organization's resources 
    <?php
    $user = $client->create('user',
    
      array (
        'name' => 'New user of my organization',
        'email' => 'user@organization.com',
        'password' => '... random password ...'
      )
    );
    print("Success! { $user }");
    ?>
    
       Example of creating a technical user. Make sure it is added to the correct organization by using the API token of an organization owner which has access to your organization's resources 
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "name": "New user of my organization",
        "email": "user@organization.com",
        "password": "... random password ..."
      }
    }
    EOF
    
    
       Example of the creation of a 'user' resource. If no invite code is provided this will also create a new organization 
    user = client.create("user",
    {
        "email": "example@luzmo.com",
        "password": "your-password",
        "name": "Sam Examplius"
    })
    print("Success! ", user)
    
    User
    Organization
    flagMember
    Grant the right to view accessible dashboards
    flagEditor
    Right to create or edit dashboards
    flagAdmin
    Right to view, edit, share, and delete all securables within the organization and suborganization(s).
    flagOwn
    Right to manage the organization (e.g. add/update org members, plan & billing info, etc.), create Integrations, save Organization themes, etc.
      Example of changing the user role to role 'admin' (Only organization owners can create or update users)
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "version": "0.1.0",
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN"
      "id": "< user id >",
      "resource": {
        "role": "Organizations",
        "id": "< organization id >"
      },
      "properties": {
        "flagMember": true,
        "flagEditor": true,
        "flagAdmin": true,
        "flagOwn": false
      }
    }
    EOF
    
    
      Example of changing the user role, Only organization owner can update the user role
    client.associate(
        'user',
        <user id to update>,
        { role: 'Organizations', id: <your organzation id> },
        { flagAdmin: true, flagEditor: true, flagMember: true, flagOwn: false }
      )
    .then(function(user) {
      console.log('Success!', user);
    });
    
      Example of changing the user role, Only organization owner can update the user role 
    client.associate("user", "<user id to update>", "Organizations", "< your organization id>", 
      ImmutableMap.of(
        "flagMember" , true,
        "flagEditor" , true,
        "flagAdmin" , true,
        "flagOwn" , false
      ));
    
      Example of changing the user role, Only organization owner can update the user role 
    dynamic properties = new ExpandoObject();
    properties.flagMember = true;
    properties.flagOwn = false;
    properties.flagAdmin = true;
    properties.flagAEditor = true;
    
    client.associate("user", "<your user id>", "Organizations", "< your organization id>",     properties );
    
      Example of changing the user role, Only organization owner can update the user role 
    <?php
    $client->associate('user', '<your user id>', 'Organizations', '< your organization id>', , 
      array (
        'flagMember' => true,
        'flagEditor' => true,
        'flagAdmin' => true,
        'flagOwn' => false
      ) );
    ?>
    
      Example of changing the user role, Only organization owner can update the user role  
    client.associate("user", "<your_user_id>", {"role":"Organizations","id":"< your organization id>"}, {
        "flagMember": True,
        "flagEditor": True,
        "flagAdmin": True,
        "flagOwn": False
    } )
    

    The link between Organizations and Users is a special case: you can't add users to an organization once the users are made. If you use an owner's API token to create a user, the association between the organization and user will be made implicitly (i.e. the only way to add users to an organization is on creation time). If no API token is provided, the user will be added to a new organization.

    To change the role of an existing user in your main organization, you need to use the API key-token pair from an organization owner, and set the desired flag(s) to true on the user-organization association.

    Dissociate

       Example that removes a user from an organization 
    client.dissociate("organization", "<your organization id>", "Users", "<user id>");
    
       Example that removes a user from an organization 
    client.dissociate("organization", "<your organization id>", "Users", "<user id>");
    
       Example that removes a user from an organization 
    let promise = client.dissociate('organization', '<your organization id>', {
        role: 'Users',
        id: '<user id>'
    });
    
       Example that removes a user from an organization 
    <?php
    $client->associate('organization', '<your organization id>', "Users", "<user id>");
    ?>
    
       Example that removes a user from an organization 
    curl https://api.luzmo.com/0.1.0/organization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your organization id>",
      "resource": {
      "role": "Users",
      "id": "<user id>"
    }
    }
    EOF
    
       Example that removes a user from an organization 
    client.dissociate("organization", "<your_organization_id>", {"role":"Users","id":"<user id>"})
    
       Example that removes a plugin from an organization 
    client.dissociate("organization", "<your organization id>", "Plugins", "<plugin id>");
    
       Example that removes a plugin from an organization 
    client.dissociate("organization", "<your organization id>", "Plugins", "<plugin id>");
    
       Example that removes a plugin from an organization 
    let promise = client.dissociate('organization', '<your organization id>', {
        role: 'Plugins',
        id: '<plugin id>'
    });
    
       Example that removes a plugin from an organization 
    <?php
    $client->associate('organization', '<your organization id>', "Plugins", "<plugin id>");
    ?>
    
       Example that removes a plugin from an organization 
    curl https://api.luzmo.com/0.1.0/organization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your organization id>",
      "resource": {
      "role": "Plugins",
      "id": "<plugin id>"
    }
    }
    EOF
    
       Example that removes a plugin from an organization 
    client.dissociate("organization", "<your_organization_id>", {"role":"Plugins","id":"<plugin id>"})
    

    Dissociating is similar for all resources. To break the link between two resources, simply provide the resource names and ids. Be careful that the 'role' of a resource is uppercase and usually plural. Dissociating can be done in both directions.

    Plugin

    Plugins are flexible data connectors to connect data stores, APIs or open datasets to Luzmo.

    If your database or service is not yet available via a build-in connector, or if you already have an API for your company data and want to reuse it, building a plugin is the way to go!

    This API endpoint therefore allows you to preconfigure certain plugins for your organization and users, fetch information about existing plugins or update existing plugins.

    Properties

    Parameter
    Description
    id
    uuid
    Unique key of the Plugin (automatically assigned)
    slug
    string
    Unique slug (textual identifier) of your Plugin. A slug must be unique across Luzmo, between 1 and 50 (inclusive) characters long and can only contain alphanumeric characters. There are several reserved slugs, including athena, cassandra, googleanalytics, googledrive, local, mailchimp, mariadb, mysql, pipelinedb, postgresql, quandl, redshift, rdbms, salesforce, sqlserver, stripe, teamleader and zendesk. When creating datasets via a plugin (e.g. via dataprovider) this slug is used to identify it.
    name
    localized
    Name of your Plugin, as shown in the Luzmo UI
    description
    localized
    Description of your Plugin, as shown in the Luzmo UI
    base_url
    string
    Base URL of your Plugin that is used to construct /datasets, /query, ... endpoints. This URL must be reachable by Luzmo (publicly routable) -- endpoints like localhost, 192.186.0.0 or 10.0.0.0 will be rejected. To safeguard our customers, your Plugin must be called over HTTPS. A base URL can be at most 1000 characters long.
    url
    string
    URL where more information about your product or Plugin can be found, as shown in the Luzmo UI.
    license
    string
    License under which end-users can use, re-use, modify or publish data exposed via your Plugin.
    secret
    string
    Plugin secret that can be verified by a Plugin to check whether calls originate from Luzmo, or vice-versa. (automatically assigned)
    authorize
    string
    Determines which properties can be set by a user when connecting to your Plugin. Can be either:
    • none: don't use plugin properties. Use this for open data sources, or when you want to handle authentication/authorization fully on your Plugins side, eg. based on the 'user context', metadata or 'authorization overrides'.
    • oauth2: offer a single-click connect to your plugin. In this case, you must implement an /authorize and /exchange endpoint.
    • custom: use a specific set of properties (eg. key, token, host, ...). The properties are defined in properties.
    properties
    array[object]
    List of properties that can be set by a user when creating a plugin Account.
    id
    string
    Unique identifier of the property. This identifier is used to set the properties when creating a plugin Account, and will be sent along in X-Property-<id> headers (or in the body of the /authorize requests). This identifier can only contain alphanumeric characters or the following special characters: - and _.
    name
    localized
    Localized name of the property, as shown in the interface.
    sensitive
    boolean
    Whether this property might contain sensitive data, like passwords or tokens. This will cause the properties to be masked in logs and input fields.
    tiles
    boolean
    Whether to show a tile-based layout (= true) or a list-based layout (false). For a dynamic (personalized per user) or large set of datasets, a list-based layout is advised. Defaults to false.
    search
    boolean
    Whether to show a search box to limit the dataset selection. For a dynamic (personalized per user) or large set of datasets, search functionality is advised. Defaults to false.
    public
    boolean
    Whether to make this plugin available to all Luzmo users (pending review by the Luzmo team). Defaults to false.
    reviewed
    boolean
    (Read-only) Whether this Plugin has been reviewed positively by the Luzmo team on security, branding and usability characteristics.
    color
    rgb
    Key hexadecimal or RGB color value of this Plugin, as applied to the Luzmo UI.
    protocol_version
    string
    The version of the Plugin API specification to which this Plugin conforms. Valid values: 1.0.0, 1.1.0 or 2.0.0 (default).
    pushdown
    boolean
    Whether your Plugin supports pushdown behaviour. Setting this to true entails specific support in the handling of /query calls, as described in detail in 2. Pushdown-enabled Plugin. Defaults to false.

    Actions

    Get
    List
    Delete
    Update
    Associate
    Dissociate

    Action: Create

       This will create a plugin with custom authentication properties api_key and api_token.
    A user who would like to connect to this plugin to import their own datasets will be required to fill in these custom properties, the plugin can validate these properties in each request.
    JSONObject plugin = client.create("plugin",
      ImmutableMap.of(
        "slug" , "myplugin",
        "name" , ImmutableMap.of(
          "en" , "My Internal Api Plugin"
        ),
        "description" , ImmutableMap.of(
          "en" , "Since we already have an API, we wrote a simple plugin around our API"
        ),
        "base_url" , "https://my-company.com/data/api/v1",
        "url" , "https://my-company.com/info",
        "color" , "#00FF00",
        "pushdown" , false,
        "authorize" , "custom",
        "properties", ImmutableList.of(
          ImmutableMap.of(
            "id", "api_key",
            "name", ImmutableMap.of(
              "en", "API key"
            ),
            "sensitive", false
          ),
          ImmutableMap.of(
            "id", "api_token",
            "name", ImmutableMap.of(
              "en", "API token"
            ),
            "sensitive", true
          )
        )
      ));
    System.out.printf("Plugin id: %s%n", plugin.get("id"));
    
       This will create a plugin with custom authentication properties api_key and api_token.
    A user who would like to connect to this plugin to import their own datasets will be required to fill in these custom properties, the plugin can validate these properties in each request.
    dynamic properties = new ExpandoObject();
    properties.slug = "myplugin";
    properties.name = new {
          en = "My Internal Api Plugin"
        };
    properties.description = new {
          en = "Since we already have an API, we wrote a simple plugin around our API"
        };
    properties.base_url = "https://my-company.com/data/api/v1";
    properties.url = "https://my-company.com/info";
    properties.color = "#00FF00";
    properties.pushdown = false;
    properties.authorize = "custom";
    properties.properties = new List<Object> {
      new {
        "id" = "api_key",
        "name" = new {
          "en" = "API key"
        },
        "sensitive" = false
      },
      new {
        "id" = "api_token",
        "name" = new {
          "en" = "API token"
        },
        "sensitive" = true
      }
    };
    dynamic plugin = client.create("plugin",    properties);
    
     Console.WriteLine("Plugin id is {0}", plugin["id"]);
    
       This will create a plugin with custom authentication properties api_key and api_token.
    A user who would like to connect to this plugin to import their own datasets will be required to fill in these custom properties, the plugin can validate these properties in each request.
    client.create('plugin',
      {
        slug: 'myplugin',
        name: {
            en: 'My Internal Api Plugin'
        },
        description: {
            en: 'Since we already have an API, we wrote a simple plugin around our API'
        },
        base_url: 'https://my-company.com/data/api/v1',
        url: 'https://my-company.com/info',
        color: '#00FF00',
        pushdown: false,
      authorize: 'custom',
      properties: [
        {
          id: 'api_key',
          name: {
            en: 'API key'
          },
          sensitive: false
        },
        {
          id: 'api_token',
          name: {
            en: 'API token'
          },
          sensitive: true
        }
      ]
    }
    
    )
      .then(function(plugin) {
        var pluginId = plugin.id;
      });
    
       This will create a plugin with custom authentication properties api_key and api_token.
    A user who would like to connect to this plugin to import their own datasets will be required to fill in these custom properties, the plugin can validate these properties in each request.
    <?php
    $plugin = $client->create('plugin',
    
      array (
        'slug' => 'myplugin',
        'name' => array (
          'en' => 'My Internal Api Plugin'
        ),
        'description' => array (
          'en' => 'Since we already have an API, we wrote a simple plugin around our API'
        ),
        'base_url' => 'https://my-company.com/data/api/v1',
        'url' => 'https://my-company.com/info',
        'color' => '#00FF00',
        'pushdown' => false,
        'authorize' => 'custom',
        'properties' => array (
          array (
            'id' => 'api_key',
            'name' => {
              'en' => 'API key'
            },
            'sensitive' => false
          ),
          array (
            'id' => 'api_token',
            'name' => {
              'en' => 'API token'
            },
            'sensitive' => true
          )
        )
      )
    
    );
    print( $plugin['id'] );
    ?>
    
       This will create a plugin with custom authentication properties api_key and api_token.
    A user who would like to connect to this plugin to import their own datasets will be required to fill in these custom properties, the plugin can validate these properties in each request.
    curl https://api.luzmo.com/0.1.0/plugin  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "slug": "myplugin",
      "name": {
        "en": "My Internal Api Plugin"
      },
      "description": {
        "en": "Since we already have an API, we wrote a simple plugin around our API"
      },
      "base_url": "https://my-company.com/data/api/v1",
      "url": "https://my-company.com/info",
      "color": "#00FF00",
      "pushdown": false,
      "authorize": "custom",
      "properties": [
        {
          "id": "api_key",
          "name": {
            "en": "API key"
          },
          "sensitive": false
        },
        {
          "id": "api_token",
          "name": {
            "en": "API token"
          },
          "sensitive": true
        }
      ]
    }
    }
    EOF
    # result format of the plugin contains its id
    {
     ...
     "id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
       This will create a plugin with custom authentication properties api_key and api_token.
    A user who would like to connect to this plugin to import their own datasets will be required to fill in these custom properties, the plugin can validate these properties in each request.
    plugin = client.create("plugin",
    {
      "slug": "myplugin",
      "name": {
        "en": "My Internal Api Plugin"
      },
      "description": {
        "en": "Since we already have an API, we wrote a simple plugin around our API"
      },
      "base_url": "https://my-company.com/data/api/v1",
      "url": "https://my-company.com/info",
      "color": "#00FF00",
      "pushdown": False,
      "authorize": "custom",
      "properties": [
        {
          "id": "api_key",
          "name": {
            "en": "API key"
          },
          "sensitive": false
        },
        {
          "id": "api_token",
          "name": {
            "en": "API token"
          },
          "sensitive": true
        }
      ]
    })
    plugin_id = plugin["id"]
    
    Create
    can be executed by:
    Logged-in User

    When you build a plugin (Plugin API), you essentially host an API with authentication and several standard endpoints. The create action in the Core API registers the plugin in the platform for a specific user. You can then later associate it to an organization in order to make it available for the organization.

    The effect will be that users of your organization will see this plugin when they add new data.

    Action: Update

       Update the name of the plugin 
    JSONObject plugin = client.update("plugin", "<your plugin id>", 
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "< plugin name in English >",
          "fr" , "< plugin name in French >"
        )
      ));
    
       Update the name of the plugin 
    dynamic properties = new ExpandoObject();
    properties.name = new {
          en = "< plugin name in English >",
          fr = "< plugin name in French >"
        };
    
    dynamic plugin = client.update("plugin", "<your plugin id>", );
    
       Update the name of the plugin 
    client.update('plugin',
      '<your plugin id>',
      {
        name: {
            en: '< plugin name in English >',
            fr: '< plugin name in French >'
        }
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Update the name of the plugin 
    <?php
    $user = $client->update('plugin', '<your plugin id>', 
      array (
        'name' => array (
          'en' => '< plugin name in English >',
          'fr' => '< plugin name in French >'
        )
      ));
    ?>
    
       Update the name of the plugin 
    curl https://api.luzmo.com/0.1.0/plugin  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your plugin id>",
      "properties": {
      "name": {
        "en": "< plugin name in English >",
        "fr": "< plugin name in French >"
      }
    }
    }
    EOF
    
       Update the name of the plugin 
    plugin = client.update("plugin", "<your_plugin_id>", {
        "name": {
          "en": "< plugin name in English >",
          "fr": "< plugin name in French >"
        }
    })
    
    Update
    can be executed by:
    Plugin Owner

    Plugins can be updated by the owner of the plugin. The owner is the user who created the plugin.

    Action: Get

       Retrieve all plugins in your organization 
    JSONObject data = client.get("plugin", 
      ImmutableMap.of(
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "Organization",
            "where" , ImmutableMap.of(
              "id" , "< your organization id >"
            ),
            "jointype" , "inner"
          )
        )
      ));
    
    
       Retrieve all plugins in your organization 
    dynamic query = new ExpandoObject();
    query.include = new List<Object> {
    
          new {
            model = "Organization",
            where = new {
              id = "< your organization id >"
            },
            jointype = "inner"
          }
        };
    
    dynamic data = client.get("plugin",     query);
    
    
       Retrieve all plugins in your organization 
    client.get('plugin', {
        include: [
            {
                model: 'Organization',
                where: {
                    id: '< your organization id >'
                },
                jointype: 'inner'
            }
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Retrieve all plugins in your organization 
    <?php
    $user = $client->get('plugin', 
      array (
        'include' => array (
    
          array (
            'model' => 'Organization',
            'where' => array (
              'id' => '< your organization id >'
            ),
            'jointype' => 'inner'
          )
        )
      ));
    
    ?>
    
       Retrieve all plugins in your organization 
    curl https://api.luzmo.com/0.1.0/plugin  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "include": [
        {
          "model": "Organization",
          "where": {
            "id": "< your organization id >"
          },
          "jointype": "inner"
        }
      ]
    }
    }
    EOF
    
    
       Retrieve all plugins in your organization 
    data = client.get("plugin", {
        "include": [{
          "model": "Organization",
          "where": {
            "id": "< your organization id >"
          },
          "jointype": "inner"
        }]
    })
    
    
       Example of the return structure of a query of all plugins from your organization
    {
      "count": 1,
      "rows": [
        {
          "id": "6b297528-91e5-4655-99a3-fe200f91b64b",
          "slug": "myplugin9974880",
          "name": {
            "en": "My Internal Api Plugin"
          },
          "description": {
            "en": "Since we already have an API, we wrote a simple plugin around our API"
          },
          "url": "https://url-to-some-product-info.com",
          "license": "Create Commons 0",
          "base_url": "https://8017349d.ngrok.io",
          "authorize": "token",
          "tiles": true,
          "search": false,
          "public": false,
          "reviewed": false,
          "color": "#00FF00",
          "organization": {
            "id": "55df2cc9-64a8-4a85-8c82-938909ef0b6e",
            "name": {
              "nl": "Jouw organisatie",
              "en": "Your organization",
              "fr": "Ton association"
            },
            "payment_method": "creditcard",
            "address_line_1": null,
            "address_line_2": null,
            "zipcode": null,
            "state": null,
            "city": null,
            "vat": null,
            "legal_name": null,
            "dpo_name": null,
            "dpo_address_line_1": null,
            "dpo_address_line_2": null,
            "dpo_email": null,
            "dpo_phone": null,
            "dpa_signed_by": null,
            "dpa_signed_on": null,
            "dpa_text": null,
            "flag_allow_viewers": true,
            "flag_publish": false,
            "flag_whitelabeling": false,
            "main_color": null,
            "accent_color": null,
            "from_email": null,
            "subdomain": null,
            "created_at": "2018-08-31T11:14:02.854Z",
            "updated_at": "2018-08-31T11:14:02.854Z",
            "country_id": null,
            "theme_id": null,
            "locale_id": null
          }
        }
      ]
    }
    
    
    Get
    can be executed by:
    Plugin Owner
    Plugin Reader
    List
    can be executed by:
    Plugin Reader

    Action: Delete

       Delete a plugin 
    client.delete("plugin", "<your plugin id>");
    
       Delete a plugin 
    $client->delete("plugin", "<your plugin id>");
    
       Delete a plugin 
    let promise = client.delete('plugin', '<your plugin id>');
    
       Delete a plugin 
    <?php
    $client->delete('plugin', '<your plugin id>');
    ?>
    
       Delete a plugin 
    curl https://api.luzmo.com/0.1.0/plugin  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your plugin id>"
    }
    EOF
    
       Delete a plugin 
    client.delete("plugin", "<your_plugin_id>")
    
    Delete
    can be executed by:
    Plugin Owner

    Delete a plugin by providing the id of the plugin.

    Associations

    A plugin is automatically associated to the creating user, this association cannot be done manually. As member or owner of the Organization, you can associate the plugin with the Organization to make it available for every member. You can also associate a thumbnail to the Plugin to change its icon.

    %3 <!-- Removed the Securable, Dashboard & Dataset association --> <!-- User --> User User <!-- Plugin --> Plugin Plugin <!-- User->Plugin --> User->Plugin <!-- Organization --> Organization Organization <!-- Thumbnail --> Thumbnail Thumbnail <!-- Thumbnail->Plugin --> Thumbnail->Plugin <!-- Plugin->Organization --> Plugin->Organization

    Associate: Organization

       Link an organization to a plugin to make that plugin available to the organization 
    client.associate("organization", "<your organization id>", "Plugins", "< your plugin id>");
    
       Link an organization to a plugin to make that plugin available to the organization 
    
    client.associate("organization", "<your organization id>", "Plugins", "< your plugin id>");
    
       Link an organization to a plugin to make that plugin available to the organization 
    let promise = client.associate('organization', '<your organization id>', {
        role: 'Plugins',
        id: '< your plugin id>'
    });
    
       Link an organization to a plugin to make that plugin available to the organization 
    <?php
    $client->associate('organization', '<your organization id>', 'Plugins', '< your plugin id>', );
    ?>
    
       Link an organization to a plugin to make that plugin available to the organization 
    curl https://api.luzmo.com/0.1.0/organization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your organization id>",
      "resource": {
        "role": "Plugins",
        "id": "< your plugin id>"
      }
    }
    EOF
    
       Link an organization to a plugin to make that plugin available to the organization 
    client.associate("organization", "<your_organization_id>", {"role":"Plugins","id":"< your plugin id>"})
    
    Organization
    Plugin
    Associate
    requires:
    Organization Member
    and
    Plugin Owner

    By default, when you make a plugin via the API, the plugin is only associated to the user that created it. By associating the plugin to the organization you make it available to all users in the organization. Associating a plugin to an organization can be done by each organization member.

    Associate: Thumbnail

       Link your plugin to a thumbnail to change the icon 
    client.associate("plugin", "<your plugin id>", "Thumbnails", "< your thumbnail id >");
    
       Link your plugin to a thumbnail to change the icon 
    
    client.associate("plugin", "<your plugin id>", "Thumbnails", "< your thumbnail id >");
    
       Link your plugin to a thumbnail to change the icon 
    let promise = client.associate('plugin', '<your plugin id>', {
        role: 'Thumbnails',
        id: '< your thumbnail id >'
    });
    
       Link your plugin to a thumbnail to change the icon 
    <?php
    $client->associate('plugin', '<your plugin id>', 'Thumbnails', '< your thumbnail id >', );
    ?>
    
       Link your plugin to a thumbnail to change the icon 
    curl https://api.luzmo.com/0.1.0/plugin  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your plugin id>",
      "resource": {
        "role": "Thumbnails",
        "id": "< your thumbnail id >"
      }
    }
    EOF
    
       Link your plugin to a thumbnail to change the icon 
    client.associate("plugin", "<your_plugin_id>", {"role":"Thumbnails","id":"< your thumbnail id >"})
    
    Plugin
    Thumbnail
    Associate
    requires:
    Plugin Owner

    It is possible to associate your plugin to a thumbnail to change the icon.

    Associate: User

       A plugin is automatically bound to the creating user on creation, that user is the Entity Owner and is the only one who can change the plugin 
    JSONObject plugin = client.create("plugin",
    
      ImmutableMap.of(
        "slug" , "myplugin",
        "name" , ImmutableMap.of(
          "en" , "My Internal Api Plugin"
        ),
        "description" , ImmutableMap.of(
          "en" , "Since we already have an API, we wrote a simple plugin around our API"
        ),
        "base_url" , "https://my-company.com/data/api/v1",
        "url" , "https://my-company.com/info",
        "secret" , "<luzmo-secret>",
        "authorize" , "token",
        "color" , "#00FF00",
        "pushdown" , false
      ));
    System.out.printf("User id: %s%n", plugin.get("user_id"));
    
       A plugin is automatically bound to the creating user on creation, that user is the Entity Owner and is the only one who can change the plugin 
    dynamic properties = new ExpandoObject();
    properties.slug = "myplugin";
    properties.name = new {
          en = "My Internal Api Plugin"
        };
    properties.description = new {
          en = "Since we already have an API, we wrote a simple plugin around our API"
        };
    properties.base_url = "https://my-company.com/data/api/v1";
    properties.url = "https://my-company.com/info";
    properties.secret = "<luzmo-secret>";
    properties.authorize = "token";
    properties.color = "#00FF00";
    properties.pushdown = false;
    
    dynamic plugin = client.create("plugin",    properties);
    
     Console.WriteLine("User id is {0}", plugin["user_id"]);
    
       A plugin is automatically bound to the creating user on creation, that user is the Entity Owner and is the only one who can change the plugin 
    client.create('plugin', {
      slug: 'myplugin',
      name: {
        en: 'My Internal Api Plugin'
      },
      description: {
        en: 'Since we already have an API, we wrote a simple plugin around our API'
      },
      base_url: 'https://my-company.com/data/api/v1',
      url: 'https://my-company.com/info',
      secret: '<luzmo-secret>',
      authorize: 'token',
      color: '#00FF00',
      pushdown: false
    })
      .then(function(plugin) {
        var user = plugin.user_id;
      });
    
       A plugin is automatically bound to the creating user on creation, that user is the Entity Owner and is the only one who can change the plugin 
    <?php
    $plugin = $client->create('plugin',
    
      array (
        'slug' => 'myplugin',
        'name' => array (
          'en' => 'My Internal Api Plugin'
        ),
        'description' => array (
          'en' => 'Since we already have an API, we wrote a simple plugin around our API'
        ),
        'base_url' => 'https://my-company.com/data/api/v1',
        'url' => 'https://my-company.com/info',
        'secret' => '<luzmo-secret>',
        'authorize' => 'token',
        'color' => '#00FF00',
        'pushdown' => false
      )
    
    );
    print( $plugin['user_id'] );
    ?>
    
       A plugin is automatically bound to the creating user on creation, that user is the Entity Owner and is the only one who can change the plugin 
    curl https://api.luzmo.com/0.1.0/plugin  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "slug": "myplugin",
        "name": {
          "en": "My Internal Api Plugin"
        },
        "description": {
          "en": "Since we already have an API, we wrote a simple plugin around our API"
        },
        "base_url": "https://my-company.com/data/api/v1",
        "url": "https://my-company.com/info",
        "secret": "<luzmo-secret>",
        "authorize": "token",
        "color": "#00FF00",
        "pushdown": false
      }
    }
    EOF
    # result format of the plugin contains the user_id 
    {
     ... 
     "user_id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
       A plugin is automatically bound to the creating user on creation, that user is the Entity Owner and is the only one who can change the plugin 
    plugin = client.create("plugin",
    {
        "slug": "myplugin",
        "name": {
          "en": "My Internal Api Plugin"
        },
        "description": {
          "en": "Since we already have an API, we wrote a simple plugin around our API"
        },
        "base_url": "https://my-company.com/data/api/v1",
        "url": "https://my-company.com/info",
        "secret": "<luzmo-secret>",
        "authorize": "token",
        "color": "#00FF00",
        "pushdown": False
    })
    user = plugin["user_id"]
    
    User
    Plugin

    This is a special case similar to many entities that are linked to user. The association to the creating user is automatically added when a plugin is created, this association cannot be created manually. The user that created the schedule is the owner of the Plugin and the only one who can manipulate the plugin.

    Dissociate

       Dissociate the plugin from the organization (making it unavailable for your organization members) 
    client.dissociate("plugin", "<your plugin id>", "Organizations", "< your organization id >");
    
       Dissociate the plugin from the organization (making it unavailable for your organization members) 
    client.dissociate("plugin", "<your plugin id>", "Organizations", "< your organization id >");
    
       Dissociate the plugin from the organization (making it unavailable for your organization members) 
    let promise = client.dissociate('plugin', '<your plugin id>', {
        role: 'Organizations',
        id: '< your organization id >'
    });
    
       Dissociate the plugin from the organization (making it unavailable for your organization members) 
    <?php
    $client->associate('plugin', '<your plugin id>', "Organizations", "< your organization id >");
    ?>
    
       Dissociate the plugin from the organization (making it unavailable for your organization members) 
    curl https://api.luzmo.com/0.1.0/plugin  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your plugin id>",
      "resource": {
      "role": "Organizations",
      "id": "< your organization id >"
    }
    }
    EOF
    
       Dissociate the plugin from the organization (making it unavailable for your organization members) 
    client.dissociate("plugin", "<your_plugin_id>", {"role":"Organizations","id":"< your organization id >"})
    
       Remove the logo from a plugin 
    client.dissociate("plugin", "<your plugin id>", "Thumbnails", "< your thumbnail id >");
    
       Remove the logo from a plugin 
    client.dissociate("plugin", "<your plugin id>", "Thumbnails", "< your thumbnail id >");
    
       Remove the logo from a plugin 
    let promise = client.dissociate('plugin', '<your plugin id>', {
        role: 'Thumbnails',
        id: '< your thumbnail id >'
    });
    
       Remove the logo from a plugin 
    <?php
    $client->associate('plugin', '<your plugin id>', "Thumbnails", "< your thumbnail id >");
    ?>
    
       Remove the logo from a plugin 
    curl https://api.luzmo.com/0.1.0/plugin  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your plugin id>",
      "resource": {
      "role": "Thumbnails",
      "id": "< your thumbnail id >"
    }
    }
    EOF
    
       Remove the logo from a plugin 
    client.dissociate("plugin", "<your_plugin_id>", {"role":"Thumbnails","id":"< your thumbnail id >"})
    

    Dissociating is similar for all resources. To break the link between two resources, simply provide the resource names and ids. Be careful that the 'role' of a resource is uppercase and usually plural. Dissociating can be done in both directions.

    Schedule

    A schedule is an automated synchronization or screenshot task. This way you can automatically send screenshots with a certain frequency or specify how frequently a dataset has to be synchronized. Schedules can be created, updated and deleted by all users or group members with at least modifying rights to the securable.

    Properties

    Parameter
    Description
    id
    uuid
    Unique key of the Schedule (automatically assigned)
    type
    string
    Type of schedule. Can be either dataset or screenshot.
    started_at
    datetime
    Initial start date of the synchronization. This is the reference for further scheduling, e.g. if you asked for a weekly frequency then the start date determines the day of the week and the hour
    frequency
    integer
    The frequency of update, in minutes. Minimum: 15, maximum: 525600. Defaults to 60 minutes.
    retries
    integer
    (Read-only) The number of retries since the last successful sync, in case the synchronization is currently failing.
    active
    boolean
    Whether the synchronization is currently enabled. Can be used to temporarily disable the synchronization without removing it.
    completed_at
    datetime
    (Read-only) Date/time of the most recent successful synchronization.
    last_scheduled_at
    datetime
    (Read-only) Last date/time when an attempt was made by the scheduler to do a synchronization.

    Actions

    Create
    Get
    List
    Delete
    Update
    Associate
    Dissociate

    Action: Create

       Create an export schedule 
    JSONObject schedule = client.create("schedule",
    
      ImmutableMap.of(
        "type" , "screenshot",
        "subtype" , "export",
        "started_at" , new Date();,
        "frequency" , "1440",
        "task" , ImmutableMap.of(
          "type" , "png",
          "locale_id" , "en",
          "screenmode" , "desktop",
          "emails" , ImmutableList.of(
            "test-user@documentation.com"
          )
        ),
        "active" , true
      ));
    System.out.println("Success! %s%n", schedule);
    
       Create an export schedule 
    dynamic properties = new ExpandoObject();
    properties.type = "screenshot";
    properties.subtype = "export";
    properties.started_at = DateTime.UtcNow;
    properties.frequency = "1440";
    properties.task = new {
          type = "png",
          locale_id = "en",
          screenmode = "desktop",
          emails = new List<Object> {
            "test-user@documentation.com"
          }
        };
    properties.active = true;
    
    dynamic schedule = client.create("schedule",    properties);
    Console.WriteLine("Success!", schedule);
    
       Create an export schedule 
    client.create('schedule',
      {
        type: 'screenshot',
        subtype: 'export',
        started_at: new Date(),
        frequency: 1440,
        task: {
            type: 'png',
            locale_id: 'en',
            screenmode: 'desktop',
            emails: [
                'test-user@documentation.com'
            ]
        },
        active: true
    }
    
    )
      .then(function(schedule) {
        console.log('Success!', schedule);
      });
    
       Create an export schedule 
    <?php
    $schedule = $client->create('schedule',
    
      array (
        'type' => 'screenshot',
        'subtype' => 'export',
        'started_at' => date("Y-m-d H:i:s"),
        'frequency' => '1440',
        'task' => array (
          'type' => 'png',
          'locale_id' => 'en',
          'screenmode' => 'desktop',
          'emails' => array (
            'test-user@documentation.com'
          )
        ),
        'active' => true
      )
    
    );
    print("Success! { $schedule }");
    ?>
    
       Create an export schedule 
    curl https://api.luzmo.com/0.1.0/schedule  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "type": "screenshot",
      "subtype": "export",
      "started_at": "2017-08-30T14:30:15Z",
      "frequency": 1440,
      "task": {
        "type": "png",
        "locale_id": "en",
        "screenmode": "desktop",
        "emails": [
          "test-user@documentation.com"
        ]
      },
      "active": true
    }
    }
    EOF
    
    
       Example of a schedule to synchronize a dataset 
    JSONObject schedule = client.create("schedule",
    
      ImmutableMap.of(
        "type" , "dataset",
        "started_at" , new Date();,
        "frequency" , "1440",
        "active" , true
      ));
    System.out.println("Success! %s%n", schedule);
    
       Example of a schedule to synchronize a dataset 
    dynamic properties = new ExpandoObject();
    properties.type = "dataset";
    properties.started_at = DateTime.UtcNow;
    properties.frequency = "1440";
    properties.active = true;
    
    dynamic schedule = client.create("schedule",    properties);
    Console.WriteLine("Success!", schedule);
    
       Example of a schedule to synchronize a dataset 
    client.create('schedule',
      {
        type: 'dataset',
        started_at: new Date(),
        frequency: 1440,
        active: true
    }
    
    )
      .then(function(schedule) {
        console.log('Success!', schedule);
      });
    
       Example of a schedule to synchronize a dataset 
    <?php
    $schedule = $client->create('schedule',
    
      array (
        'type' => 'dataset',
        'started_at' => 'date("Y-m-d H:i:s"),
        'frequency' => '1440',
        'active' => true
      )
    
    );
    print("Success! { $schedule }");
    ?>
    
       Example of a schedule to synchronize a dataset 
    curl https://api.luzmo.com/0.1.0/schedule  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "type": "dataset",
      "started_at": "2017-08-30T14:30:15Z",
      "frequency": 1440,
      "active": true
    }
    }
    EOF
    
    
    Create
    can be executed by:
    Logged-in User

    Action: Update

       Change frequency to yearly 
    JSONObject schedule = client.update("schedule", "<your schedule id>", 
      ImmutableMap.of(
        "frequency" , "525600"
      ));
    
       Change frequency to yearly 
    dynamic properties = new ExpandoObject();
    properties.frequency = "525600";
    
    dynamic schedule = client.update("schedule", "<your schedule id>", );
    
       Change frequency to yearly 
    client.update('schedule',
      '<your schedule id>',
      {
        frequency: 525600
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Change frequency to yearly 
    <?php
    $user = $client->update('schedule', '<your schedule id>', 
      array (
        'frequency' => '525600'
      ));
    ?>
    
       Change frequency to yearly 
    curl https://api.luzmo.com/0.1.0/schedule  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your schedule id>",
      "properties": {
      "frequency": 525600
    }
    }
    EOF
    
       Change frequency to yearly 
    schedule = client.update("schedule", "<your_schedule_id>", {
        "frequency": 525600
    })
    
    Update
    can be executed by:
    Securable Modifier

    Action: Get

       Retrieve a schedule and the securables for which it schedules a task (e.g. datasets/dashboards) 
    JSONObject data = client.get("schedule", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "id" , "< your schedule id >"
        ),
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "Securable"
          )
        )
      ));
    
    
       Retrieve a schedule and the securables for which it schedules a task (e.g. datasets/dashboards) 
    dynamic query = new ExpandoObject();
    query.where = new {
          id = "< your schedule id >"
        };
    query.include = new List<Object> {
    
          new {
            model = "Securable"
          }
        };
    
    dynamic data = client.get("schedule",     query);
    
    
       Retrieve a schedule and the securables for which it schedules a task (e.g. datasets/dashboards) 
    client.get('schedule', {
        where: {
            id: '< your schedule id >'
        },
        include: [
            {
                model: 'Securable'
            }
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Retrieve a schedule and the securables for which it schedules a task (e.g. datasets/dashboards) 
    <?php
    $user = $client->get('schedule', 
      array (
        'where' => array (
          'id' => '< your schedule id >'
        ),
        'include' => array (
    
          array (
            'model' => 'Securable'
          )
        )
      ));
    
    ?>
    
       Retrieve a schedule and the securables for which it schedules a task (e.g. datasets/dashboards) 
    curl https://api.luzmo.com/0.1.0/schedule  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "id": "< your schedule id >"
      },
      "include": [
        {
          "model": "Securable"
        }
      ]
    }
    }
    EOF
    
    
       Retrieve a schedule and the securables for which it schedules a task (e.g. datasets/dashboards) 
    data = client.get("schedule", {
        "where": {
          "id": "< your schedule id >"
        },
        "include": [{
          "model": "Securable"
        }]
    })
    
    
       Example of the return structure of the query above 
    {
      "count": 2,
      "rows": [
        {
          "id": "29db3c0e-be2b-488b-9b54-d1d9ae9dff3a",
          "task": null,
          "started_at": "2018-09-03T12:38:18.614Z",
          "frequency": 1440,
          "retries": 0,
          "active": true,
          "completed_at": "2018-09-03T12:38:18.614Z",
          "created_at": "2018-09-03T12:38:18.630Z",
          "updated_at": "2018-09-03T12:38:18.656Z",
          "last_scheduled_at": null,
          "user_id": "b0d76f5d-f3da-4c55-9497-d8457ccdccda",
          "securable_id": "b3cfbfc2-a9c0-48e3-b726-b93bdb569bfa",
          "scheduled_at": "2018-09-04T12:38:18.614Z",
          "timezone": "",
          "securable": {
            "id": "b3cfbfc2-a9c0-48e3-b726-b93bdb569bfa",
            "type": "dataset",
            "subtype": "api",
            "name": {
              "en": "Customers.csv"
            },
            "description": null,
            "subtitle": null,
            "contents": null,
            "css": null,
            "source_dataset": null,
            "source_sheet": null,
            "source_query": null,
            "transformation": null,
            "rows": 2806,
            "featured": false,
            "modified_at": "2018-09-03T12:38:17.857Z",
            "cache": 0,
            "created_at": "2018-09-03T12:38:17.651Z",
            "updated_at": "2018-09-03T12:38:18.495Z",
            "template_id": null,
            "source_id": null,
            "modifier_id": "b0d76f5d-f3da-4c55-9497-d8457ccdccda",
            "owner_id": "b0d76f5d-f3da-4c55-9497-d8457ccdccda"
          }
        },
        {
          ...
        }
      ]
    }
    
    Get
    can be executed by:
    Securable Modifier
    List
    can be executed by:
    Securable Modifier

    Action: Delete

       This will delete the specified Schedule 
    client.delete("schedule", "<your schedule id>");
    
       This will delete the specified Schedule 
    $client->delete("schedule", "<your schedule id>");
    
       This will delete the specified Schedule 
    let promise = client.delete('schedule', '<your schedule id>');
    
       This will delete the specified Schedule 
    <?php
    $client->delete('schedule', '<your schedule id>');
    ?>
    
       This will delete the specified Schedule 
    curl https://api.luzmo.com/0.1.0/schedule  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your schedule id>"
    }
    EOF
    
       This will delete the specified Schedule 
    client.delete("schedule", "<your_schedule_id>")
    
    Delete
    can be executed by:
    Securable Modifier

    Delete a schedule by providing the id of the schedule. You can only delete schedules if the securable that is linked to it can be modified by you.

    Associations

    Schedules are automatically associated to users on creation and need to be associated to datasets/dashboards in order to have effect.

    %3 <!-- Dashboard --> Dashboard Dashboard <!-- Securable --> Securable Securable <!-- Dashboard->Securable --> Dashboard->Securable <!-- Dataset --> Dataset Dataset <!-- Dataset->Securable --> Dataset->Securable <!-- User --> User User <!-- Schedule --> Schedule Schedule <!-- User->Schedule --> User->Schedule <!-- Schedule->Securable --> Schedule->Securable

    Associate: Alert (implicit)

       Schedules are automatically linked to the alert on creation time 
    JSONObject account = client.create("alert",
    
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "<title of your alert>"
        ),
        "query", ImmutableMap.of(
          "dimensions" , ImmutableList.of(
    
            ImmutableMap.of(
              "dataset_id" , "< Burrito dataset id >",
              "column_id" , "< Type of burrito column id >"
            )
          ),
          "measures" , ImmutableList.of(
    
            ImmutableMap.of(
              "dataset_id" , "< Burrito dataset id >",
              "column_id" , "< Number of burritos column id >",
              "aggregation" , ImmutableMap.of(
                "type" , "sum"
              )
            )
          ),
          "where" , ImmutableList.of(
    
            ImmutableMap.of(
              "expression" , "? in ?",
              "parameters" , ImmutableList.of(
    
                ImmutableMap.of(
                  "dataset_id" , "< Burrito dataset id >",
                  "column_id" , "< Type of burrito column id >"
                ),
                ImmutableList.of("Quesarito", "Chicken baconito")
              )
            )
          ),
          "having", ImmutableList.of(
    
            ImmutableMap.of(
              "expression" , "? >= ?",
              "parameters" , ImmutableList.of(
                ImmutableMap.of(
                  "dataset_id" , "< Burrito dataset id >",
                  "column_id" , "< Sold units column id >"
                  aggregation: {
                    type: 'sum'
                  }
                ),
                10000
              )
            )
          )
        ),
        "frequency", ImmutableMap.of(
          "unit", "day",
          "quantity", 1 
        ),
        "channels, ImmutableList.of(
          ImmutableMap.of(
            "type", "email",
            "config", ImmutableMap.of(
              "recipients", ImmutableList.of(
                "address", "user@organization.com",
                "type", "to",
                "locale", "en"
              ),
              "subject", ImmutableMap.of(
                "en", "Great sales!"
              ),
              "message", ImmutableMap.of(
                "en", "We've done great boys! Check out these numbers!"
              )
            )
          )
        )
      )
    );
    
    
       Schedules are automatically linked to the alert on creation time 
    dynamic properties = new ExpandoObject();
    properties.name = new {
      en = "<title of your alert>"
    };
    properties.query = new {
      dimensions = new List<Object> {
        new {
          dataset_id = "< Burrito dataset id >",
          column_id = "< Type of burrito column id >"
        }
      },
      measures = new List<Object> {
        new {
          dataset_id = "< Burrito dataset id >",
          column_id = "< Number of burritos column id >",
          aggregation = new {
            type = "sum"
          }
        }
      },
      where = new List<Object> {
        new {
          expression = "? in ?",
          parameters = new List<Object> {
            new {
              dataset_id = "< Burrito dataset id >",
              column_i = "< Type of burrito column id >"
            },
            new List<Object>{'Quesarito', 'Chicken baconito'}
          }
        }
      },
      having = new List<Object> {
        new {
          expression = "? >= ?",
          parameters = new List<Object> {
            new {
              dataset_id = "< Burrito dataset id >",
              column_id = "< Sold units column id >",
              aggregation = new {
                type = "sum"
              }
            },
            10000
          }
        }
      }
    };
    properties.frequency = new {
      unit = "day",
      quantity = 1
    };
    properties.channels = new List<Object> {
      new {
        type = "email",
        config = new {
          recipients = new List<Object> {
            new {
              address = "user@organization.com",
              type = "to",
              locale = "en"
            }
          },
          subject = new {
            en = "Great sales!"
          },
          message = new {
            en: "We've done great boys! Check out these numbers!"
          }
        }
      }
    };
    
    dynamic alert = client.create("alert", properties);
    
       Schedules are automatically linked to the alert on creation time 
    client.create('account',
      {
        name: { en: '<title of your alert>' },
        query: {
        dimensions: [
          {
            dataset_id: '< Burrito dataset id >',
            column_id: '< Type of burrito column id >'
          }
        ],
        measures: [
          {
            dataset_id: '< Burrito dataset id >',
            column_id: '< Number of burritos column id >',
            aggregation: {
              type: 'sum'
            }
          }
        ],
        where: [
          {
            expression: '? in ?',
            parameters: [
              {
                dataset_id: '< Burrito dataset id >',
                column_id: '< Type of burrito column id >'
              },
              ['Quesarito', 'Chicken baconito']
            ]
          }
        ],
        having: [
          {
            expression: '? >= ?',
            parameters: [
              {
                dataset_id: '< Burrito dataset id >',
                column_id: '< Sold units column id >',
                aggregation: {
                  type: 'sum'
                }
              },
              10000
            ]
          }
        ]
      },
        frequency: {
        unit: 'day',
        quantity: 1
      },
      channels: [
        {
          type: 'email',
          config: {
            recipients: [
              {
                address: 'user@organization.com',
                type: 'to',
                locale: 'en'
              }
            ],
            subject: {
              en: 'Great sales!'
            },
            message: {
              en: "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    }
    );
    
       Schedules are automatically linked to the alert on creation time 
    <?php
    $alert = $client->create('alert',
      array (
        'name' => array (
          'en' => '<title of your alert>'
        ),
        'query' => array (
          'dimensions' => array (
            array (
              'dataset_id' => '< Burrito dataset id >',
              'column_id' => '< Type of burrito column id >'
            )
          ),
          'measures' => array (
            array (
              'dataset_id' => '< Burrito dataset id >',
              'column_id' => '< Number of burritos column id >',
              'aggregation' => array (
                'type' => 'sum'
              )
            )
          ),
          'where' => array (
            array (
              'expression' => '? in ?',
              'parameters' => array (
                array (
                  'dataset_id' => '< Burrito dataset id >',
                  'column_id' => '< Type of burrito column id >'
                ),
                array ('Quesarito', 'Chicken baconito')
              )
            )
          ),
          'having' => array (
            array (
              'expression' => '? >= ?',
              'parameters' => array (
                array (
                  'dataset_id' => '< Burrito dataset id >',
                  'column_id' => '< Sold units column id >',
                  'aggregation' => array (
                    'type' => 'sum'
                  )
                ),
              10000
              )
            )
          )
        )
        'frequency' => array (
          'unit' => 'day',
          'quantity' => 1
        ),
        'channels' => array (
          array (
            'type' => 'email',
            'config' => array (
              'recipients' => array (
                array (
                  'address' => 'user@organization.com',
                  'type' => 'to',
                  'locale' => 'en'
                )
              ),
              'subject' => array (
                'en' => 'Great sales!'
              ),
              'message' => array (
                'en' => "We've done great boys! Check out these numbers!"
              )
            )
          )
        )
      )
    
    );
    ?>
    
       Schedules are automatically linked to the alert on creation time 
    curl https://api.luzmo.com/0.1.0/alert  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "name": { "en": "<title of your alert>" }
      "query": {
        "dimensions": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Type of burrito column id >"
          }
        ],
        "measures": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Number of burritos column id >",
            "aggregation": {
              "type": "sum"
            }
          }
        ],
        "where": [
          {
            "expression": "? in ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Type of burrito column id >"
              },
              ["Quesarito", "Chicken baconito"]
            ]
          }
        ],
        "having": [
          {
            "expression": "? >= ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Sold units column id >",
                "aggregation": {
                  "type": "sum"
                }
              },
              10000
            ]
          }
        ]
      },
      "frequency": { "unit": "day", "quantity": 1 }
      "channels": [
        {
          "type": "email",
          "config": {
            "recipients": [
              {
                "address": "user@organization.com",
                "type": "to",
                "locale": "en"
              }
            ],
            "subject": {
              "en": "Great sales!"
            },
            "message": {
              "en": "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    }
    }
    EOF
    
       Schedules are automatically linked to the alert on creation time 
    alert = client.create("alert",
    {
        "name": { "en": "<title of your alert>" }
      "query": {
        "dimensions": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Type of burrito column id >"
          }
        ],
        "measures": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Number of burritos column id >",
            "aggregation": {
              "type": "sum"
            }
          }
        ],
        "where": [
          {
            "expression": "? in ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Type of burrito column id >"
              },
              ["Quesarito", "Chicken baconito"]
            ]
          }
        ],
        "having": [
          {
            "expression": "? >= ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Sold units column id >",
                "aggregation": {
                  "type": "sum"
                }
              },
              10000
            ]
          }
        ]
      },
      "frequency": { "unit": "day", "quantity": 1 }
      "channels": [
        {
          "type": "email",
          "config": {
            "recipients": [
              {
                "address": "user@organization.com",
                "type": "to",
                "locale": "en"
              }
            ],
            "subject": {
              "en": "Great sales!"
            },
            "message": {
              "en": "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    })
    
    Alert
    Schedule

    The association to the schedule is created automatically when an alert is made, this association cannot be created manually.

    Associate: Dashboard

       Link a dashboard to a schedule 
    client.associate("securable", "<your securable id>", "Schedule", "< your schedule id>");
    
       Link a dashboard to a schedule 
    
    client.associate("securable", "<your securable id>", "Schedule", "< your schedule id>");
    
       Link a dashboard to a schedule 
    let promise = client.associate('securable', '<your securable id>', {
        role: 'Schedule',
        id: '< your schedule id>'
    });
    
       Link a dashboard to a schedule 
    <?php
    $client->associate('securable', '<your securable id>', 'Schedule', '< your schedule id>', );
    ?>
    
       Link a dashboard to a schedule 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
        "role": "Schedule",
        "id": "< your schedule id>"
      }
    }
    EOF
    
       Link a dashboard to a schedule 
    client.associate("securable", "<your_securable_id>", {"role":"Schedule","id":"< your schedule id>"})
    
    Dashboard
    Schedule
    Associate
    requires:
    Securable Modifier
    and
    Securable Modifier

    Scheduling a dashboard allows you to send automatic exports.

    Associate: Dataset

       Associate a schedule with a securable in order to start synchronizing the securable. 
    client.associate("schedule", "<your schedule id>", "Securables", "<dataset id>");
    
       Associate a schedule with a securable in order to start synchronizing the securable. 
    
    client.associate("schedule", "<your schedule id>", "Securables", "<dataset id>");
    
       Associate a schedule with a securable in order to start synchronizing the securable. 
    let promise = client.associate('schedule', '<your schedule id>', {
        role: 'Securables',
        id: '<dataset id>'
    });
    
       Associate a schedule with a securable in order to start synchronizing the securable. 
    <?php
    $client->associate('schedule', '<your schedule id>', 'Securables', '<dataset id>', );
    ?>
    
       Associate a schedule with a securable in order to start synchronizing the securable. 
    curl https://api.luzmo.com/0.1.0/schedule  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your schedule id>",
      "resource": {
        "role": "Securables",
        "id": "<dataset id>"
      }
    }
    EOF
    
       Associate a schedule with a securable in order to start synchronizing the securable. 
    client.associate("schedule", "<your_schedule_id>", {"role":"Securables","id":"<dataset id>"})
    
    Dataset
    Schedule
    Associate
    requires:
    Securable Modifier

    Schedules are used to schedule synchronization for datasets coming from Webservice connectors (e.g. Google Drive, Asana, etc.). To start scheduling a specific dataset, you need to link the schedule to the dataset by associating them.

    Associate: User (implicit)

       Schedules are automatically linked to the user who created them 
    JSONObject schedule = client.create("schedule",
    
      ImmutableMap.of(
        "type" , "dataset",
        "started_at" , "startDate",
        "frequency" , "1440",
        "scheduled_at" , new Date();,
        "completed_at" , new Date();,
        "active" , true
      ));
    System.out.printf("User id: %s%n", schedule.get("user_id"));
    
       Schedules are automatically linked to the user who created them 
    dynamic properties = new ExpandoObject();
    properties.type = "dataset";
    properties.started_at = "startDate";
    properties.frequency = "1440";
    properties.scheduled_at = DateTime.UtcNow;
    properties.completed_at = DateTime.UtcNow;
    properties.active = true;
    
    dynamic schedule = client.create("schedule",    properties);
    
     Console.WriteLine("User id is {0}", schedule["user_id"]);
    
       Schedules are automatically linked to the user who created them 
    client.create('schedule', {
      type: 'dataset',
      started_at: 'startDate',
      frequency: 1440,
      scheduled_at: new Date(),
      completed_at: '<!new Date()!>',
      active: true
    })
      .then(function(schedule) {
        var user = schedule.user_id;
      });
    
       Schedules are automatically linked to the user who created them 
    <?php
    $schedule = $client->create('schedule',
    
      array (
        'type' => 'dataset',
        'started_at' => 'startDate',
        'frequency' => '1440',
        'scheduled_at' => date("Y-m-d H:i:s"),
        'completed_at' => date("Y-m-d H:i:s"),
        'active' => true
      )
    
    );
    print( $schedule['user_id'] );
    ?>
    
       Schedules are automatically linked to the user who created them 
    curl https://api.luzmo.com/0.1.0/schedule  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "type": "dataset",
        "started_at": "startDate",
        "frequency": 1440,
        "scheduled_at": "2017-08-30T14:30:15Z",
        "completed_at": "2017-08-30T14:30:15Z",
        "active": true
      }
    }
    EOF
    # result format of the schedule contains the user_id 
    {
     ... 
     "user_id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
       Create a scheduled (daily = 24 * 60) pdf export that will be sent to e-mail 
    export = client.create("export",
    {
        "securable_id": " < your dataset id >",
        "type": "pdf",
        "schedule": {
          "frequency": 1440,
          "start_date": "2018-09-03T12:16:59Z"
        },
        "emails": ["testexport@luzmo.com"]
    })
    print("Success! ", export)
    
    User
    Schedule

    This is a special case similar to many entities that are linked to user. The association to the creating user is created automatically when a schedule is made, this association cannot be created manually. The user that created the schedule is the only one who can get, delete, update, associate or dissociate this schedule

    Dissociate

    Dissociating is similar for all resources. To break the link between two resources, simply provide the resource names and ids. Be careful that the 'role' of a resource is uppercase and usually plural. Dissociating can be done in both directions.

    Share

    A share is a private link to a dashboard. Each share has a default language and its own usage statistics. The creating user is automatically linked to the Share.

    Besides of sharing dashboards with users that do not have a Luzmo account, another usage is to have different usage statistics for different groups of users. In other words, you can create multiple share links for a dashboard for which the owner receives separate usage statistics.

    Properties

    Parameter
    Description
    id
    string
    Unique 8 character key of the share (automatically assigned)
    date
    datetime
    Creation date of the share. Defaults to the current date.

    Actions

    Create
    Get
    List
    Delete
    Update

    Action: Create

       Shares don't require parameters and are immediately linked to a user on creation 
    JSONObject share = client.create("share",
    
      ImmutableMap.of(
    
      ));
    System.out.printf("User id: %s%n", share.get("user_id"));
    
       Shares don't require parameters and are immediately linked to a user on creation 
    dynamic properties = new ExpandoObject();
    
    dynamic share = client.create("share",    properties);
    
     Console.WriteLine("User id is {0}", share["user_id"]);
    
       Shares don't require parameters and are immediately linked to a user on creation 
    client.create('share',
      {}
    
    )
      .then(function(share) {
        var user = share.user_id;
      });
    
       Shares don't require parameters and are immediately linked to a user on creation 
    <?php
    $share = $client->create('share',
    
      array (
    
      )
    
    );
    print( $share['user_id'] );
    ?>
    
       Shares don't require parameters and are immediately linked to a user on creation 
    curl https://api.luzmo.com/0.1.0/share  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {}
    }
    EOF
    # result format of the share contains the user_id 
    {
     ... 
     "user_id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
       Shares don't require parameters and are immediately linked to a user on creation 
    share = client.create("share",
    {
    
    })
    user = share["user_id"]
    
    Create
    can be executed by:
    Logged-in User

    Creating a share allows you to create private urls. Once you have created a share, retrieve the share id from the result. This id will have be a short code (e.g. fzvq1g10) from which you can then construct an url: (e.g. app.luzmo.com/s/-fzvq1g10)

    To create a working private link, several steps are necessary:

    Action: Get

       Retrieving a share and the connected resources 
    JSONObject data = client.get("share", 
      ImmutableMap.of(
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "Securable"
          ),
    
          ImmutableMap.of(
            "model" , "Locale"
          )
        )
      ));
    
    
       Retrieving a share and the connected resources 
    dynamic query = new ExpandoObject();
    query.include = new List<Object> {
    
          new {
            model = "Securable"
          },
    
          new {
            model = "Locale"
          }
        };
    
    dynamic data = client.get("share",     query);
    
    
       Retrieving a share and the connected resources 
    client.get('share', {
        include: [
            {
                model: 'Securable'
            },
            {
                model: 'Locale'
            }
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Retrieving a share and the connected resources 
    <?php
    $user = $client->get('share', 
      array (
        'include' => array (
    
          array (
            'model' => 'Securable'
          ),
    
          array (
            'model' => 'Locale'
          )
        )
      ));
    
    ?>
    
       Retrieving a share and the connected resources 
    curl https://api.luzmo.com/0.1.0/share  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "include": [
        {
          "model": "Securable"
        },
        {
          "model": "Locale"
        }
      ]
    }
    }
    EOF
    
    
       Retrieving a share and the connected resources 
    data = client.get("share", {
        "include": [{
          "model": "Securable"
        },{
          "model": "Locale"
        }]
    })
    
    
       Example of a share get result, the final url is derived from the share id: app.luzmo.com/s/-fzvq1g10 
    {
      "count": 1,
      "rows": [
        {
          "id": "ad92sybl",
          "date": "2018-09-03T15:35:22.000Z",
          "created_at": "2018-09-03T15:35:22.391Z",
          "updated_at": "2018-09-03T15:35:22.465Z",
          "deleted_at": null,
          "locale_id": "en",
          "securable_id": "5f14b895-80ff-4d24-8982-47e4e0f3d623",
          "user_id": "7b28b650-a425-4324-ac25-c0ade2626180",
          "locale": {
            "id": "en",
            "description": "English",
            "created_at": "2014-12-14T23:00:00.000Z",
            "updated_at": "2014-12-14T23:00:00.000Z"
          },
          "securable": {
            "id": "5f14b895-80ff-4d24-8982-47e4e0f3d623",
            "type": "dashboard",
            "subtype": "api",
            "name": {
              "en": "Test1"
            },
            ...
          }
        }
      ]
    }
    
    Get
    can be executed by:
    Logged-in User
    List
    can be executed by:
    Securable Reader

    Action: Delete

       Deleting a share 
    client.delete("share", "<your share id>");
    
       Deleting a share 
    $client->delete("share", "<your share id>");
    
       Deleting a share 
    let promise = client.delete('share', '<your share id>');
    
       Deleting a share 
    <?php
    $client->delete('share', '<your share id>');
    ?>
    
       Deleting a share 
    curl https://api.luzmo.com/0.1.0/share  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your share id>"
    }
    EOF
    
       Deleting a share 
    client.delete("share", "<your_share_id>")
    
    Delete
    can be executed by:
    Securable Owner

    Delete a share by providing the id of the share. You can only delete schedules if the securable that is linked to it can be modified by you.

    Associations

    Shares are automatically connected to the users that make them. Besides of that, they have to be associated to the dashboard that they share and can optionally be associated to a locale in order to set the default locale for the share. In order to make a private share link work you also have to make sure that you dashboards and the datasets that are used are associated with the public group.

    %3 <!-- Dashboard --> Dashboard Dashboard <!-- Securable --> Securable Securable <!-- Dashboard->Securable --> Dashboard->Securable <!-- Dataset --> Dataset Dataset <!-- Dataset->Securable --> Dataset->Securable <!-- User --> User User <!-- Share --> Share Share <!-- User->Share --> User->Share <!-- Locale --> Locale Locale <!-- Share->Securable --> Share->Securable <!-- Share->Locale --> Share->Locale

    Associate: Dashboard

       Link a share to a dashboard
    client.associate("securable", "<your securable id>", "Shares", "< your share id>");
    
       Link a user to a dashboard
    dynamic properties = new ExpandoObject();
    
    client.associate("securable", "<your securable id>", "Shares", "< your share id>");
    
       Link a share to a dashboard
    let promise = client.associate('securable', '<your securable id>', {
        role: 'Shares',
        id: '< your share id>'
    } );
    
       Link a share to a dashboard
    <?php
    $client->associate('securable', '<your securable id>', 'Shares', '< your share id>');
    ?>
    
       Link a share to a dashboard
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
        "role": "Shares",
        "id": "< your share id>"
      }
    }
    EOF
    
       Link a user to a share 
    client.associate("securable", "<your_securable_id>", {"role":"Shares","id":"< your share id>"})
    
    Dashboard
    Share
    Associate
    requires:
    Share Owner
    and
    Securable Owner

    Creating a share and associating it to a dashboard makes it possible to share private links with users.

    Associate: Locale

       Set the locale of a share. 
    client.associate("locale", "<your locale id>", "Shares", "< your share id>");
    
       Set the locale of a share. 
    
    client.associate("locale", "<your locale id>", "Shares", "< your share id>");
    
       Set the locale of a share. 
    let promise = client.associate('locale', '<your locale id>', {
        role: 'Shares',
        id: '< your share id>'
    });
    
       Set the locale of a share. 
    <?php
    $client->associate('locale', '<your locale id>', 'Shares', '< your share id>', );
    ?>
    
       Set the locale of a share. 
    curl https://api.luzmo.com/0.1.0/locale  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your locale id>",
      "resource": {
        "role": "Shares",
        "id": "< your share id>"
      }
    }
    EOF
    
       Set the locale of a share. 
    client.associate("locale", "<your_locale_id>", {"role":"Shares","id":"< your share id>"})
    
    Locale
    Share
    Associate
    requires:
    Logged-in User
    and
    Securable Owner

    A user is allowed to link a locale to a share in case the user is owner of the dashboard that is shared in the link. Associating a locale with the share will make sure that all users that open the dashboard via this link will see it in that specific locale. You can make multiple share links for a dashboard with different locales in case you need to send private links to a mixed audience.

    Associate: User

    User
    Share
       Shares don't require parameters and are immediately linked to a user on creation 
    JSONObject share = client.create("share",
    
      ImmutableMap.of(
    
      ));
    System.out.printf("User id: %s%n", share.get("user_id"));
    
       Shares don't require parameters and are immediately linked to a user on creation 
    dynamic properties = new ExpandoObject();
    
    dynamic share = client.create("share",    properties);
    
     Console.WriteLine("User id is {0}", share["user_id"]);
    
       Shares don't require parameters and are immediately linked to a user on creation 
    client.create('share', {})
      .then(function(share) {
        var user = share.user_id;
      });
    
       Shares don't require parameters and are immediately linked to a user on creation 
    <?php
    $share = $client->create('share',
    
      array (
    
      )
    
    );
    print( $share['user_id'] );
    ?>
    
       Shares don't require parameters and are immediately linked to a user on creation 
    curl https://api.luzmo.com/0.1.0/share  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {}
    }
    EOF
    # result format of the share contains the user_id 
    {
     ... 
     "user_id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
       Shares don't require parameters and are immediately linked to a user on creation 
    share = client.create("share",
    {
    
    })
    user = share["user_id"]
    

    This is a special case similar to many entities that are linked to user. When creating a private link to a dashboard, the creating user is automatically linked to the Share. Note that the code on the right only creates a link which is not yet linked to a dashboard.

    Dissociate

       Dissociate the locale 
    client.dissociate("share", "<your share id>", "Locales", "en");
    
       Dissociate the locale 
    client.dissociate("share", "<your share id>", "Locales", "en");
    
       Dissociate the locale 
    let promise = client.dissociate('share', '<your share id>', {
        role: 'Locales',
        id: 'en'
    });
    
       Dissociate the locale 
    <?php
    $client->associate('share', '<your share id>', "Locales", "en");
    ?>
    
       Dissociate the locale 
    curl https://api.luzmo.com/0.1.0/share  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your share id>",
      "resource": {
      "role": "Locales",
      "id": "en"
    }
    }
    EOF
    
       Dissociate the locale 
    client.dissociate("share", "<your_share_id>", {"role":"Locales","id":"en"})
    
       Dissociate the dashboard that is shared 
    client.dissociate("share", "<your share id>", "Securables", "<the new securable id>");
    
       Dissociate the dashboard that is shared 
    client.dissociate("share", "<your share id>", "Securables", "<the new securable id>");
    
       Dissociate the dashboard that is shared 
    let promise = client.dissociate('share', '<your share id>', {
        role: 'Securables',
        id: '<the new securable id>'
    });
    
       Dissociate the dashboard that is shared 
    <?php
    $client->associate('share', '<your share id>', "Securables", "<the new securable id>");
    ?>
    
       Dissociate the dashboard that is shared 
    curl https://api.luzmo.com/0.1.0/share  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your share id>",
      "resource": {
      "role": "Securables",
      "id": "<the new securable id>"
    }
    }
    EOF
    
       Dissociate the dashboard that is shared 
    client.dissociate("share", "<your_share_id>", {"role":"Securables","id":"<the new securable id>"})
    

    Dissociating is similar for all resources. To break the link between two resources, simply provide the resource names and ids. Be careful that the 'role' of a resource is uppercase and usually plural. Dissociating can be done in both directions.

    Tag

    A tag is an identification of a dashboard or dataset which you can use to group several dashboards or datasets together, that can then be filtered on using the search bar. For example, you can set the tag 'HR' for all the dashboards related to HR and then you can find all these dashboards by searching for 'HR' in the search bar.

    Properties

    Parameter
    Description
    tag
    string
    Unique name of a tag (150 characters max)

    Actions

    Create
    Get & List
    Delete
    Association
    Dissociation

    Action: Create

       Example of creation of a tag and associating with a securable at the same time 
    JSONObject tag = client.create("tag",
    
      ImmutableMap.of(
        "tag" , "My first tag"
      ),
      ImmutableList.of(
    
        ImmutableMap.of(
          "role" , "Securables",
          "id" , "securable_id"
        )
      ));
    System.out.println("Success! %s%n", tag);
    
       Example of creating a tag 
    dynamic properties = new ExpandoObject();
    properties.tag = "My first tag";
    
    dynamic tag = client.create("tag",    properties);
    Console.WriteLine("Success!", tag);
    
       Example of creation of a tag and associating with a securable at the same time 
    client.create('tag',
      {
        tag: 'My first tag'
    },
      [ {
        role: 'Securables',
        id: '< securable_id >'
    } ]
    )
      .then(function(tag) {
        console.log('Success!', tag);
      });
    
       Example of creation of a tag and associating with a securable at the same time 
    <?php
    $tag = $client->create('tag',
    
      array (
        'tag' => 'My first tag'
      )
    );
    print("Success! { $tag }");
    ?>
    
       Example of creation of a tag and associating with a securable at the same time 
    curl https://api.luzmo.com/0.1.0/tag  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "tag": "My first tag"
      },
      "associations": [
      {
        "role": "Securables",
        "id": "< securable_id >"
      },
      .....
    ]
    }
    EOF
    
    
    Create
    can be executed by:
    Logged-in User

    A tag can be associated with a securable at the time of creation.

    Action: Get & List

       Example query that returns a tag based on the tag name 
    JSONObject data = client.get("tag", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "tag" , "< your tag name >"
        )
      ));
    
    
       Example query that returns a tag based on the tag name 
    dynamic query = new ExpandoObject();
    query.where = new {
          tag = "< your tag name >"
        };
    
    dynamic data = client.get("tag",     query);
    
    
       Example query that returns a tag based on the tag name 
    client.get('tag', {
        where: {
            tag: '< your tag name >'
        }
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Example query that returns a tag based on the tag name 
    <?php
    $tag = $client->get('tag', 
      array (
        'where' => array (
          'tag' => '< your tag name >'
        )
      ));
    
    ?>
    
       Example query that returns a tag based on the tag name 
    curl https://api.luzmo.com/0.1.0/tag  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "tag": "< your tag name >"
      }
    }
    }
    EOF
    
    
       Example of the return structure of the query above 
    {
        "count": 1,
        "rows": [
            {
                "id": "364de8ef-....",
                "tag": "Test tag 1",
                "category": null,
                "created_at": "2020-02-27T10:58:48.727Z",
                "updated_at": "2020-02-27T10:58:48.726Z",
                "deleted_at": null
            }
        ]
    }
    
       Example query that returns all tags that are applied to a securable matching the id. 
    JSONObject data = client.get("tag", 
      ImmutableMap.of(
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "Securable",
            "where", ImmutableList.of(
              ImmutableList.of(
                "id", "< your securable id >"
              )
            )
          )
        )
      ));
    
    
       Example query that returns all tags that are applied to a securable matching the id. 
    dynamic query = new ExpandoObject();
    query.include = new List<Object> {
        new {
            model = "Securable",
            where = new {
              id = "< your securable id>"
            },
            attributes = new List<Object> {
              "id",
              "name"
            },
            jointype = "inner"
        }
    };
    
    dynamic data = client.get("tag",     query);
    
    
       Example query that returns all tags that are applied to a securable matching the id. 
    client.get('tag', {
        include: [
            {
                model: 'Securable',
                where: {
                    id: "< your securable id >"
                },
                attributes: ["id", "name"],
                jointype: "inner"
            }
        ]
    })
    .then(function(data) {
      console.log('Success!', data);
    })
    
       Example query that returns all tags that are applied to a securable matching the id. 
    <?php
    $tag = $client->get('tag', 
      array (
        'include' => array (
          array (
              'model' => 'Securable',
              'where' => array (
                  'id' => '< id of securable >'
              ),
              'jointype' => 'inner'
          )
        )
      ));
    
    ?>
    
       Example query that returns all tags that are applied to a securable matching the id. 
    curl https://api.luzmo.com/0.1.0/tag  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
        "include": [
            {
                "model": "Securable",
                "where": {
                    "id": "< your securable id >"
                },
                "attributes": ["id", "name"],
                "jointype": "inner"
            }
        ]
      }
    }
    EOF
    
    
       Example of the return structure of the query above 
    {
        "count": 2,
        "rows": [
            {
                "id": "364de8ef-....",
                "tag": "Test tag 1",
                "category": null,
                "created_at": "2020-02-27T10:58:48.727Z",
                "updated_at": "2020-02-27T10:58:48.726Z",
                "deleted_at": null,
                "securables": [
                    {
                        "name": {
                            "en": ""
                        },
                        "id": "2be5dcfa-....",
                        "securablesTag": {
                            "created_at": "2020-02-27T10:58:48.741Z",
                            "updated_at": "2020-02-27T10:58:48.741Z",
                            "tag_id": "364de8ef-....",
                            "securable_id": "2be5dcfa-...."
                        }
                    }
                ]
            },
            {
                "id": "c7e251e9-....",
                "tag": "Test tag 2",
                "category": null,
                "created_at": "2020-02-27T11:02:22.585Z",
                "updated_at": "2020-02-27T11:02:22.585Z",
                "deleted_at": null,
                "securables": [
                    {
                        "name": {
                            "en": ""
                        },
                        "id": "2be5dcfa-....",
                        "securablesTag": {
                            "created_at": "2020-02-27T11:02:22.601Z",
                            "updated_at": "2020-02-27T11:02:22.601Z",
                            "tag_id": "c7e251e9-....",
                            "securable_id": "2be5dcfa-...."
                        }
                    }
                ]
            }
        ]
    }
    
    Get
    can be executed by:
    Logged-in User
    List
    can be executed by:
    Logged-in User

    Action: Delete

       Delete a tag 
    client.delete("tag", "<your tag id>");
    
       Delete a tag 
    $client->delete("tag", "<your tag id>");
    
       Delete a tag 
    let promise = client.delete('tag', '<your tag id>');
    
       Delete a tag 
    <?php
    $client->delete('tag', '<your tag id>');
    ?>
    
       Delete a tag 
    curl https://api.luzmo.com/0.1.0/tag  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your tag id>"
    }
    EOF
    
        
    client.delete("tag", "<your_tag_id>")
    
    Delete
    can be executed by:

    Associations

    Tags can only be associated to securables and the association should be specified at the time of their creation.

    Associate: Securables

       Add a column to your dataset (you have to create the column first) 
    client.associate("tag", "< your tag id >", "Securables", "<  your securable id >");
    
       Add a column to your dataset (you have to create the column first) 
    
    client.associate("tag", "< your tag id >", "Securables", "<  your securable id >");
    
       Add a column to your dataset (you have to create the column first) 
    let promise = client.associate('tag', '< your tag id >', {
        role: 'Securables',
        id: '<  your securable id >'
    });
    
       Add a column to your dataset (you have to create the column first) 
    <?php
    $client->associate('tag', '< your tag id >', 'Securables', '<  your securable id >', );
    ?>
    
       Add a column to your dataset (you have to create the column first) 
    curl https://api.luzmo.com/0.1.0/tag  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "< your tag id >",
      "resource": {
        "role": "Securables",
        "id": "<  your securable id >"
      }
    }
    EOF
    
       Add a column to your dataset (you have to create the column first) 
    client.associate("tag", "< your tag id >", {"role":"Securables", "id":"<  your securable id >"})
    
    Tag
    Securables
    Associate
    requires:
    Logged-in User

    Associating a tag to a securable is useful to group dashboards/datasets together. These tags can be used in the search bar in our UI, but also to e.g. get a list of tagged dashboards via API.

    Dissociate

       Dissociate a tag with a securable 
    client.dissociate("tag", "< your tag id >", "Securables", "< your securable id >");
    
       Dissociate a tag with a securable 
    client.dissociate("tag", "< your tag id >", "Securables", "< your securable id >");
    
       Dissociate a tag with a securable 
    let promise = client.dissociate('tag', '< your tag id >', {
        role: 'Securables',
        id: '< your securable id >'
    })
    
       Dissociate a tag with a securable 
    <?php
    $client->associate('tag', '< your tag id >', "Securables", "< your securable id >");
    ?>
    
       Dissociate a tag with a securable 
    curl https://api.luzmo.com/0.1.0/tag  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "< your tag id >",
      "resource": {
      "role": "Securables",
      "id": "< your securable id >"
    }
    }
    EOF
    
       Dissociate a tag with a securable 
    client.dissociate("tag", "< your tag id >", {"role":"Securables","id":"< your securable id >"})
    

    Dissociating is similar for all resources. To break the link between two resources, simply provide the resource names and ids. Be careful that the 'role' of a resource is uppercase and usually plural. Dissociating can be done in both directions.

    Theme

    A theme for your dashboards, belonging to your organization.

    Properties

    Parameter
    Description
    id
    string
    Unique key of the theme (automatically assigned)
    name
    string
    Name of the theme
    theme
    string
    JSON definition of the theme.
    created_at
    datetime
    Creation date of the theme.
    updated_at
    datetime
    The date and time at which the theme was last updated

    Actions

    Create
    Get
    List
    Delete
    Update

    Action: Create

       Example of the creation of a 'theme' resource. 
    JSONObject theme = client.create("theme",
    
      ImmutableMap.of(
        "name" , ImmutableMap.of( "en" , "My super fancy theme"),
        "theme" , ImmutableMap.of(
          "font", ImmutableMap.of(
            "fontSize", 15,
            "fontFamily", "Open Sans"
          ),
          "type", "custom",
          "title", ImmutableMap.of(
            "bold", false,
            "align", "left",
            "border", false,
            "italic", true,
            "underline", false,
            "fontSize", 20,
            "lineHeight", 40
          ),
          "colors", ImmutableList.of(
            "#00a8b7",
            "rgb(232,228,228)",
            "rgba(226,180,12,0.5)"
          ),
          "borders", ImmutableMap.of(
            "border-color", "rgba(0,0,0,.1)",
            "border-style", "none",
            "border-radius", "3px",
            "border-top-width", "1px",
            "border-left-width", "1px",
            "border-right-width", "1px",
            "border-bottom-width", "1px"
          ),
          "margins", ImmutableList.of(
            10,
            10
          ),
          "boxShadow", ImmutableMap.of(
            "size", "S",
            "color", "rgb(2,34,32)"
          ),
          "mainColor", "#004cb7",
          "background", "#EEF3F6",
          "itemsBackground", "#ffffff",
          "editModeBackground", "#ececec",
          "axis", ImmutableMap.of(
            "fontSize", 13
          ),
          "legend", ImmutableMap.of(
            "type", "normal"
          ),
          "tooltip", ImmutableMap.of(
            "background", "rgba(255,255,255,1)",
            "fontSize", 13
          ),
          "editBackground", "rgb(222, 226, 229)",
          "editDarkOrLight", "light-edit",
          "darkOrLight", "light",
          "name", "My fancy theme"
        )
      )
    );
    System.out.println("Success! %s%n", theme);
    
       Example of the creation of a 'theme' resource.
    dynamic properties = new ExpandoObject();
    properties.name = new {
      en = "My super fancy theme"
    };
    
    properties.theme =  new {
      font = new {
        fontSize = 15,
        fontFamily = Open Sans
      },
      type = "custom",
      title = new {
        bold = false,
        align = "left",
        border = false,
        italic = true,
        underline = false,
        fontSize = 20,
        lineHeight = 40
      },
      colors = new List<String> { 
        "#00a8b7",
        "rgb(232,228,228)",
        "rgba(226,180,12,0.5)"
      },
      borders = new {
        "border-color" = "rgba(0,0,0,.1)",
        "border-style" = "none",
        "border-radius" = "3px",
        "border-top-width" = "1px",
        "border-left-width" = "1px",
        "border-right-width" = "1px",
        "border-bottom-width" = "1px"
      },
      margins = new List<String> {
        10,
        10
      },
      boxShadow = new {
        size = "S",
        color = "rgb(2,34,32)"
      },
      mainColor = "#004cb7",
      background = "#EEF3F6",
      itemsBackground = "#ffffff",
      editModeBackground = "#ececec",
      axis = new {
        fontSize = 13
      },
      legend = new {
        type = "normal"
      },
      tooltip = new {
        background = "rgba(255,255,255,1)",
        fontSize = 13
      },
      editBackground = "rgb(222, 226, 229)",
      editDarkOrLight = "light-edit",
      darkOrLight = "light",
      name = "My fancy theme"
    };
    
    dynamic theme = client.create("theme",    properties);
    Console.WriteLine("Success!", theme);
    
       Example of the creation of a 'theme' resource.
    client.create('theme',
      {
        name: { en: 'example@luzmo.com'},
      theme: {
        font: {
          fontSize: 15,
          fontFamily: "Open Sans"
        },
        type: "custom",
        title: {
          bold: false,
          align: "left",
          border: false,
          italic: true,
          underline: false,
          fontSize: 20,
          lineHeight: 40
        },
        colors: [
          "#00a8b7",
          "rgb(232,228,228)",
          "rgba(226,180,12,0.5)"
        ],
        borders: {
          "border-color": "rgba(0,0,0,.1)",
          "border-style": "none",
          "border-radius": "3px",
          "border-top-width": "1px",
          "border-left-width": "1px",
          "border-right-width": "1px",
          "border-bottom-width": "1px"
        },
        margins: [
          10,
          10
        ],
        boxShadow: {
          "size": "S",
          "color": "rgb(2,34,32)"
        },
        mainColor: "#004cb7",
        background: "#EEF3F6",
        itemsBackground: "#ffffff",
        editModeBackground: "#ececec",
        axis: {
          fontSize: 13
        },
        legend: {
          type: "normal"
        },
        tooltip: {
          background: "rgba(255,255,255,1)",
          fontSize: 13
        },
        editBackground: "rgb(222, 226, 229)",
        editDarkOrLight: "light-edit",
        darkOrLight: "light",
        name: "My fancy theme"
      }
    }
    
    )
      .then(function(theme) {
        console.log('Success!', theme);
      });
    
       Example of the creation of a 'theme' resource.
    <?php
    $theme = $client->create('theme',
    
      array (
        'name' => array (
          en => 'My super fancy theme'
        ),
        'theme' => array(
          'font' => array ( 
            'fontSize' => 15,
            'fontFamily' => 'Open Sans'
          ),
          'type' => 'custom',
          'title'=> array (
            'bold' => false,
            'align' => 'left',
            'border' => false,
            'italic' => true,
            'underline' => false,
            'fontSize' => 20,
            'lineHeight' => 40
          ),
          'colors'=> array (
            '#00a8b7',
            'rgb(232,228,228)',
            'rgba(226,180,12,0.5)'
          ),
          'borders'=> array (
            'border-color' => 'rgba(0,0,0,.1)',
            'border-style' => 'none',
            'border-radius' => '3px',
            'border-top-width' => '1px',
            'border-left-width' => '1px',
            'border-right-width' => '1px',
            'border-bottom-width' => '1px'
          ),
          'margins'=> array (
            10,
            10
          ),
          'boxShadow'=> array (
            'size' => 'S',
            'color' => 'rgb(2,34,32)'
          ),
          'mainColor' => '#004cb7',
          'background' => '#EEF3F6',
          'itemsBackground' => '#ffffff',
          'editModeBackground' => '#ececec',
          'axis'=> array (
            'fontSize': 13
          ),
          'legend'=> array (
            'type' => 'normal'
          ),
          'tooltip'=> array (
            'background' => 'rgba(255,255,255,1)',
            'fontSize' => 13
          ),
          'editBackground' => 'rgb(222, 226, 229)',
          'editDarkOrLight' => 'light-edit',
          'darkOrLight' => 'light',
          'name' => 'My fancy theme'
        )
      )
    
    );
    print("Success! { $theme }");
    ?>
    
       Example of the creation of a 'theme' resource.
    curl https://api.luzmo.com/0.1.0/theme  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "name": {
          "en" : "My super fancy theme",
        }
        "theme": {
          "font": {
            "fontSize": 15,
            "fontFamily": "Open Sans"
          },
          "type": "custom",
          "title": {
            "bold": false,
            "align": "left",
            "border": false,
            "italic": true,
            "underline": false,
            "fontSize": 20,
            "lineHeight": 40
          },
          "colors": [
            "#00a8b7",
            "rgb(232,228,228)",
            "rgba(226,180,12,0.5)"
          ],
          "borders": {
            "border-color": "rgba(0,0,0,.1)",
            "border-style": "none",
            "border-radius": "3px",
            "border-top-width": "1px",
            "border-left-width": "1px",
            "border-right-width": "1px",
            "border-bottom-width": "1px"
          },
          "margins": [
            10,
            10
          ],
          "boxShadow": {
            "size": "S",
            "color": "rgb(2,34,32)"
          },
          "mainColor": "#004cb7",
          "background": "#EEF3F6",
          "itemsBackground": "#ffffff",
          "editModeBackground": "#ececec",
          "axis": {
            "fontSize": 13
          },
          "legend": {
            "type": "normal"
          },
          "tooltip": {
            "background": "rgba(255,255,255,1)",
            "fontSize": 13
          },
          "editBackground": "rgb(222, 226, 229)",
          "editDarkOrLight": "light-edit",
          "darkOrLight": "light",
          "name": "My fancy theme"
        }
      }
    }
    EOF
    
    
    Create
    can be executed by:
    Organization Member

    You can create themes by providing a name and valid JSON theme definition. This way you can easily duplicate themes and make small changes. A theme can be created by anyone who is an organization member and has access to the dashboard editor.

    Action: Update

       Example where the JSON definition a theme is updated programmatically 
    JSONObject theme = client.update("theme", "<your theme id>", 
      ImmutableMap.of(
        "theme" , "<your new JSON theme definition>"
      ));
    
       Example where the JSON definition a theme is updated programmatically 
    dynamic properties = new ExpandoObject();
    properties.theme = "<your new JSON theme definition>";
    
    dynamic theme = client.update("theme", "<your theme id>", );
    
       Example where the JSON definition a theme is updated programmatically 
    client.update('theme',
      '<your theme id>',
      {
        theme: '<your new JSON theme definition>'
      }
      )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Example where the JSON definition a theme is updated programmatically 
    <?php
    $theme = $client->update('theme', '<your theme id>', 
      array (
        'theme' => '<your new JSON theme definition>'
      ));
    ?>
    
       Example where the JSON definition a theme is updated programmatically 
    curl https://api.luzmo.com/0.1.0/theme  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your theme id>",
      "properties": {
      "theme": "<your new JSON theme definition>"
    }
    }
    EOF
    
    Update
    can be executed by:
    Organization Member

    To update a theme, provide the id of the theme and an object of properties which you want to overwrite. A theme can be updated by any member of the organization.

    Action: Get & List

       Simple query to list all themes' id and their names 
    JSONObject data = client.get("theme", 
      ImmutableMap.of(
        "attributes" , ImmutableList.of(
          "id" , "name"
        )
      ));
    
    
       Simple query to list all themes' id and their names 
    dynamic query = new ExpandoObject();
    query.attributes = new List<string> {
          "id", "name"
        };
    
    dynamic data = client.get("theme",     query);
    
    
       Simple query to list all themes' id and their names 
    client.get('theme', {
        attributes: [
        'id', 'name'
      ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Simple query to list all themes' id and their names 
    <?php
    $theme = $client->get('theme', 
      array (
        'attributes' => array (
          'id', 'name'
        )
      ));
    
    ?>
    
       Simple query to list all themes' id and their names 
    curl https://api.luzmo.com/0.1.0/theme  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "attributes": [
        "id", "name"
      ]
    }
    }
    EOF
    
    
    Get
    can be executed by:
    Anonymous
    Logged-in User
    List
    can be executed by:
    Organization Member

    Any user in an organization can get and list the custom themes that are associated to the organization.

    Action: Delete

       An organization owner can delete a theme using its id 
    client.delete("theme", "<your theme id>");
    
       An organization owner can delete a theme using its id 
    $client->delete("theme", "<your theme id>");
    
       An organization owner can delete a theme using its id 
    let promise = client.delete('theme', '<your theme id>');
    
       An organization owner can delete a theme using its id 
    <?php
    $client->delete('theme', '<your theme id>');
    ?>
    
       An organization owner can delete a theme using its id 
    curl https://api.luzmo.com/0.1.0/theme  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your theme id>"
    }
    EOF
    
    Delete
    can be executed by:
    Organization Owner

    An organization owner can delete any themes that are associated with his organization. If a user is a member, but not an owner, he cannot delete themes. Even if he is the one that created the theme in the first place.

    User

    A registered Luzmo user; note that creating new users can lead to additional charges for your current or next billing cycle. Any anonymous user or organization owner can create new users. You can only view users within your own organization. Only the user him/herself and the organization owner can view the e-mail address or update a user. Only an organization owner can delete a user.

    Properties

    Parameter
    Description
    id
    string
    Unique key of the User (automatically assigned)
    email
    string
    E-mail address of the user
    emailConfirmed
    boolean
    Indicates whether or not the user confirmed his/her email address by clicking the link in the confirmation e-mail.
    phone
    string
    Phone number of the user
    password
    string
    (Optional) Initial password of the user. The user should be encouraged to choose a new password as soon as possible. If no initial password is set, the signup mail will contain an activation link to set the password.
    name
    string
    The full name of the user (first_name last_name)
    city
    string
    Residence city of the user
    suborganization
    string
    (optional) The name of the suborganization you want this user to join (this ensures that users from a suborganization cannot see members of your organization or other suborganizations). If no suborganization is not defined, the user will be added to your organization in case you've used an API token and you're the owner of the organization.
    onboarding_editor_active
    boolean
    Indicates if the initial onboarding guide in the dashboard editor is active or not.
    onboarding_editor_progress
    integer
    Progress the user has made in the initial onboarding guide in the dashboard editor.
    role
    string
    Role of the user within Luzmo. Either 'viewer', 'member', 'admin' or 'owner'. Defaults to 'member' if not specified. If a suborganization is specified, an 'owner' and 'admin' roles are not allowed!
    Viewer role can view dashboards.
    Editor role (i.e. 'member') can create and adapt dashboards and share these to other users.
    Admin role can view, edit, share and delete all organization and sub-organization securables.
    Owner role can add members and set their role, view and adapt plan and billing information, view and adapt the legal & compliance information, create Integrations, create and save organization themes, create and adapt dashboards and share these to other users.
    plan
    string
    The billing plan of the user.
    cycle
    string
    The billing cycle of the user. Can be either monthly or annually.
    currency
    string
    The billing currency of the user.
    flags
    array
    Array containing the flags that have been set for the user. Flags are determined based on the plan of the user.
    account_overrides
    object
    Let this token override the connection to one or more data connections (to a Plugin or database). You can use this to dynamically route requests to different endpoints (eg. the correct endpoint per client in a single-tenant setup). All overrides are optional -- if not specified, the value as configured on the original Account will be used instead.
    < account id >
    object
    The Plugin account id for which you want to override properties as property name.
    base_url
    string
    (optional) The new base URL that will be called.
    properties
    object
    (optional) Lists the custom authentication properties to override for plugin-based connections.
    <custom_property_id>
    string
    (optional) The new custom authentication property value (the key is the custom authentication property id as defined when setting up the plugin in Luzmo).
    This will be sent as X-Property-<custom_property_id> header to the Plugin.
    datasets
    object
    (optional) List of dataset-level overrides. Useful if you want to override only a single table in your dashboard or if you have a separate table per client.
    < dataset id >
    object
    The dataset (securable) ID that you want to override.
    table
    string
    (optional) The new canonical dataset identifier (as defined in the Plugin) to retrieve data from.
    < account id >
    object
    The database account id for which you want to override properties as property name.
    host
    string
    (optional) The new database host to connect to. The database must be of the same type as the originally configured database.
    port
    string
    (optional) The new port to connect to.
    user
    string
    (optional) The new user to use when connecting.
    password
    string
    (optional) The new password to use when connecting.
    schema
    string
    (optional) The new schema to retrieve data from. Note that to MySQL the concepts database and schema are identical. So when overriding a database / schema for MySQL, make sure to pass the same value to both schema and database
    database
    string
    (optional) the new database to retrieve data from. Note that to MySQL the concepts database and schema are identical. So when overriding a database / schema for MySQL, make sure to pass the same value to both schema and database
    table
    string
    (optional) The new table to retrieve data from.
    datasets
    object
    (optional) List of dataset-level overrides. Useful if you want to override only a single table in your dashboard or if you have a separate table per client. The SQL query of the dataset can also be overridden if it's a SQL dataset within Luzmo. Allowing you to call stored procedures for example.
    < dataset id >
    object
    The dataset (securable) ID that you want to override.
    table
    string
    (optional) The new table to connect to
    schema
    string
    (optional) The new schema to connect to.
    sql
    string
    (optional) The new SQL statement to use. NOTE: the columns returned in the new query need to conform to the same schema as the original dataset.

    Actions

    Create
    Get
    List
    Delete
    Update
    Associate
    Dissociate

    Action: Create

       Example of the creation of a 'user' resource. If an organization owner's API token is used to make this request, the user will be added to the Owner's organization. If no API token is provided, it will be added to a new Organization. 
    JSONObject user = client.create("user",
    
      ImmutableMap.of(
        "email" , "example@luzmo.com",
        "password" , "your-password",
        "name" , "Sam Examplius",
        "role", "viewer"
      ));
    System.out.println("Success! %s%n", user);
    
       Example of the creation of a 'user' resource. If an organization owner's API token is used to make this request, the user will be added to the Owner's organization. If no API token is provided, it will be added to a new Organization. 
    dynamic properties = new ExpandoObject();
    properties.email = "example@luzmo.com";
    properties.password = "your-password";
    properties.name = "Sam Examplius";
    properties.role = "viewer";
    
    dynamic user = client.create("user",    properties);
    Console.WriteLine("Success!", user);
    
       Example of the creation of a 'user' resource. If an organization owner's API token is used to make this request, the user will be added to the Owner's organization. If no API token is provided, it will be added to a new Organization. 
    client.create('user',
      {
        email: 'example@luzmo.com',
        password: 'your-password',
        name: 'Sam Examplius',
        role: 'viewer'
    }
    
    )
      .then(function(user) {
        console.log('Success!', user);
      });
    
       Example of the creation of a 'user' resource. If an organization owner's API token is used to make this request, the user will be added to the Owner's organization. If no API token is provided, it will be added to a new Organization. 
    <?php
    $user = $client->create('user',
    
      array (
        'email' => 'example@luzmo.com',
        'password' => 'your-password',
        'name' => 'Sam Examplius',
        'role' => 'viewer'
      )
    
    );
    print("Success! { $user }");
    ?>
    
       Example of the creation of a 'user' resource. If an organization owner's API token is used to make this request, the user will be added to the Owner's organization. If no API token is provided, it will be added to a new Organization. 
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "email": "example@luzmo.com",
        "password": "your-password",
        "name": "Sam Examplius",
        "role": "viewer"
      }
    }
    EOF
    
       Example of the creation of a 'user' resource. If an organization owner's API token is used to make this request, the user will be added to the Owner's organization. If no API token is provided, it will be added to a new Organization. 
    user = client.create("user",
    {
        "email": "example@luzmo.com",
        "password": "your-password",
        "name": "Sam Examplius",
        "role": "viewer"
    })
    print("Success! ", user)
    
       You can additionally specify a suborganization and the invite code can then be used to add users to a suborganization within your organization itself. 
    JSONObject user = client.create("user",
    
      ImmutableMap.of(
        "name" , "New user of my suborganization",
        "email" , "user@suborganization.com",
        "password" , "... random password ...",
        "suborganization" , "suborganization",
        "role" , "member"
      ));
    System.out.println("Success! %s%n", user);
    
       You can additionally specify a suborganization and the invite code can then be used to add users to a suborganization within your organization itself. 
    dynamic properties = new ExpandoObject();
    properties.name = "New user of my organization";
    properties.email = "user@organization.com";
    properties.password = "... random password ...";
    properties.suborganization = "suborganization";
    properties.role = "member";
    
    dynamic user = client.create("user",    properties);
    Console.WriteLine("Success!", user);
    
       You can optionally specify a suborganization to have a clear separation between users (i.e. users from a suborganization cannot see other users from other suborganizations nor from the main organization). 
    client.create('user',
      {
        name: 'New user of my suborganization',
        email: 'user@suborganization.com',
        password: '... random password ...',
        suborganization: 'suborganization',
        role: 'member'
    }
    ).then(function(user) {
        console.log('Success!', user);
      });
    
       You can optionally specify a suborganization to have a clear separation between users (i.e. users from a suborganization cannot see other users from other suborganizations nor from the main organization). 
    <?php
    $user = $client->create('user',
    
      array (
        'name' => 'New user of my suborganization',
        'email' => 'user@suborganization.com',
        'password' => '... random password ...',
        'suborganization' => 'suborganization',
        'role' => 'member'
      )
    
    );
    print("Success! { $user }");
    ?>
    
       You can optionally specify a suborganization to have a clear separation between users (i.e. users from a suborganization cannot see other users from other suborganizations nor from the main organization). 
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "name": "New user of my suborganization",
        "email": "user@suborganization.com",
        "password": "... random password ...",
        "suborganization": "suborganization",
        "role": "member"
      }
    }
    EOF
    
    
        You can optionally specify a suborganization to have a clear separation between users (i.e. users from a suborganization cannot see other users from other suborganizations nor from the main organization).
    user = client.create("user",
    {
        "name": "New user of my organization",
        "email": "user@organization.com",
        "password": "... random password ...",
        "suborganization": "suborganization",
        "role": "member"
    })
    print("Success! ", user)
    
    Create
    can be executed by:
    Anonymous
    Organization Owner

    Any new user that is created without an API token is automatically assigned to a new organization. Users can be created by anyone (even without a login token) in order to bootstrap the process to create a new organization from scratch. An organization owner can use an API token to add a new user directly to the organization. This is the only way to add users to your organization, you can't associate users to organizations after their creation.

    Action: Update

       Example where the password of a user is updated programmatically 
    JSONObject user = client.update("user", "<your user id>", 
      ImmutableMap.of(
        "password" , "your-new-password"
      ));
    
       Example where the password of a user is updated programmatically 
    dynamic properties = new ExpandoObject();
    properties.password = "your-new-password";
    
    dynamic user = client.update("user", "<your user id>", );
    
       Example where the password of a user is updated programmatically 
    client.update('user',
      '<your user id>',
      {
        password: 'your-new-password'
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Example where the password of a user is updated programmatically 
    <?php
    $user = $client->update('user', '<your user id>', 
      array (
        'password' => 'your-new-password'
      ));
    ?>
    
       Example where the password of a user is updated programmatically 
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your user id>",
      "properties": {
      "password": "your-new-password"
    }
    }
    EOF
    
       Example where the password of a user is updated programmatically 
    user = client.update("user", "<your_user_id>", {
        "password": "your-new-password"
    })
    
    Update
    can be executed by:
    User Owner
    Organization Owner

    To update a user, provide the id of the user and an object of properties which you want to overwrite. A user can update itself and an organization can update its user.

    Action: Get & List

       Simple query to get all users from your (sub)organization (in case you are an organization owner, you can get all users from all suborganizations). 
    JSONObject data = client.get("user", 
      ImmutableMap.of(
      ));
    
    
       Simple query to get all users from your (sub)organization (in case you are an organization owner, you can get all users from all suborganizations). 
    dynamic query = new ExpandoObject();
    
    dynamic data = client.get("user",     query);
    
    
       Simple query to get all users from your (sub)organization (in case you are an organization owner, you can get all users from all suborganizations). 
    client.get('user', {
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Simple query to get all users from your (sub)organization (in case you are an organization owner, you can get all users from all suborganizations). 
    <?php
    $user = $client->get('user', 
      array (
      ));
    
    ?>
    
       Simple query to get all users from your (sub)organization (in case you are an organization owner, you can get all users from all suborganizations). 
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {}
    }
    EOF
    
    
       Query to get a specific user 
    JSONObject data = client.get("user", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "id" , "< your user id >"
        )
      ));
    
    
       Query to get a specific user 
    dynamic query = new ExpandoObject();
    query.where = new {
          id = "< your user id >"
        };
    
    dynamic data = client.get("user",     query);
    
    
       Query to get a specific user 
    client.get('user', {
        where: {
            id: '< your user id >'
        }
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Query to get a specific user 
    <?php
    $user = $client->get('user', 
      array (
        'where' => array (
          'id' => '< your user id >'
        )
      ));
    
    ?>
    
       Query to get a specific user 
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "id": "< your user id >"
      }
    }
    }
    EOF
    
    
       Query to get a specific user 
    data = client.get("user", {
        "where": {
          "id": "< your user id >"
        }
    })
    
    
       Example query that returns all securables (dashboard or dataset) that a specific user has access to either via a group or directly 
    JSONObject data = client.get("user", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "id" , "< your user id >"
        ),
        "include" , ImmutableList.of(
    
          ImmutableMap.of(
            "model" , "Group",
            "include" , ImmutableList.of(
    
              ImmutableMap.of(
                "model" , "Securable",
                "attributes", ImmutableList.of("id")
              )
            )
          ),
    
          ImmutableMap.of(
            "model" , "Securable",
            "attributes", ImmutableList.of("id")
          )
        ),
        "attributes", ImmutableList.of("id", "name")
      ));
    
    
       Example query that returns all securables (dashboard or dataset) that a specific user has access to either via a group or directly 
    dynamic query = new ExpandoObject();
    query.where = new {
          id = "< your user id >"
        };
    query.include = new List<Object> {
    
          new {
            model = "Group",
            include = new List<Object> {
    
              new {
                model = "Securable",
                attributes = new List<String> {
                  "id"
                }
              }
            }
          },
    
          new {
            model = "Securable",
            attributes = new List<String> {
              "id"
            }
          }
        };
    query.attributes = new List<String> {
      "id", "name"
    };
    
    dynamic data = client.get("user",     query);
    
    
       Example query that returns all securables (dashboard or dataset) that a specific user has access to either via a group or directly 
    client.get('user', {
      where: {
        id: '< your user id >'
      },
      include: [
        {
          model: 'Group',
          include: [
            {
              model: 'Securable',
              attributes: ['id']
            }
          ]
        },
        {
          model: 'Securable',
          attributes: ['id']
        }
      ],
      attributes: ['name', 'id']
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Example query that returns all securables (dashboard or dataset) that a specific user has access to either via a group or directly 
    <?php
    $user = $client->get('user', 
      array (
        'where' => array (
          'id' => '< your user id >'
        ),
        'include' => array (
    
          array (
            'model' => 'Group',
            'include' => array (
    
              array (
                'model' => 'Securable',
                'attributes' => array ( 'id' )
              )
            )
          ),
    
          array (
            'model' => 'Securable',
            'attributes' => array ( 'id' )
          )
        ),
        'attributes' => array ( 'id', 'name' )
      ));
    
    ?>
    
       Example query that returns all securables (dashboard or dataset) that a specific user has access to either via a group or directly 
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "id": "< your user id >"
      },
      "include": [
        {
          "model": "Group",
          "include": [
            {
              "model": "Securable",
              "attributes": ["id"]
            }
          ]
        },
        {
          "model": "Securable",
          "attributes": ["id"]
        }
      ],
      "attributes": ["name", "id"]
    }
    }
    EOF
    
    
       Example query that returns all securables (dashboard or dataset) that a specific user has access to either via a group or directly 
    data = client.get("user", {
        "where": {
          "id": "< your user id >"
        },
        "include": [{
          "model": "group",
          "include": [{
            "model": "securable"
          }]
        },{
          "model": "securable"
        }]
    })
    
    
       Example of the return structure of the query above 
    {
      "count": 1,
      "rows": [
        {
          "email": "test-0d2b5f60@luzmo.com",
          "name": "Mr Unit McTestFace",
          "city": "SmallUnitVille",
          "country_id": null,
          "locale_id": "en",
          "created_at": "2018-08-27T08:27:35.911Z",
          "id": "21f04b48-b5....",
          "groups": [
            {
              "id": "09960f12-a7....",
              "name": null,
              "public": false,
              "created_at": "2018-08-27T08:27:36.250Z",
              "updated_at": "2018-08-27T08:27:36.250Z",
              "groupRole": {
                "flagMember": true,
                "flagOwn": false,
                ...
                "user_id": "21f04b48-b544...",
                "group_id": "09960f12-a71c...."
              },
              "securables": [
                {
                  "id": "26535991-03e7-4fa7-97b6-204752da6cd0",
                  "type": "dataset",
                  ...
                  "groupAccessRight": {
                    "flagRead": true,
                    "flagUse": false,
                    "flagModify": false,
                    "flagOwn": false,
                    "published": false,
                    "filters": null,
                    "created_at": "2018-08-27T08:27:42.121Z",
                    "updated_at": "2018-08-27T08:27:42.121Z",
                    "group_id": "09960f12-a71c-...",
                    "securable_id": "26535991-03e..."
                  }
                }
              ]
            }
          ],
          "securables": [
            {
              "id": "b7864072-ef71-4c8d...",
              "type": "dataset",
              "subtype": "api",
              "name": {
                "en": "SalesProfitCost2004.csv"
              },
              ...
              "userAccessRight": {
                "flagRead": true,
                "flagUse": false,
                ...
              }
            }
          ]
        }
      ]
    }
    
    Get
    can be executed by:
    User Owner
    Organization Member
    List
    can be executed by:
    Organization Member

    A user can list all/specific users of their (sub)organization. For your own user-id, you can use the 'include' syntax to include information on other resources which are connected to your user. Only an organization owner can list all users from all suborganizations.

    Action: Delete

       An organization owner can delete a user using the id 
    client.delete("user", "<a user id>");
    
       An organization owner can delete a user using the id 
    $client->delete("user", "<a user id>");
    
       An organization owner can delete a user using the id 
    let promise = client.delete('user', '<a user id>');
    
       An organization owner can delete a user using the id 
    <?php
    $client->delete('user', '<a user id>');
    ?>
    
       An organization owner can delete a user using the id 
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<a user id>"
    }
    EOF
    
       An organization owner can delete a user using the id 
    client.delete("user", "<your_user_id>")
    
    Delete
    can be executed by:
    Organization Owner

    Delete a user by providing the id of the user.

    Associations

    Users are connected to many resources as can be seen from the partial schema. %3 <!-- Dashboard --> Dashboard Dashboard <!-- Securable --> Securable Securable <!-- Dashboard->Securable --> Dashboard->Securable <!-- Dataset --> Dataset Dataset <!-- Dataset->Securable --> Dataset->Securable <!-- Account --> Account Account <!-- User --> User User <!-- User->Account --> User->Account <!-- Authorization --> Authorization Authorization <!-- User->Authorization --> User->Authorization <!-- Locale --> Locale Locale <!-- User->Locale --> User->Locale <!-- User->Securable --> User->Securable <!-- Country --> Country Country <!-- User->Country --> User->Country <!-- Organization --> Organization Organization <!-- User->Organization --> User->Organization <!-- Thumbnail --> Thumbnail Thumbnail <!-- User->Thumbnail --> User->Thumbnail <!-- Share --> Share Share <!-- User->Share --> User->Share <!-- Group --> Group Group <!-- User->Group --> User->Group <!-- Schedule --> Schedule Schedule <!-- User->Schedule --> User->Schedule <!-- Plugin --> Plugin Plugin <!-- User->Plugin --> User->Plugin

    Associate: Account (implicit)

       Accounts are linked to users on creation 
    JSONObject account = client.create("account",
    
      ImmutableMap.of(
        "provider" , "postgresql",
        "host" , "<host address / ip>",
        "port" , "5432",
        "scope" , "<your database name>",
        "identifier" , "<username>",
        "token" , "<password>"
      ));
    System.out.printf("User id: %s%n", account.get("user_id"));
    
       Accounts are linked to users on creation 
    dynamic properties = new ExpandoObject();
    properties.provider = "postgresql";
    properties.host = "<host address / ip>";
    properties.port = "5432";
    properties.scope = "<your database name>";
    properties.identifier = "<username>";
    properties.token = "<password>";
    
    dynamic account = client.create("account",    properties);
    
     Console.WriteLine("User id is {0}", account["user_id"]);
    
       Accounts are linked to users on creation 
    client.create('account',
      {
        provider: 'postgresql',
        host: '<host address / ip>',
        port: 5432,
        scope: '<your database name>',
        identifier: '<username>',
        token: '<password>'
    })
      .then(function(account) {
        var user = account.user_id;
      });
    
       Accounts are linked to users on creation 
    <?php
    $account = $client->create('account',
    
      array (
        'provider' => 'postgresql',
        'host' => '<host address / ip>',
        'port' => '5432',
        'scope' => '<your database name>',
        'identifier' => '<username>',
        'token' => '<password>'
      )
    
    );
    print( $account['user_id'] );
    ?>
    
       Accounts are linked to users on creation 
    curl https://api.luzmo.com/0.1.0/account  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "provider": "postgresql",
        "host": "<host address / ip>",
        "port": 5432,
        "scope": "<your database name>",
        "identifier": "<username>",
        "token": "<password>"
      } 
    }
    EOF
    # result format of the account contains the user_id 
    {
     ... 
     "user_id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
    User
    Account
    Associate
    requires:
    Account Owner
    and
    User Owner

    This is a special case similar to many entities that are linked to user. The association to the creating user is automatically added when a new account is created.

    Associate: Alert (implicit)

       Alerts are automatically linked to the user on creation time 
    JSONObject account = client.create("alert",
    
      ImmutableMap.of(
        "name" , ImmutableMap.of(
          "en" , "<title of your alert>"
        ),
        "query", ImmutableMap.of(
          "dimensions" , ImmutableList.of(
    
            ImmutableMap.of(
              "dataset_id" , "< Burrito dataset id >",
              "column_id" , "< Type of burrito column id >"
            )
          ),
          "measures" , ImmutableList.of(
    
            ImmutableMap.of(
              "dataset_id" , "< Burrito dataset id >",
              "column_id" , "< Number of burritos column id >",
              "aggregation" , ImmutableMap.of(
                "type" , "sum"
              )
            )
          ),
          "where" , ImmutableList.of(
    
            ImmutableMap.of(
              "expression" , "? in ?",
              "parameters" , ImmutableList.of(
    
                ImmutableMap.of(
                  "dataset_id" , "< Burrito dataset id >",
                  "column_id" , "< Type of burrito column id >"
                ),
                ImmutableList.of("Quesarito", "Chicken baconito")
              )
            )
          ),
          "having", ImmutableList.of(
    
            ImmutableMap.of(
              "expression" , "? >= ?",
              "parameters" , ImmutableList.of(
                ImmutableMap.of(
                  "dataset_id" , "< Burrito dataset id >",
                  "column_id" , "< Sold units column id >"
                  aggregation: {
                    type: 'sum'
                  }
                ),
                10000
              )
            )
          )
        ),
        "frequency", ImmutableMap.of(
          "unit", "day",
          "quantity", 1 
        ),
        "channels, ImmutableList.of(
          ImmutableMap.of(
            "type", "email",
            "config", ImmutableMap.of(
              "recipients", ImmutableList.of(
                "address", "user@organization.com",
                "type", "to",
                "locale", "en"
              ),
              "subject", ImmutableMap.of(
                "en", "Great sales!"
              ),
              "message", ImmutableMap.of(
                "en", "We've done great boys! Check out these numbers!"
              )
            )
          )
        )
      )
    );
    
    
       Alerts are automatically linked to the user on creation time 
    dynamic properties = new ExpandoObject();
    properties.name = new {
      en = "<title of your alert>"
    };
    properties.query = new {
      dimensions = new List<Object> {
        new {
          dataset_id = "< Burrito dataset id >",
          column_id = "< Type of burrito column id >"
        }
      },
      measures = new List<Object> {
        new {
          dataset_id = "< Burrito dataset id >",
          column_id = "< Number of burritos column id >",
          aggregation = new {
            type = "sum"
          }
        }
      },
      where = new List<Object> {
        new {
          expression = "? in ?",
          parameters = new List<Object> {
            new {
              dataset_id = "< Burrito dataset id >",
              column_i = "< Type of burrito column id >"
            },
            new List<Object>{'Quesarito', 'Chicken baconito'}
          }
        }
      },
      having = new List<Object> {
        new {
          expression = "? >= ?",
          parameters = new List<Object> {
            new {
              dataset_id = "< Burrito dataset id >",
              column_id = "< Sold units column id >",
              aggregation = new {
                type = "sum"
              }
            },
            10000
          }
        }
      }
    };
    properties.frequency = new {
      unit = "day",
      quantity = 1
    };
    properties.channels = new List<Object> {
      new {
        type = "email",
        config = new {
          recipients = new List<Object> {
            new {
              address = "user@organization.com",
              type = "to",
              locale = "en"
            }
          },
          subject = new {
            en = "Great sales!"
          },
          message = new {
            en: "We've done great boys! Check out these numbers!"
          }
        }
      }
    };
    
    dynamic alert = client.create("alert", properties);
    
       Alerts are automatically linked to the user on creation time 
    client.create('account',
      {
        name: { en: '<title of your alert>' },
        query: {
        dimensions: [
          {
            dataset_id: '< Burrito dataset id >',
            column_id: '< Type of burrito column id >'
          }
        ],
        measures: [
          {
            dataset_id: '< Burrito dataset id >',
            column_id: '< Number of burritos column id >',
            aggregation: {
              type: 'sum'
            }
          }
        ],
        where: [
          {
            expression: '? in ?',
            parameters: [
              {
                dataset_id: '< Burrito dataset id >',
                column_id: '< Type of burrito column id >'
              },
              ['Quesarito', 'Chicken baconito']
            ]
          }
        ],
        having: [
          {
            expression: '? >= ?',
            parameters: [
              {
                dataset_id: '< Burrito dataset id >',
                column_id: '< Sold units column id >',
                aggregation: {
                  type: 'sum'
                }
              },
              10000
            ]
          }
        ]
      },
        frequency: {
        unit: 'day',
        quantity: 1
      },
      channels: [
        {
          type: 'email',
          config: {
            recipients: [
              {
                address: 'user@organization.com',
                type: 'to',
                locale: 'en'
              }
            ],
            subject: {
              en: 'Great sales!'
            },
            message: {
              en: "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    }
    );
    
       Alerts are automatically linked to the user on creation time 
    <?php
    $alert = $client->create('alert',
      array (
        'name' => array (
          'en' => '<title of your alert>'
        ),
        'query' => array (
          'dimensions' => array (
            array (
              'dataset_id' => '< Burrito dataset id >',
              'column_id' => '< Type of burrito column id >'
            )
          ),
          'measures' => array (
            array (
              'dataset_id' => '< Burrito dataset id >',
              'column_id' => '< Number of burritos column id >',
              'aggregation' => array (
                'type' => 'sum'
              )
            )
          ),
          'where' => array (
            array (
              'expression' => '? in ?',
              'parameters' => array (
                array (
                  'dataset_id' => '< Burrito dataset id >',
                  'column_id' => '< Type of burrito column id >'
                ),
                array ('Quesarito', 'Chicken baconito')
              )
            )
          ),
          'having' => array (
            array (
              'expression' => '? >= ?',
              'parameters' => array (
                array (
                  'dataset_id' => '< Burrito dataset id >',
                  'column_id' => '< Sold units column id >',
                  'aggregation' => array (
                    'type' => 'sum'
                  )
                ),
              10000
              )
            )
          )
        )
        'frequency' => array (
          'unit' => 'day',
          'quantity' => 1
        ),
        'channels' => array (
          array (
            'type' => 'email',
            'config' => array (
              'recipients' => array (
                array (
                  'address' => 'user@organization.com',
                  'type' => 'to',
                  'locale' => 'en'
                )
              ),
              'subject' => array (
                'en' => 'Great sales!'
              ),
              'message' => array (
                'en' => "We've done great boys! Check out these numbers!"
              )
            )
          )
        )
      )
    
    );
    ?>
    
       Alerts are automatically linked to the user on creation time 
    curl https://api.luzmo.com/0.1.0/alert  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "name": { "en": "<title of your alert>" }
      "query": {
        "dimensions": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Type of burrito column id >"
          }
        ],
        "measures": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Number of burritos column id >",
            "aggregation": {
              "type": "sum"
            }
          }
        ],
        "where": [
          {
            "expression": "? in ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Type of burrito column id >"
              },
              ["Quesarito", "Chicken baconito"]
            ]
          }
        ],
        "having": [
          {
            "expression": "? >= ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Sold units column id >",
                "aggregation": {
                  "type": "sum"
                }
              },
              10000
            ]
          }
        ]
      },
      "frequency": { "unit": "day", "quantity": 1 }
      "channels": [
        {
          "type": "email",
          "config": {
            "recipients": [
              {
                "address": "user@organization.com",
                "type": "to",
                "locale": "en"
              }
            ],
            "subject": {
              "en": "Great sales!"
            },
            "message": {
              "en": "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    }
    }
    EOF
    
       Alerts are automatically linked to the user on creation time 
    alert = client.create("alert",
    {
        "name": { "en": "<title of your alert>" }
      "query": {
        "dimensions": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Type of burrito column id >"
          }
        ],
        "measures": [
          {
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Number of burritos column id >",
            "aggregation": {
              "type": "sum"
            }
          }
        ],
        "where": [
          {
            "expression": "? in ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Type of burrito column id >"
              },
              ["Quesarito", "Chicken baconito"]
            ]
          }
        ],
        "having": [
          {
            "expression": "? >= ?",
            "parameters": [
              {
                "dataset_id": "< Burrito dataset id >",
                "column_id": "< Sold units column id >",
                "aggregation": {
                  "type": "sum"
                }
              },
              10000
            ]
          }
        ]
      },
      "frequency": { "unit": "day", "quantity": 1 }
      "channels": [
        {
          "type": "email",
          "config": {
            "recipients": [
              {
                "address": "user@organization.com",
                "type": "to",
                "locale": "en"
              }
            ],
            "subject": {
              "en": "Great sales!"
            },
            "message": {
              "en": "We've done great boys! Check out these numbers!"
            }
          }
        }
      ]
    })
    
    Alert
    User

    The association to the user is created automatically when an alert is made, this association cannot be created manually. The alert will be associated with the user making the request.

    Associate: Authorization (implicit)

       newly created associations are immediately associated with the user that created them, the response contains the user_id, this is the only way to associate users 
    JSONObject authorization = client.create("authorization",
    
      ImmutableMap.of(
        "type" , "temporary",
        "securables" , ImmutableList.of(
          "< dashboard id >"
        )
      ));
    System.out.printf("User id: %s%n", authorization.get("user_id"));
    
       newly created associations are immediately associated with the user that created them, the response contains the user_id, this is the only way to associate users 
    dynamic properties = new ExpandoObject();
    properties.type = "temporary";
    properties.securables = new List<Object> {
          "< dashboard id >"
        };
    
    dynamic authorization = client.create("authorization",    properties);
    
     Console.WriteLine("User id is {0}", authorization["user_id"]);
    
       newly created associations are immediately associated with the user that created them, the response contains the user_id, this is the only way to associate users 
    client.create('authorization',
      {
        type: 'temporary',
        securables: [
            '< dashboard id >'
        ]
    }
    
    )
      .then(function(authorization) {
        var user = authorization.user_id;
      });
    
       newly created associations are immediately associated with the user that created them, the response contains the user_id, this is the only way to associate users 
    <?php
    $authorization = $client->create('authorization',
    
      array (
        'type' => 'temporary',
        'securables' => array (
          '< dashboard id >'
        )
      )
    
    );
    print( $authorization['user_id'] );
    ?>
    
       newly created associations are immediately associated with the user that created them, the response contains the user_id, this is the only way to associate users 
    curl https://api.luzmo.com/0.1.0/authorization  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "type": "temporary",
      "securables": [
        "< dashboard id >"
      ]
    }
    }
    EOF
    # result format of the authorization contains the user_id 
    {
     ... 
     "user_id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
      newly created associations are immediately associated with the user that created them, the response contains the user_id, this is the only way to associate users
    authorization = client.create("authorization",
    {
        "type": "temporary",
        "securables": ["< dashboard id >"]
    })
    print(authorization[user_id])
    
    Authorization
    User
    Associate
    requires:
    Authorization Owner

    When associating authorizations there are two things to keep in mind. First is that authorizations are immutable and thus the 'associate' call cannot be called directly. Secondly, the link between authorizations and users is implicit, while you can associate in the 'create' action as well, this is not possible for users. Authorizations are associated automatically. to the user who created them, you will never call the 'associate' call directly and cannot associate them to someone else than the creator.

    Associate: Country

       Set the country of residence for a user 
    client.associate("country", "<your country id>", "Users", "< your user id>");
    
       Set the country of residence for a user 
    
    client.associate("country", "<your country id>", "Users", "< your user id>");
    
       Set the country of residence for a user 
    let promise = client.associate('country', '<your country id>', {
        role: 'Users',
        id: '< your user id>'
    });
    
       Set the country of residence for a user 
    <?php
    $client->associate('country', '<your country id>', 'Users', '< your user id>', );
    ?>
    
       Set the country of residence for a user 
    curl https://api.luzmo.com/0.1.0/country  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your country id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      }
    }
    EOF
    
       Set the country of residence for a user 
    client.associate("country", "<your_country_id>", {"role":"Users","id":"< your user id>"})
    
    User
    Country
    Associate
    requires:
    Logged-in User
    and
    User Owner

    Users can be associated to countries. This simply informs the platform on the country of residence of the user. Countries can also be associated to organizations which serve as a default for the users of that organization. Just like locale, a country associated with user directly will take priority.

    Associate: Dashboard

       Link a user to a dashboard in order to make that dashboard readable by the user 
    client.associate("securable", "< your dashboard id >", "Users", "< a user id >", 
      ImmutableMap.of(
        "flagRead" , true
      ) );
    
       Link a user to a dashboard in order to make that dashboard readable by the user 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    
    client.associate("securable", "< your dashboard id >", "Users", "< a user id >",     properties );
    
       Link a user to a dashboard in order to make that dashboard readable by the user 
    let promise = client.associate('securable', '< your dashboard id >', {
        role: 'Users',
        id: '< a user id >'
    },
    {
        flagRead: true
    });
    
       Link a user to a dashboard in order to make that dashboard readable by the user 
    <?php
    $client->associate('securable', '< your dashboard id >', 'Users', '< a user id >', , 
      array (
        'flagRead' => true
      ) );
    ?>
    
       Link a user to a dashboard in order to make that dashboard readable by the user 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "< your dashboard id >",
      "resource": {
        "role": "Users",
        "id": "< a user id >"
      },
      "properties": {
        "flagRead": true
      }
    }
    EOF
    
       Link a user to a dashboard in order to make that dashboard readable by the user 
    client.associate("securable", "< your dashboard id >", {"role":"Users","id":"< a user id >"}, {
        "flagRead": True
    } )
    
       Link a user to a dashboard and give him all the rights (making him also owner of the dashboard) 
    client.associate("securable", "< your dashboard id >", "Users", "< a user id >", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagOwn" , true,
        "flagUse" , true,
        "flagModify" , true
      ) );
    
       Link a user to a dashboard and give him all the rights (making him also owner of the dashboard) 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagOwn = true;
    properties.flagUse = true;
    properties.flagModify = true;
    
    client.associate("securable", "< your dashboard id >", "Users", "< a user id >",     properties );
    
       Link a user to a dashboard and give him all the rights (making him also owner of the dashboard) 
    let promise = client.associate('securable', '< your dashboard id >', {
        role: 'Users',
        id: '< a user id >'
    },
    {
        flagRead: true,
        flagOwn: true,
        flagUse: true,
        flagModify: true
    });
    
       Link a user to a dashboard and give him all the rights (making him also owner of the dashboard) 
    <?php
    $client->associate('securable', '< your dashboard id >', 'Users', '< a user id >', , 
      array (
        'flagRead' => true,
        'flagOwn' => true,
        'flagUse' => true,
        'flagModify' => true
      ) );
    ?>
    
       Link a user to a dashboard and give him all the rights (making him also owner of the dashboard) 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "< your dashboard id >",
      "resource": {
        "role": "Users",
        "id": "< a user id >"
      },
        "properties": {
        "flagRead": true,
        "flagOwn": true,
        "flagUse": true,
        "flagModify": true
      }
    }
    EOF
    
       Link a user to a dashboard and give him all the rights (making him also owner of the dashboard) 
    client.associate("securable", "< your dashboard id >", {"role":"Users","id":"< a user id >"}, {
        "flagRead": True,
        "flagOwn": True,
        "flagUse": True,
        "flagModify": True
    } )
    
    User
    Securable
    flagRead
    Grant the right to view the dashboard
    flagUse
    Right requires for example to duplicate the dashboard
    flagModify
    Right to modify the dashboard
    flagOwn
    Right to delete the dashboard, or to modify the access rights e.g. by associating the dashboard with users (multiple users can be owner)
    Associate
    requires:
    Securable Owner
    and
    Logged-in User

    A user can be linked to a dashboard to give him access to that dashboard. To start associating, note that a dashboard is a subclass of securable so we use securable in the calls. The association has flag properties to define what kind of access the user will receive. In order to start associating dashboards with users, you already need to be resource owner of the dashboard. That means that you either created the dashboard or received access from someone that associated you with the dashboard using the flagOwn = true property. That way it is possible to set multiple owners for a dashboard.

    Associate: Dataset

       Link a user to a dataset in order to make that dataset readable by the user 
    client.associate("securable", "<your securable id>", "Users", "< your user id>", 
      ImmutableMap.of(
        "flagRead" , true
      ));
    
       Link a user to a dataset in order to make that dataset readable by the user 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    
    client.associate("securable", "<your securable id>", "Users", "< your user id>",     properties );
    
       Link a user to a dataset in order to make that dataset readable by the user 
    let promise = client.associate('securable', '<your securable id>', {
        role: 'Users',
        id: '< your user id>'
    },
    {
        flagRead: true
    });
    
       Link a user to a dataset in order to make that dataset readable by the user 
    <?php
    $client->associate('securable', '<your securable id>', 'Users', '< your user id>', , 
      array (
        'flagRead' => true
      ));
    ?>
    
       Link a user to a dataset in order to make that dataset readable by the user 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      },
      "properties": {
        "flagRead": true
      }
    }
    EOF
    
       Link a user to a dataset in order to make that dataset readable by the user 
    client.associate("securable", "<your_securable_id>", {"role":"Users","id":"< your user id>"}, {
        "flagRead": True
    } )
    
       Link a user to a dataset and give him all the rights (making him also owner of the dataset) 
    client.associate("securable", "<your securable id>", "Users", "< your user id>", 
      ImmutableMap.of(
        "flagRead" , true,
        "flagOwn" , true,
        "flagUse" , true,
        "flagModify" , true
      ));
    
       Link a user to a dataset and give him all the rights (making him also owner of the dataset) 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagOwn = true;
    properties.flagUse = true;
    properties.flagModify = true;
    
    client.associate("securable", "<your securable id>", "Users", "< your user id>",     properties );
    
       Link a user to a dataset and give him all the rights (making him also owner of the dataset) 
    let promise = client.associate('securable', '<your securable id>', {
        role: 'Users',
        id: '< your user id>'
    },
    {
        flagRead: true,
        flagOwn: true,
        flagUse: true,
        flagModify: true
    });
    
       Link a user to a dataset and give him all the rights (making him also owner of the dataset) 
    <?php
    $client->associate('securable', '<your securable id>', 'Users', '< your user id>', , 
      array (
        'flagRead' => true,
        'flagOwn' => true,
        'flagUse' => true,
        'flagModify' => true
      ));
    ?>
    
       Link a user to a dataset and give him all the rights (making him also owner of the dataset) 
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      },
      "properties": {
        "flagRead": true,
        "flagOwn": true,
        "flagUse": true,
        "flagModify": true
      }
    }
    EOF
    
       Link a user to a dataset and give him all the rights (making him also owner of the dataset) 
    client.associate("securable", "<your_securable_id>", {"role":"Users","id":"< your user id>"}, {
        "flagRead": True,
        "flagOwn": True,
        "flagUse": True,
        "flagModify": True
    } )
    
       Link a user to a dataset, give him use rights and apply some filters 
    client.associate("securable", "<your securable id>", "Users", "< your user id>", 
      ImmutableMap.of(
        "flagRead", true,
        "flagUse" , true,
        "filters", ImmutableList.of(
          ImmutableMap.of(
            "clause", "where",
            "origin", "global",
            "securable_id", "< dataset id >",
            "column_id", "< column id of a column in the dataset >",
            "expression", "? = ?",
            "value", "< value to be applied to the expression >"
          )
        )
      ) 
    );
    
       Link a user to a dataset, give him use rights and apply some filters 
    dynamic properties = new ExpandoObject();
    properties.flagRead = true;
    properties.flagUse = true;
    
    properties.filters = new List<dynamic> {
      new {  
        clause = "where";
        origin = "global";
        securable_id = "< dataset id >";
        column_id = "< column id of a column in the dataset >";
        expression = "? = ?";
        value = "< value to be applied to the expression >";
      }
    };
    
    client.associate("securable", "<your securable id>", "Users", "< your user id>",   properties );
    
       Link a user to a dataset, give him use rights and apply some filters
    let promise = client.associate('securable', '<your securable id>', {
      role: 'Users',
      id: '< your user id>'
    },
    {
      flagRead: true,
      flagUse: true,
      filters: [
        {
          clause: 'where',
          origin: 'global',
          securable_id: '< dataset id >',
          column_id: '< column id of a column used in the dataset >',  
          expression: '? = ?',
          value: '< value to be applied to the expression >'
        }  
      ]
    });
    
       Link a user to a dataset, give him use rights and apply some filters 
    <?php
    $client->associate('securable', '<your securable id>', 'Users', '< your user id>', , 
      array (
        'flagRead' => true,
        'flagUse' => true,
        'filters' => array(
          'clause'       => 'where',
          'origin'       => 'global',
          'securable_id' => '< dataset id >',
          'column_id'    => '< column id of a column used in the dataset >',
          'expression'   => '? = ?',
          'value'        => '< value to be applied to the expression >'
        )
      ) );
    ?>
    
       Link a user to a dataset, give him use rights and apply some filters
    curl https://api.luzmo.com/0.1.0/securable  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your securable id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      },
      "properties": {
        "flagRead": true,
        "flagUse": true,
        "filters": [
            {
              "clause": "where",
              "origin": "global",
              "securable_id": "< dataset id >",
              "column_id": "< column id of a column used in the dataset >",  
              "expression": "? = ?",
              "value": "< value to be applied to the expression >"
            }
          ]
      }
    }
    EOF
    
    User
    Securable
    flagRead
    Grant the right to query the dataset
    flagUse
    Right required to use the dataset in the dashboard editor to create dashboards with it
    flagModify
    Right to modify the dataset, e.g. add a derived column
    flagOwn
    Right to delete the dataset, or to modify the access rights e.g. by associating the dataset with users (multiple users can be owner)
    Associate
    requires:
    Securable Owner
    and
    Logged-in User

    A user can be linked to a securable to give him access to that dataset. To start associating, note that a dataset is a subclass of securable so we use securable in the calls. The association has flag properties to define what kind of access the user will receive. In order to start associating dashboards with users, you already need to be resource owner. That means that you either created the dashboard or received access from someone that associated you with the dashboard using the flagOwn = true property. That way it is possible to set multiple owners for a dataset. In addition to setting ownership properties, you can supply filters when associating a dataset to a user. When a user opens or uses the dataset, these filters will be applied. The syntax is identical to creating an authorization with filters.

    Associate: Group

       Link a user to a group and set him as member of that group 
    client.associate("group", "<your group id>", "Users", "< your user id>", 
      ImmutableMap.of(
        "flagMember" , true,
        "flagOwn" , false
      ));
    
       Link a user to a group and set him as member of that group 
    dynamic properties = new ExpandoObject();
    properties.flagMember = true;
    properties.flagOwn = false;
    
    client.associate("group", "<your group id>", "Users", "< your user id>",     properties );
    
       Link a user to a group and set him as member of that group 
    let promise = client.associate('group', '<your group id>', {
        role: 'Users',
        id: '< your user id>'
    },
    {
        flagMember: true,
        flagOwn: false
    });
    
       Link a user to a group and set him as member of that group 
    <?php
    $client->associate('group', '<your group id>', 'Users', '< your user id>', , 
      array (
        'flagMember' => true,
        'flagOwn' => false
      ) );
    ?>
    
       Link a user to a group and set him as member of that group 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      },
      "properties": {
        "flagMember": true,
        "flagOwn": false
      }
    }
    EOF
    
       Link a user to a group and set him as member of that group 
    client.associate("group", "<your_group_id>", {"role":"Users","id":"< your user id>"}, {
        "flagMember": True,
        "flagOwn": False
    } )
    
    User
    Group
    flagMember
    Make the user member of the group
    flagOwn
    Make the user owner of the group (there can be multiple owners)
    Associate
    requires:
    Group Owner
    and
    Logged-in User

    Groups can be used to give a group of users access to securables (dashboards or datasets). When associating a user with a group there are flags available that describe the kind of relation. Adding a user in a group without setting any flags will not have any effect. Only the owner of a group can add members to the group. The user who created the group automatically becomes an owner of the group.

    Associate: Integration

       Link a User to an Integration. 
    client.associate("integration", "<your_integration_id>", "Users", "<user_id>");
    
       Link a User to an Integration. 
    client.associate("integration", "<your_integration_id>", "Users", "<user_id>" );
    
       Link a User to an Integration. 
    let promise = client.associate('integration', '<your_integration_id>', {
        role: 'Users',
        id: '<user_id>'
    });
    
       Link a User to an Integration. 
    <?php
    $client->associate('integration', '<your_integration_id>', 'Users', '<user_id>');
    ?>
    
       Link a User to an Integration. 
    curl https://api.luzmo.com/0.1.0/integration \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your_integration_id>",
      "resource": {
        "role": "Users",
        "id": "<user_id>"
      }
    }
    EOF
    
       Link a User to an Integration. 
    client.associate("integration", "<your_integration_id>", {"role": "Users", "id": "<user_id>"})
    
    Integration
    Users
    Associate
    requires:
    User Owner

    Sharing an Integration with a user can be done by associating the Integration with that user.

    Associate: Locale

       Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. 
    client.associate("locale", "<your locale id>", "Users", "< your user id>");
    
       Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. 
    
    client.associate("locale", "<your locale id>", "Users", "< your user id>");
    
       Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. 
    let promise = client.associate('locale', '<your locale id>', {
        role: 'Users',
        id: '< your user id>'
    });
    
       Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. 
    <?php
      $client->associate('locale', '<your locale id>', 'Users', '< your user id>', );
    ?>
    
       Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. 
    curl https://api.luzmo.com/0.1.0/locale  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your locale id>",
      "resource": {
        "role": "Users",
        "id": "< your user id>"
      }
    }
    EOF
    
       Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. 
    client.associate("locale", "<your_locale_id>", {"role":"Users","id":"< your user id>"})
    
    User
    Locale
    Associate
    requires:
    User Owner
    and
    Logged-in User

    Set the default language (locale) of the user. Datasets and dashboards will initially open with this selected language. The locale of the user needs to be changed by the entity owner. If you need to set the locale manually for each user you can use the login token when you created them to fetch an API token and set the locale for him.

    Associate: Organization

       Example of creating a technical user. Make sure it is added to the correct organization by using the API token of an organization owner which has access to your organization's resources 
    JSONObject user = client.create("user",
    
      ImmutableMap.of(
        "name" , "New user of my organization",
        "email" , "user@organization.com",
        "password" , "... random password ..."
      ));
    System.out.println("Success! %s%n", user);
    
       Example of creating a technical user. Make sure it is added to the correct organization by using the API token of an organization owner which has access to your organization's resources 
    dynamic properties = new ExpandoObject();
    properties.name = "New user of my organization";
    properties.email = "user@organization.com";
    properties.password = "... random password ...";
    
    dynamic user = client.create("user",    properties);
    Console.WriteLine("Success!", user);
    
       Example of creating a technical user. Make sure it is added to the correct organization by using the API token of an organization owner which has access to your organization's resources 
    client.create('user',
      {
        name: 'New user of my organization',
        email: 'user@organization.com',
        password: '... random password ...'
    })
      .then(function(user) {
        console.log('Success!', user);
      });
    
       Example of creating a technical user. Make sure it is added to the correct organization by using the API token of an organization owner which has access to your organization's resources 
    <?php
    $user = $client->create('user',
    
      array (
        'name' => 'New user of my organization',
        'email' => 'user@organization.com',
        'password' => '... random password ...'
      )
    );
    print("Success! { $user }");
    ?>
    
       Example of creating a technical user. Make sure it is added to the correct organization by using the API token of an organization owner which has access to your organization's resources 
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "name": "New user of my organization",
        "email": "user@organization.com",
        "password": "... random password ..."
      }
    }
    EOF
    
    
       Example of the creation of a 'user' resource. If no invite code is provided this will also create a new organization 
    user = client.create("user",
    {
        "email": "example@luzmo.com",
        "password": "your-password",
        "name": "Sam Examplius"
    })
    print("Success! ", user)
    
    User
    Organization
    flagMember
    Grant the right to view accessible dashboards
    flagEditor
    Right to create or edit dashboards
    flagAdmin
    Right to view, edit, share, and delete all securables within the organization and suborganization(s).
    flagOwn
    Right to manage the organization (e.g. add/update org members, plan & billing info, etc.), create Integrations, save Organization themes, etc.
      Example of changing the user role to role 'admin' (Only organization owners can create or update users)
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "version": "0.1.0",
      "action": "associate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN"
      "id": "< user id >",
      "resource": {
        "role": "Organizations",
        "id": "< organization id >"
      },
      "properties": {
        "flagMember": true,
        "flagEditor": true,
        "flagAdmin": true,
        "flagOwn": false
      }
    }
    EOF
    
    
      Example of changing the user role, Only organization owner can update the user role
    client.associate(
        'user',
        <user id to update>,
        { role: 'Organizations', id: <your organzation id> },
        { flagAdmin: true, flagEditor: true, flagMember: true, flagOwn: false }
      )
    .then(function(user) {
      console.log('Success!', user);
    });
    
      Example of changing the user role, Only organization owner can update the user role 
    client.associate("user", "<user id to update>", "Organizations", "< your organization id>", 
      ImmutableMap.of(
        "flagMember" , true,
        "flagEditor" , true,
        "flagAdmin" , true,
        "flagOwn" , false
      ));
    
      Example of changing the user role, Only organization owner can update the user role 
    dynamic properties = new ExpandoObject();
    properties.flagMember = true;
    properties.flagOwn = false;
    properties.flagAdmin = true;
    properties.flagAEditor = true;
    
    client.associate("user", "<your user id>", "Organizations", "< your organization id>",     properties );
    
      Example of changing the user role, Only organization owner can update the user role 
    <?php
    $client->associate('user', '<your user id>', 'Organizations', '< your organization id>', , 
      array (
        'flagMember' => true,
        'flagEditor' => true,
        'flagAdmin' => true,
        'flagOwn' => false
      ) );
    ?>
    
      Example of changing the user role, Only organization owner can update the user role  
    client.associate("user", "<your_user_id>", {"role":"Organizations","id":"< your organization id>"}, {
        "flagMember": True,
        "flagEditor": True,
        "flagAdmin": True,
        "flagOwn": False
    } )
    

    The link between Organizations and Users is a special case: you can't add users to an organization once the users are made. If you use an owner's API token to create a user, the association between the organization and user will be made implicitly (i.e. the only way to add users to an organization is on creation time). If no API token is provided, the user will be added to a new organization.

    To change the role of an existing user in your main organization, you need to use the API key-token pair from an organization owner, and set the desired flag(s) to true on the user-organization association.

    Associate: Plugin (implicit)

       A plugin is automatically bound to the creating user on creation, that user is the Entity Owner and is the only one who can change the plugin 
    JSONObject plugin = client.create("plugin",
    
      ImmutableMap.of(
        "slug" , "myplugin",
        "name" , ImmutableMap.of(
          "en" , "My Internal Api Plugin"
        ),
        "description" , ImmutableMap.of(
          "en" , "Since we already have an API, we wrote a simple plugin around our API"
        ),
        "base_url" , "https://my-company.com/data/api/v1",
        "url" , "https://my-company.com/info",
        "secret" , "<luzmo-secret>",
        "authorize" , "token",
        "color" , "#00FF00",
        "pushdown" , false
      ));
    System.out.printf("User id: %s%n", plugin.get("user_id"));
    
       A plugin is automatically bound to the creating user on creation, that user is the Entity Owner and is the only one who can change the plugin 
    dynamic properties = new ExpandoObject();
    properties.slug = "myplugin";
    properties.name = new {
          en = "My Internal Api Plugin"
        };
    properties.description = new {
          en = "Since we already have an API, we wrote a simple plugin around our API"
        };
    properties.base_url = "https://my-company.com/data/api/v1";
    properties.url = "https://my-company.com/info";
    properties.secret = "<luzmo-secret>";
    properties.authorize = "token";
    properties.color = "#00FF00";
    properties.pushdown = false;
    
    dynamic plugin = client.create("plugin",    properties);
    
     Console.WriteLine("User id is {0}", plugin["user_id"]);
    
       A plugin is automatically bound to the creating user on creation, that user is the Entity Owner and is the only one who can change the plugin 
    client.create('plugin', {
      slug: 'myplugin',
      name: {
        en: 'My Internal Api Plugin'
      },
      description: {
        en: 'Since we already have an API, we wrote a simple plugin around our API'
      },
      base_url: 'https://my-company.com/data/api/v1',
      url: 'https://my-company.com/info',
      secret: '<luzmo-secret>',
      authorize: 'token',
      color: '#00FF00',
      pushdown: false
    })
      .then(function(plugin) {
        var user = plugin.user_id;
      });
    
       A plugin is automatically bound to the creating user on creation, that user is the Entity Owner and is the only one who can change the plugin 
    <?php
    $plugin = $client->create('plugin',
    
      array (
        'slug' => 'myplugin',
        'name' => array (
          'en' => 'My Internal Api Plugin'
        ),
        'description' => array (
          'en' => 'Since we already have an API, we wrote a simple plugin around our API'
        ),
        'base_url' => 'https://my-company.com/data/api/v1',
        'url' => 'https://my-company.com/info',
        'secret' => '<luzmo-secret>',
        'authorize' => 'token',
        'color' => '#00FF00',
        'pushdown' => false
      )
    
    );
    print( $plugin['user_id'] );
    ?>
    
       A plugin is automatically bound to the creating user on creation, that user is the Entity Owner and is the only one who can change the plugin 
    curl https://api.luzmo.com/0.1.0/plugin  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "slug": "myplugin",
        "name": {
          "en": "My Internal Api Plugin"
        },
        "description": {
          "en": "Since we already have an API, we wrote a simple plugin around our API"
        },
        "base_url": "https://my-company.com/data/api/v1",
        "url": "https://my-company.com/info",
        "secret": "<luzmo-secret>",
        "authorize": "token",
        "color": "#00FF00",
        "pushdown": false
      }
    }
    EOF
    # result format of the plugin contains the user_id 
    {
     ... 
     "user_id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
       A plugin is automatically bound to the creating user on creation, that user is the Entity Owner and is the only one who can change the plugin 
    plugin = client.create("plugin",
    {
        "slug": "myplugin",
        "name": {
          "en": "My Internal Api Plugin"
        },
        "description": {
          "en": "Since we already have an API, we wrote a simple plugin around our API"
        },
        "base_url": "https://my-company.com/data/api/v1",
        "url": "https://my-company.com/info",
        "secret": "<luzmo-secret>",
        "authorize": "token",
        "color": "#00FF00",
        "pushdown": False
    })
    user = plugin["user_id"]
    
    User
    Plugin

    This is a special case similar to many entities that are linked to user. The association to the creating user is automatically added when a plugin is created, this association cannot be created manually. The user that created the schedule is the owner of the Plugin and the only one who can manipulate the plugin.

    Associate: Schedule (implicit)

       Schedules are automatically linked to the user who created them 
    JSONObject schedule = client.create("schedule",
    
      ImmutableMap.of(
        "type" , "dataset",
        "started_at" , "startDate",
        "frequency" , "1440",
        "scheduled_at" , new Date();,
        "completed_at" , new Date();,
        "active" , true
      ));
    System.out.printf("User id: %s%n", schedule.get("user_id"));
    
       Schedules are automatically linked to the user who created them 
    dynamic properties = new ExpandoObject();
    properties.type = "dataset";
    properties.started_at = "startDate";
    properties.frequency = "1440";
    properties.scheduled_at = DateTime.UtcNow;
    properties.completed_at = DateTime.UtcNow;
    properties.active = true;
    
    dynamic schedule = client.create("schedule",    properties);
    
     Console.WriteLine("User id is {0}", schedule["user_id"]);
    
       Schedules are automatically linked to the user who created them 
    client.create('schedule', {
      type: 'dataset',
      started_at: 'startDate',
      frequency: 1440,
      scheduled_at: new Date(),
      completed_at: '<!new Date()!>',
      active: true
    })
      .then(function(schedule) {
        var user = schedule.user_id;
      });
    
       Schedules are automatically linked to the user who created them 
    <?php
    $schedule = $client->create('schedule',
    
      array (
        'type' => 'dataset',
        'started_at' => 'startDate',
        'frequency' => '1440',
        'scheduled_at' => date("Y-m-d H:i:s"),
        'completed_at' => date("Y-m-d H:i:s"),
        'active' => true
      )
    
    );
    print( $schedule['user_id'] );
    ?>
    
       Schedules are automatically linked to the user who created them 
    curl https://api.luzmo.com/0.1.0/schedule  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "type": "dataset",
        "started_at": "startDate",
        "frequency": 1440,
        "scheduled_at": "2017-08-30T14:30:15Z",
        "completed_at": "2017-08-30T14:30:15Z",
        "active": true
      }
    }
    EOF
    # result format of the schedule contains the user_id 
    {
     ... 
     "user_id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
       Create a scheduled (daily = 24 * 60) pdf export that will be sent to e-mail 
    export = client.create("export",
    {
        "securable_id": " < your dataset id >",
        "type": "pdf",
        "schedule": {
          "frequency": 1440,
          "start_date": "2018-09-03T12:16:59Z"
        },
        "emails": ["testexport@luzmo.com"]
    })
    print("Success! ", export)
    
    User
    Schedule

    This is a special case similar to many entities that are linked to user. The association to the creating user is created automatically when a schedule is made, this association cannot be created manually. The user that created the schedule is the only one who can get, delete, update, associate or dissociate this schedule

    Associate: Share (implicit)

    User
    Share
       Shares don't require parameters and are immediately linked to a user on creation 
    JSONObject share = client.create("share",
    
      ImmutableMap.of(
    
      ));
    System.out.printf("User id: %s%n", share.get("user_id"));
    
       Shares don't require parameters and are immediately linked to a user on creation 
    dynamic properties = new ExpandoObject();
    
    dynamic share = client.create("share",    properties);
    
     Console.WriteLine("User id is {0}", share["user_id"]);
    
       Shares don't require parameters and are immediately linked to a user on creation 
    client.create('share', {})
      .then(function(share) {
        var user = share.user_id;
      });
    
       Shares don't require parameters and are immediately linked to a user on creation 
    <?php
    $share = $client->create('share',
    
      array (
    
      )
    
    );
    print( $share['user_id'] );
    ?>
    
       Shares don't require parameters and are immediately linked to a user on creation 
    curl https://api.luzmo.com/0.1.0/share  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {}
    }
    EOF
    # result format of the share contains the user_id 
    {
     ... 
     "user_id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
       Shares don't require parameters and are immediately linked to a user on creation 
    share = client.create("share",
    {
    
    })
    user = share["user_id"]
    

    This is a special case similar to many entities that are linked to user. When creating a private link to a dashboard, the creating user is automatically linked to the Share. Note that the code on the right only creates a link which is not yet linked to a dashboard.

    Dissociate

       Example query that removes a user from a group 
    client.dissociate("user", "<your user id>", "Groups", "<group id>");
    
       Example query that removes a user from a group 
    client.dissociate("user", "<your user id>", "Groups", "<group id>");
    
       Example query that removes a user from a group 
    let promise = client.dissociate('user', '<your user id>', {
        role: 'Groups',
        id: '<group id>'
    });
    
       Example query that removes a user from a group 
    <?php
    $client->associate('user', '<your user id>', "Groups", "<group id>");
    ?>
    
       Example query that removes a user from a group 
    curl https://api.luzmo.com/0.1.0/user  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your user id>",
      "resource": {
      "role": "Groups",
      "id": "<group id>"
    }
    }
    EOF
    
       Example query that removes a user from a group 
    client.dissociate("user", "<your_user_id>", {"role":"Groups","id":"<group id>"})
    
       Example query that removes a user from a group 
    client.dissociate("group", "<your group id>", "Users", "<user id>");
    
       Example query that removes a user from a group 
    client.dissociate("group", "<your group id>", "Users", "<user id>");
    
       Example query that removes a user from a group 
    let promise = client.dissociate('group', '<your group id>', {
        role: 'Users',
        id: '<user id>'
    });
    
       Example query that removes a user from a group 
    <?php
    $client->associate('group', '<your group id>', "Users", "<user id>");
    ?>
    
       Example query that removes a user from a group 
    curl https://api.luzmo.com/0.1.0/group  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "dissociate",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your group id>",
      "resource": {
      "role": "Users",
      "id": "<user id>"
    }
    }
    EOF
    

    Dissociating is similar for all resources. To break the link between two resources, simply provide the resource names and ids. Be careful that the 'role' of a resource is uppercase and usually plural. Dissociating can be done in both directions.

    Services

    Services are slightly different than resources in the sense that you can not associate anything to them. They either do exports, push data or perform a certain action. For example:

    These services do not follow the same conventions as the other resources and will only support a small subset of the actions.

    AI Chart

    Retrieve AI-generated chart suggestions based on the structure of a specified dataset and optionally a user-specified prompt.

    Find potential use cases on our blog.

    The chart generator can currently create charts of the following types: areachart, barchart, bubblechart, circlepack, columnchart, donut, linechart, number, pivottable, regulartable, scatterplot, sunburst and treemap and filters of the following types: datefilter, selectbox, slicer and slider. The generator can suggest chart types automatically based on the context or you can guide it to a particular type. Chart option support is continuously expanding.

    Properties

    Parameter
    Description
    dataset_id
    uuid
    (Required) ID of the dataset for which to generate a new chart
    type
    string
    (Required) Type of AI recommendation. Can be either generate-chart or generate-example-questions.
    question
    string
    (Required for type generate-chart) User prompt to guide the recommendations. This can be a question, a sentence or a few keywords.
    message_history
    array[string]
    Optional history of the conversation, not including the latest question.

    Actions

    Create

    Action: Create

    JSONObject chart = client.create("aichart",
      ImmutableMap.of(
        "type" , "generate-chart",
        "dataset_id" , "<dataset ID>",
        "question" , "Visualize revenue by year"
      )
    );
    System.out.printf("Chart: %s%n", chart);
    
    dynamic properties = new ExpandoObject();
    properties.type = "generate-chart";
    properties.dataset_id = "<dataset ID>";
    properties.question = "Visualize revenue by year";
    
    dynamic chart = client.create("aichart", properties);
    
     Console.WriteLine("Chart id is {0}", account["id"]);
    
    const chart = await client.create('aichart', {
      type: 'generate-chart',
        dataset_id: '<dataset ID>',
        question: 'Visualize revenue by year'
    });
    console.log(chart);
    
    <?php
    $chart = $client->create('aichart',
      array (
        'type' => 'generate-chart',
        'dataset_id' => '<dataset ID>',
        'question' => 'Visualize revenue by year'
      )
    );
    print( $chart );
    ?>
    
    curl https://api.luzmo.com/0.1.0/aichart  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
        "type": "generate-chart",
        "dataset_id": "<dataset ID>",
        "question": "Visualize revenue by year"
      }
    }
    EOF
    
    chart = client.create("aichart",
    {
        "dataset_id": "<dataset ID>",
        "type": "generate-chart",
        "question": "Visualize revenue by year"
    })
    id = chart["id"]
    
    Create
    can be executed by:
    Securable User

    Data

    The data endpoint is rather a service than a resource. This endpoint can be used to add data to a dataset, or query a certain dataset, more examples can be found here. There is a guide explaining how to create datasets and push data to them as well: Interacting with data. In order to push data, you first need to create a Dataset and associate Columns with the dataset. After that you can push data to the dataset. Make sure the datastructure corresponds with the associated columns.

    Properties

    Parameter
    Description
    securable_id
    uuid
    Unique key of the securable to push data to. This parameter is required when appending or replacing data and should be left out when creating a new dataset
    data
    array of arrays
    List of data rows to append to the securable. Each data row must be an Array with column values. If omitted, an update of open dashboards will still be triggered, eg. if you are using data via a data provider.
    options
    object
    type
    string
    Either create/append/replace. Append adds new data to an existing securable in which case the rows will be added. Replace completely replaced all rows with the new rows. Create makes it possible to create a dataset from scratch by providing only the data, a header and the dataset name. Types will be automatically detected from the sample dataset (make sure it is a relevant example an does not contain a column full of null values).
    update_metadata
    boolean
    Enabling this parameter allows you to add/delete/update columns of the dataset (based on the header and the detection from the sample) and update the name of the dataset. Use it with care
    header
    array of strings
    The header allows you to provide names for your columns when you create the dataset or when creating new columns (with update_metadata). Besides of that it allows you to send the data in another order. The column order of the data will be automatically detected based on the header.
    name
    object
    localized object to provide the name on creation of the dataset or when updating the metadata

    Actions

    The data endpoint supports the create, get and update actions.

    Create
    Update
    Get

    Action: Create

       Example of uploading data and creating the dataset + columns on the fly by detecting types from the sample 
    JSONObject data = client.create("data",
    
      ImmutableMap.of(
        "type" , "create",
        "data" , ImmutableList.of(
    
          ImmutableList.of(
            "Chicken baconito ",
            "3",
            "500",
            "menu"
          ),
    
          ImmutableList.of(
            "Quesarito",
            "3.5",
            "700",
            "menu"
          )
        ),
        "options" , ImmutableMap.of(
          "update_metadata" , true,
          "header" , ImmutableList.of(
            "Burrito",
            "price",
            "weight",
            "order type"
          ),
          "name" , ImmutableMap.of(
            "en" , "Burritos"
          )
        )
      ));
    System.out.println("Success! %s%n", data);
    
       Example of uploading data and creating the dataset + columns on the fly by detecting types from the sample 
    dynamic properties = new ExpandoObject();
    properties.type = "create";
    properties.data = new List<Object> {
    
          new List<Object> {
            "Chicken baconito ",
            "3",
            "500",
            "menu"
          },
    
          new List<Object> {
            "Quesarito",
            "3.5",
            "700",
            "menu"
          }
        };
    properties.options = new {
          update_metadata = true,
          header = new List<Object> {
            "Burrito",
            "price",
            "weight",
            "order type"
          },
          name = new {
            en = "Burritos"
          }
        };
    
    dynamic data = client.create("data",    properties);
    Console.WriteLine("Success!", data);
    
       Example of uploading data and creating the dataset + columns on the fly by detecting types from the sample 
    client.create('data',
      {
        type: 'create',
        data: [
            [
                'Chicken baconito ',
                3,
                500,
                'menu'
            ],
            [
                'Quesarito',
                3.5,
                700,
                'menu'
            ]
        ],
        options: {
            update_metadata: true,
            header: [
                'Burrito',
                'price',
                'weight',
                'order type'
            ],
            name: {
                en: 'Burritos'
            }
        }
    }
    
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Example of uploading data and creating the dataset + columns on the fly by detecting types from the sample 
    <?php
    $data = $client->create('data',
    
      array (
        'type' => 'create',
        'data' => array (
    
          array (
            'Chicken baconito ',
            '3',
            '500',
            'menu'
          ),
    
          array (
            'Quesarito',
            '3.5',
            '700',
            'menu'
          )
        ),
        'options' => array (
          'update_metadata' => true,
          'header' => array (
            'Burrito',
            'price',
            'weight',
            'order type'
          ),
          'name' => array (
            'en' => 'Burritos'
          )
        )
      )
    
    );
    print("Success! ".json_encode($data));
    ?>
    
       Example of uploading data and creating the dataset + columns on the fly by detecting types from the sample 
    curl https://api.luzmo.com/0.1.0/data  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "type": "create",
      "data": [
        [
          "Chicken baconito ",
          3,
          500,
          "menu"
        ],
        [
          "Quesarito",
          3.5,
          700,
          "menu"
        ]
      ],
      "options": {
        "update_metadata": true,
        "header": [
          "Burrito",
          "price",
          "weight",
          "order type"
        ],
        "name": {
          "en": "Burritos"
        }
      }
    }
    }
    EOF
    
    
       Example of appending data to an existing dataset 
    JSONObject data = client.create("data",
    
      ImmutableMap.of(
        "securable_id" , "< Your securable id >",
        "type" , "append",
        "data" , ImmutableList.of(
    
          ImmutableList.of(
            "Fresh new burrito ",
            "3",
            "500",
            "menu"
          ),
    
          ImmutableList.of(
            "Guacarrito",
            "3.5",
            "700",
            "menu"
          )
        )
      ));
    System.out.println("Success! %s%n", data);
    
       Example of appending data to an existing dataset 
    dynamic properties = new ExpandoObject();
    properties.securable_id = "< Your securable id >";
    properties.type = "append";
    properties.data = new List<Object> {
    
          new List<Object> {
            "Fresh new burrito ",
            "3",
            "500",
            "menu"
          },
    
          new List<Object> {
            "Guacarrito",
            "3.5",
            "700",
            "menu"
          }
        };
    
    dynamic data = client.create("data",    properties);
    Console.WriteLine("Success!", data);
    
       Example of appending data to an existing dataset 
    client.create('data',
      {
        securable_id: '< Your securable id >',
        type: 'append',
        data: [
            [
                'Fresh new burrito ',
                3,
                500,
                'menu'
            ],
            [
                'Guacarrito',
                3.5,
                700,
                'menu'
            ]
        ]
    }
    
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Example of appending data to an existing dataset 
    <?php
    $data = $client->create('data',
    
      array (
        'securable_id' => '< Your securable id >',
        'type' => 'append',
        'data' => array (
    
          array (
            'Fresh new burrito ',
            '3',
            '500',
            'menu'
          ),
    
          array (
            'Guacarrito',
            '3.5',
            '700',
            'menu'
          )
        )
      )
    
    );
    print("Success! ".json_encode($data));
    ?>
    
       Example of appending data to an existing dataset 
    curl https://api.luzmo.com/0.1.0/data  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "securable_id": "< Your securable id >",
      "type": "append",
      "data": [
        [
          "Fresh new burrito ",
          3,
          500,
          "menu"
        ],
        [
          "Guacarrito",
          3.5,
          700,
          "menu"
        ]
      ]
    }
    }
    EOF
    
    
       Example of appending data to an existing dataset 
    data = client.create("data",
    {
        "securable_id": "< Your securable id >",
        "type": "append",
        "data": [["Fresh new burrito ",3,500,"menu"],["Guacarrito",3.5,700,"menu"]]
    })
    print("Success! ", data)
    
       Example of replacing data in an existing dataset. The columns will remain the same but the data will be completely replaced. 
    JSONObject data = client.create("data",
    
      ImmutableMap.of(
        "securable_id" , "< Your securable id >",
        "type" , "replace",
        "data" , ImmutableList.of(
    
          ImmutableList.of(
            "New collection Guacarrito",
            "3",
            "500",
            "menu"
          ),
    
          ImmutableList.of(
            "New collection Quasarito",
            "3.5",
            "700",
            "menu"
          )
        )
      ));
    System.out.println("Success! %s%n", data);
    
       Example of replacing data in an existing dataset. The columns will remain the same but the data will be completely replaced. 
    dynamic properties = new ExpandoObject();
    properties.securable_id = "< Your securable id >";
    properties.type = "replace";
    properties.data = new List<Object> {
    
          new List<Object> {
            "New collection Guacarrito",
            "3",
            "500",
            "menu"
          },
    
          new List<Object> {
            "New collection Quasarito",
            "3.5",
            "700",
            "menu"
          }
        };
    
    dynamic data = client.create("data",    properties);
    Console.WriteLine("Success!", data);
    
       Example of replacing data in an existing dataset. The columns will remain the same but the data will be completely replaced. 
    client.create('data',
      {
        securable_id: '< Your securable id >',
        type: 'replace',
        data: [
            [
                'New collection Guacarrito',
                3,
                500,
                'menu'
            ],
            [
                'New collection Quasarito',
                3.5,
                700,
                'menu'
            ]
        ]
    }
    
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Example of replacing data in an existing dataset. The columns will remain the same but the data will be completely replaced. 
    <?php
    $data = $client->create('data',
    
      array (
        'securable_id' => '< Your securable id >',
        'type' => 'replace',
        'data' => array (
    
          array (
            'New collection Guacarrito',
            '3',
            '500',
            'menu'
          ),
    
          array (
            'New collection Quasarito',
            '3.5',
            '700',
            'menu'
          )
        )
      )
    
    );
    print("Success! ".json_encode($data));
    ?>
    
       Example of replacing data in an existing dataset. The columns will remain the same but the data will be completely replaced. 
    curl https://api.luzmo.com/0.1.0/data  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "securable_id": "< Your securable id >",
      "type": "replace",
      "data": [
        [
          "New collection Guacarrito",
          3,
          500,
          "menu"
        ],
        [
          "New collection Quasarito",
          3.5,
          700,
          "menu"
        ]
      ]
    }
    }
    EOF
    
    
       Example of replacing data in an existing dataset. The columns will remain the same but the data will be completely replaced. 
    data = client.create("data",
    {
        "securable_id": "< Your securable id >",
        "type": "replace",
        "data": [["New collection Guacarrito",3,500,"menu"],["New collection Quasarito",3.5,700,"menu"]]
    })
    print("Success! ", data)
    
       Append data to a dataset by using 'update_metadata: true' with a header with a different set of columns. Given that there are  4 columns (Burrito, price, weight, order type), this call would introduce a new column 'newColumn' and remove weight and order type. Careful. This will delete the data from these two columns. You can also opt to update the name fo the dataset 
    JSONObject data = client.create("data",
    
      ImmutableMap.of(
        "securable_id" , "< Your securable id >",
        "type" , "append",
        "data" , ImmutableList.of(
    
          ImmutableList.of(
            "Fresh new burrito ",
            "3",
            "500",
            "menu",
            "newColumndata"
          ),
    
          ImmutableList.of(
            "Guacarrito",
            "3.5",
            "700",
            "menu",
            "newColumndata"
          )
        ),
        "options" , ImmutableMap.of(
          "update_metadata" , true,
          "header" , ImmutableList.of(
            "Burrito",
            "price",
            "weight",
            "order type",
            "newColumn"
          ),
          "name" , ImmutableMap.of(
            "en" , "Updated Burritos Name"
          )
        )
      ));
    System.out.println("Success! %s%n", data);
    
       Append data to a dataset by using 'update_metadata: true' with a header with a different set of columns. Given that there are  4 columns (Burrito, price, weight, order type), this call would introduce a new column 'newColumn' and remove weight and order type. Careful. This will delete the data from these two columns. You can also opt to update the name fo the dataset 
    dynamic properties = new ExpandoObject();
    properties.securable_id = "< Your securable id >";
    properties.type = "append";
    properties.data = new List<Object> {
    
          new List<Object> {
            "Fresh new burrito ",
            "3",
            "500",
            "menu",
            "newColumnData"
          },
    
          new List<Object> {
            "Guacarrito",
            "3.5",
            "700",
            "menu",
            "newColumnData"
          }
        };
    properties.options = new {
          update_metadata = true,
          header = new List<Object> {
            "Burrito",
            "price",
            "weight",
            "order type",
            "newColumn"
          },
          name = new {
            en = "Updated Burritos Name"
          }
        };
    
    dynamic data = client.create("data",    properties);
    Console.WriteLine("Success!", data);
    
       Append data to a dataset by using 'update_metadata: true' with a header with a different set of columns. Given that there are  4 columns (Burrito, price, weight, order type), this call would introduce a new column 'newColumn' and remove weight and order type. Careful. This will delete the data from these two columns. You can also opt to update the name fo the dataset 
    client.create('data',
      {
        securable_id: '< Your securable id >',
        type: 'append',
        data: [
            [
                'Fresh new burrito ',
                3,
                500,
                'menu',
          'newColumnData'
            ],
            [
                'Guacarrito',
                3.5,
                700,
                'menu',
          'newColumnData'
            ]
        ],
        options: {
            update_metadata: true,
            header: [
                'Burrito',
                'price',
          'weight',
          'order type',
                'newColumn'
            ],
            name: {
                en: 'Updated Burritos Name'
            }
        }
    }
    
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Append data to a dataset by using 'update_metadata: true' with a header with a different set of columns. Given that there are  4 columns (Burrito, price, weight, order type), this call would introduce a new column 'newColumn' and remove weight and order type. Careful. This will delete the data from these two columns. You can also opt to update the name fo the dataset 
    <?php
    $data = $client->create('data',
    
      array (
        'securable_id' => '< Your securable id >',
        'type' => 'append',
        'data' => array (
    
          array (
            'Fresh new burrito ',
            '3',
            '500',
            'menu',
            'newColumnData'
          ),
    
          array (
            'Guacarrito',
            '3.5',
            '700',
            'menu',
            'newColumnData'
          )
        ),
        'options' => array (
          'update_metadata' => true,
          'header' => array (
            'Burrito',
            'price',
            'weight',
            'order type',
            'newColumn'
          ),
          'name' => array (
            'en' => 'Updated Burritos Name'
          )
        )
      )
    
    );
    print("Success! ".json_encode($data));
    ?>
    
       Append data to a dataset by using 'update_metadata: true' with a header with a different set of columns. Given that there are  4 columns (Burrito, price, weight, order type), this call would introduce a new column 'newColumn' and remove weight and order type. Careful. This will delete the data from these two columns. You can also opt to update the name fo the dataset 
    curl https://api.luzmo.com/0.1.0/data  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "securable_id": "< Your securable id >",
      "type": "append",
      "data": [
        [
          "Fresh new burrito ",
          3,
          500,
          "menu",
          "newColumnData"
        ],
        [
          "Guacarrito",
          3.5,
          700,
          "menu",
          "newColumnData"
        ]
      ],
      "options": {
        "update_metadata": true,
        "header": [
          "Burrito",
          "price",
          "weight",
          "order type",
          "newColumn"
        ],
        "name": {
          "en": "Updated Burritos Name"
        }
      }
    }
    }
    EOF
    
    
       Append data to a dataset by using 'update_metadata: true' with a header with a different set of columns. Given that there are  4 columns (Burrito, price, weight, order type), this call would introduce a new column 'newColumn' and remove weight and order type. Careful. This will delete the data from these two columns. You can also opt to update the name fo the dataset 
    data = client.create("data",
    {
        "securable_id": "< Your securable id >",
        "type": "append",
        "data": [["Fresh new burrito ",3,500,"menu",',ewColumData"],["Guacarrito",3.5,700,"menu","newColumnData"]],
        "options": {
          "update_metadata": True,
          "header": ["Burrito","price","weight","order type","newColumn"],
          "name": {
            "en": "Updated Burritos Name"
          }
        }
    })
    print("Success! ", data)
    
    Create
    can be executed by:
    Securable Owner

    This endpoint can be used to: - add data to an existing dataset - overwrite data of an existing dataset - create a dataset and columns automatically from your data by analyzing the types.

    Data in Luzmo is pushed to our highly efficient OLAP for all datasets that are created after 20/09/2019. This engine is be performant enough to handle aggregations on millions of rows.

    Action: Update

       Signal update to external data 
    JSONObject data = client.update("data", "<your data id>", 
      ImmutableMap.of(
    
      ));
    
       Signal update to external data 
    dynamic properties = new ExpandoObject();
    
    dynamic data = client.update("data", "<your data id>", );
    
       Signal update to external data 
    client.update('data',
      '<your data id>',
      {}
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Signal update to external data 
    <?php
    $user = $client->update('data', '<your data id>', 
      array (
    
      ));
    ?>
    
       Signal update to external data 
    curl https://api.luzmo.com/0.1.0/data  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your data id>",
      "properties": {}
    }
    EOF
    
       Signal update to external data 
    data = client.update("data", "<your_data_id>", {
    
    })
    
    Update
    can be executed by:
    Securable Modifier

    This endpoint can be used to signal changes to external data (eg. databases or plugin) to Luzmo. Luzmo will then update any open 'data subscriptions' (eg. currently open dashboards) that rely on the modified dataset, so data can be seen changing in real-time. A maximum update frequency of 1x per 15 seconds is enforced.

    Action: Get

       Retrieve total number of burritos savoured per week, per type, starting from 2019 
    JSONObject data = client.get("data", 
      ImmutableMap.of(
        "dimensions" , ImmutableList.of(
    
          ImmutableMap.of(
            "dataset_id" , "< Burrito dataset id >",
            "column_id" , "< Type of burrito column id >"
          ),
    
          ImmutableMap.of(
            "dataset_id" , "< Burrito dataset id >",
            "column_id" , "< Date savoured column id >",
            "level" , "4"
          )
        ),
        "measures" , ImmutableList.of(
    
          ImmutableMap.of(
            "dataset_id" , "< Burrito dataset id >",
            "column_id" , "< Number of burritos column id >",
            "aggregation" , ImmutableMap.of(
              "type" , "sum"
            )
          )
        ),
        "where" , ImmutableList.of(
    
          ImmutableMap.of(
            "expression" , "? >= ?",
            "parameters" , ImmutableList.of(
    
              ImmutableMap.of(
                "dataset_id" , "< Burrito dataset id >",
                "column_id" , "< Date savoured column id >"
              ),
              "2019-01-01T00:00:00.000Z"
            )
          )
        )
      ));
    
    
       Retrieve total number of burritos savoured per week, per type, starting from 2019 
    dynamic query = new ExpandoObject();
    query.dimensions = new List<Object> {
    
          new {
            dataset_id = "< Burrito dataset id >",
            column_id = "< Type of burrito column id >"
          },
    
          new {
            dataset_id = "< Burrito dataset id >",
            column_id = "< Date savoured column id >",
            level = "4"
          }
        };
    query.measures = new List<Object> {
    
          new {
            dataset_id = "< Burrito dataset id >",
            column_id = "< Number of burritos column id >",
            aggregation = new {
              type = "sum"
            }
          }
        };
    query.where = new List<Object> {
    
          new {
            expression = "? >= ?",
            parameters = new List<Object> {
    
              new {
                dataset_id = "< Burrito dataset id >",
                column_id = "< Date savoured column id >"
              },
              "2019-01-01T00:00:00.000Z"
            }
          }
        };
    
    dynamic data = client.get("data",     query);
    
    
       Retrieve total number of burritos savoured per week, per type, starting from 2019 
    client.get('data', {
        dimensions: [
            {
                dataset_id: '< Burrito dataset id >',
                column_id: '< Type of burrito column id >'
            },
            {
                dataset_id: '< Burrito dataset id >',
                column_id: '< Date savoured column id >',
                level: 4
            }
        ],
        measures: [
            {
                dataset_id: '< Burrito dataset id >',
                column_id: '< Number of burritos column id >',
                aggregation: {
                    type: 'sum'
                }
            }
        ],
        where: [
            {
                expression: '? >= ?',
                parameters: [
                    {
                        dataset_id: '< Burrito dataset id >',
                        column_id: '< Date savoured column id >'
                    },
                    '2019-01-01T00:00:00.000Z'
                ]
            }
        ]
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Retrieve total number of burritos savoured per week, per type, starting from 2019 
    <?php
    $user = $client->get('data', 
      array (
        'dimensions' => array (
    
          array (
            'dataset_id' => '< Burrito dataset id >',
            'column_id' => '< Type of burrito column id >'
          ),
    
          array (
            'dataset_id' => '< Burrito dataset id >',
            'column_id' => '< Date savoured column id >',
            'level' => '4'
          )
        ),
        'measures' => array (
    
          array (
            'dataset_id' => '< Burrito dataset id >',
            'column_id' => '< Number of burritos column id >',
            'aggregation' => array (
              'type' => 'sum'
            )
          )
        ),
        'where' => array (
    
          array (
            'expression' => '? >= ?',
            'parameters' => array (
    
              array (
                'dataset_id' => '< Burrito dataset id >',
                'column_id' => '< Date savoured column id >'
              ),
              '2019-01-01T00:00:00.000Z'
            )
          )
        )
      ));
    
    ?>
    
       Retrieve total number of burritos savoured per week, per type, starting from 2019 
    curl https://api.luzmo.com/0.1.0/data  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "dimensions": [
        {
          "dataset_id": "< Burrito dataset id >",
          "column_id": "< Type of burrito column id >"
        },
        {
          "dataset_id": "< Burrito dataset id >",
          "column_id": "< Date savoured column id >",
          "level": 4
        }
      ],
      "measures": [
        {
          "dataset_id": "< Burrito dataset id >",
          "column_id": "< Number of burritos column id >",
          "aggregation": {
            "type": "sum"
          }
        }
      ],
      "where": [
        {
          "expression": "? >= ?",
          "parameters": [
            {
              "dataset_id": "< Burrito dataset id >",
              "column_id": "< Date savoured column id >"
            },
            "2019-01-01T00:00:00.000Z"
          ]
        }
      ]
    }
    }
    EOF
    
    
       Retrieve total number of burritos savoured per week, per type, starting from 2019 
    data = client.get("data", {
        "dimensions": [{
          "dataset_id": "< Burrito dataset id >",
          "column_id": "< Type of burrito column id >"
        },{
          "dataset_id": "< Burrito dataset id >",
          "column_id": "< Date savoured column id >",
          "level": 4
        }],
        "measures": [{
          "dataset_id": "< Burrito dataset id >",
          "column_id": "< Number of burritos column id >",
          "aggregation": {
            "type": "sum"
          }
        }],
        "where": [{
          "expression": "? >= ?",
          "parameters": [{
            "dataset_id": "< Burrito dataset id >",
            "column_id": "< Date savoured column id >"
          },"2019-01-01T00:00:00.000Z"]
        }]
    })
    
    
    Get
    can be executed by:
    Securable Reader

    This endpoint can be used to query data from one or more datasets. The syntax used to query your data is similar to the queries that are sent by dashboard to populate the charts. Therefore the query consists of dimensions and measures. Dimensions result in a group by while measures perform aggregations. Besides of 'dimensions' and 'measures', the query syntax has a 'where', 'order' and 'limit' which can be used to filter, order and limit your data. Note that to filter on columns of type date, your dates should be passed in the yyyy-MM-dd'T'HH:mm:ss.SSS format. More examples can be found in the Interacting with data guide. You can find more information on how to compose your queries here.

    Dataprovider

    Using the dataprovider service, you can create datasets for a user that are available on a provider. Providers can be web services (googleanalytics, googledrive, quandl, salesforce, mailchimp, zendesk), databases or plugins. For example, you could connect your PostgreSQL database by creating an account and then use the dataprovider 'create' action to add tables of that database to your users datasets via the API.

    Properties

    Parameter
    Description
    provider
    string
    Type of data provider to retrieve data from. Either the slug of a plugin, e.g. googleanalytics, googledrive, quandl, salesforce, mailchimp, etc... the slug of your own plugin or one of a database such as 'postgresql'. Slugs are unique short names for plugins and dataproviders (such as dbs)
    account_id
    uuid
    To add datasets via a dataprovider (create) or retrieve information on available datasets (get) you need to provide a valid account id for that provider
    ...
    ...
    The properties that are required for a dataprovider differ for each provider, if you need this kind of integration, contact the Luzmo team for information on your specific provider

    Actions

    The dataprovider endpoint supports the create and get action.

    Create
    Get

    Action: Create

       First create an account and get the account id 
    JSONObject account = client.create("account",
    
      ImmutableMap.of(
        "provider" , "postgresql",
        "host" , "<host address / ip>",
        "port" , "5432",
        "scope" , "<your database name>",
        "identifier" , "<username>",
        "token" , "<password>"
      ));
    System.out.printf("Account id: %s%n", account.get("id"));
    
       First create an account and get the account id 
    dynamic properties = new ExpandoObject();
    properties.provider = "postgresql";
    properties.host = "<host address / ip>";
    properties.port = "5432";
    properties.scope = "<your database name>";
    properties.identifier = "<username>";
    properties.token = "<password>";
    
    dynamic account = client.create("account",    properties);
    
     Console.WriteLine("Account id is {0}", account["id"]);
    
       First create an account and get the account id 
    client.create('account',
      {
        provider: 'postgresql',
        host: '<host address / ip>',
        port: 5432,
        scope: '<your database name>',
        identifier: '<username>',
        token: '<password>'
    }
    
    )
      .then(function(account) {
        var account_id = account.id;
      });
    
       First create an account and get the account id 
    <?php
    $account = $client->create('account',
    
      array (
        'provider' => 'postgresql',
        'host' => '<host address / ip>',
        'port' => '5432',
        'scope' => '<your database name>',
        'identifier' => '<username>',
        'token' => '<password>'
      )
    
    );
    print( $account['id'] );
    ?>
    
       First create an account and get the account id 
    curl https://api.luzmo.com/0.1.0/account  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "provider": "postgresql",
      "host": "<host address / ip>",
      "port": 5432,
      "scope": "<your database name>",
      "identifier": "<username>",
      "token": "<password>"
    }
    }
    EOF
    # result format of the account contains the account_id
    {
     ...
     "id": "301ca544-b8c4-42c7-8da1-ff2d76351020",
    ...
    }
    
       Add two PostgreSQL-backed datasets, using the account created. This will create the Securable and Column entities and make them available for query'ing. 
    JSONObject dataprovider = client.create("dataprovider",
    
      ImmutableMap.of(
        "provider" , "postgresql",
        "account_id" , "< your account id >",
        "tables" , ImmutableList.of(
    
          ImmutableMap.of(
            "table" , "burritos",
            "schema" , "public"
          ),
    
          ImmutableMap.of(
            "table" , "burrito_shops",
            "schema" , "public"
          )
        )
      ));
    System.out.println("Success! %s%n", dataprovider);
    
       Add two PostgreSQL-backed datasets, using the account created. This will create the Securable and Column entities and make them available for query'ing. 
    dynamic properties = new ExpandoObject();
    properties.provider = "postgresql";
    properties.account_id = "< your account id >";
    properties.tables = new List<Object> {
    
          new {
            table = "burritos",
            schema = "public"
          },
    
          new {
            table = "burrito_shops",
            schema = "public"
          }
        };
    
    dynamic dataprovider = client.create("dataprovider",    properties);
    Console.WriteLine("Success!", dataprovider);
    
       Add two PostgreSQL-backed datasets, using the account created. This will create the Securable and Column entities and make them available for query'ing. 
    client.create('dataprovider',
      {
        provider: 'postgresql',
        account_id: '< your account id >',
        tables: [
            {
                table: 'burritos',
                schema: 'public'
            },
            {
                table: 'burrito_shops',
                schema: 'public'
            }
        ]
    }
    
    )
      .then(function(dataprovider) {
        console.log('Success!', dataprovider);
      });
    
       Add two PostgreSQL-backed datasets, using the account created. This will create the Securable and Column entities and make them available for query'ing. 
    <?php
    $dataprovider = $client->create('dataprovider',
    
      array (
        'provider' => 'postgresql',
        'account_id' => '< your account id >',
        'tables' => array (
    
          array (
            'table' => 'burritos',
            'schema' => 'public'
          ),
    
          array (
            'table' => 'burrito_shops',
            'schema' => 'public'
          )
        )
      )
    
    );
    print("Success! { $dataprovider }");
    ?>
    
       Add two PostgreSQL-backed datasets, using the account created. This will create the Securable and Column entities and make them available for query'ing. 
    curl https://api.luzmo.com/0.1.0/dataprovider  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "provider": "postgresql",
      "account_id": "< your account id >",
      "tables": [
        {
          "table": "burritos",
          "schema": "public"
        },
        {
          "table": "burrito_shops",
          "schema": "public"
        }
      ]
    }
    }
    EOF
    
    
       Add two PostgreSQL-backed datasets, using the account created. This will create the Securable and Column entities and make them available for query'ing. 
    dataprovider = client.create("dataprovider",
    {
        "provider": "postgresql",
        "account_id": "< your account id >",
        "tables": [{
          "table": "burritos",
          "schema": "public"
        },{
          "table": "burrito_shops",
          "schema": "public"
        }]
    })
    print("Success! ", dataprovider)
    
       Add two plugin-backed datasets, using the preconfigured account 
    JSONObject dataprovider = client.create("dataprovider",
    
      ImmutableMap.of(
        "provider" , "< plugin slug >",
        "action" , "create",
        "account_id" , "< your account id >",
        "datasets" , ImmutableList.of(
          "< canonical dataset id >",
          "< canonical dataset id >"
        )
      ));
    System.out.println("Success! %s%n", dataprovider);
    
       Add two plugin-backed datasets, using the preconfigured account 
    dynamic properties = new ExpandoObject();
    properties.provider = "< plugin slug >";
    properties.action = "create";
    properties.account_id = "< your account id >";
    properties.datasets = new List<Object> {
          "< canonical dataset id >",
          "< canonical dataset id >"
        };
    
    dynamic dataprovider = client.create("dataprovider",    properties);
    Console.WriteLine("Success!", dataprovider);
    
       Add two plugin-backed datasets, using the preconfigured account 
    client.create('dataprovider',
      {
        provider: '< plugin slug >',
        action: 'create',
        account_id: '< your account id >',
        datasets: [
            '< canonical dataset id >',
            '< canonical dataset id >'
        ]
    }
    
    )
      .then(function(dataprovider) {
        console.log('Success!', dataprovider);
      });
    
       Add two plugin-backed datasets, using the preconfigured account 
    <?php
    $dataprovider = $client->create('dataprovider',
    
      array (
        'provider' => '< plugin slug >',
        'action' => 'create',
        'account_id' => '< your account id >',
        'datasets' => array (
          '< canonical dataset id >',
          '< canonical dataset id >'
        )
      )
    
    );
    print("Success! { $dataprovider }");
    ?>
    
       Add two plugin-backed datasets, using the preconfigured account 
    curl https://api.luzmo.com/0.1.0/dataprovider  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "provider": "< plugin slug >",
      "action": "create",
      "account_id": "< your account id >",
      "datasets": [
        "< canonical dataset id >",
        "< canonical dataset id >"
      ]
    }
    }
    EOF
    
    
       Add two plugin-backed datasets, using the preconfigured account 
    dataprovider = client.create("dataprovider",
    {
        "provider": "< plugin slug >",
        "action": "create",
        "account_id": "< your account id >",
        "datasets": ["< canonical dataset id >","< canonical dataset id >"]
    })
    print("Success! ", dataprovider)
    

    Account and Dataprovider are related. Below is an explanation what each one does and how to use them together:

    Account: represents a connection to a database, plugin or web service. When you create an account for a user (e.g. for postgresql/teamleader/salesforce etc..), that user will be able to create and query datasets via that provider.

    Dataprovider: With a dataprovider, you can go a step further and already add specific datasets from a certain provider (this provider could also be your own plugin) to the users datasets. For plugins or dataproviders that require authentication, you need to provide a valid account. To show how a dataprovider interacts with accounts and datasets we provided a full example in the code samples. The final result of the code is the addition of two PostgreSQL datasets to the users account. The user that will become owner of the datasets is the owner of the token used to connect the Luzmo client.

    Action: Get

       Get a list of datasets that can be accessed from our PostgreSQL connection 
    JSONObject data = client.get("dataprovider", 
      ImmutableMap.of(
        "provider" , "postgresql",
        "account_id" , "< your postgresql account id >"
      ));
    
    
       Get a list of datasets that can be accessed from our PostgreSQL connection 
    dynamic query = new ExpandoObject();
    query.provider = "postgresql";
    query.account_id = "< your postgresql account id >";
    
    dynamic data = client.get("dataprovider",     query);
    
    
       Get a list of datasets that can be accessed from our PostgreSQL connection 
    client.get('dataprovider', {
        provider: 'postgresql',
        account_id: '< your postgresql account id >'
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Get a list of datasets that can be accessed from our PostgreSQL connection 
    <?php
    $user = $client->get('dataprovider', 
      array (
        'provider' => 'postgresql',
        'account_id' => '< your postgresql account id >'
      ));
    
    ?>
    
       Get a list of datasets that can be accessed from our PostgreSQL connection 
    curl https://api.luzmo.com/0.1.0/dataprovider  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "provider": "postgresql",
      "account_id": "< your postgresql account id >"
    }
    }
    EOF
    
    
       Get a list of datasets that can be accessed from our PostgreSQL connection 
    data = client.get("dataprovider", {
        "provider": "postgresql",
        "account_id": "< your postgresql account id >"
    })
    
    

    Retrieve which datasets are available for a specific provider.

    Export

    Export is a service that will either:

    Properties

    Parameter
    Description
    securable_id
    uuid
    Unique key of the dashboard to export. Can be found using this method.
    type
    string
    File type of the export. Can be either png or pdf
    chart_id
    string
    Unique key of the chart to export. Can be found using this method
    locale_id
    string
    Language in which the dashboard is rendered, eg. en or nl. Note that the requested locale must be one that is configured on the dashboard, otherwise the dashboard will fall-back to a different language.
    screenmode
    string
    Screen mode in which the dashboard is rendered. Can be either desktop, mobile, tablet, largeScreen or fixed.
    dimensions
    object
    Dimensions of the exported chart
    !! Note that dimensions are only applicable when specifying a chart_id. If you export an entire dashboard, the dimensions from the selected screenmode will be used. !!
    width
    string
    Width specified in pixels. E.g. 800
    height
    string
    Height specified in pixels. E.g. 800
    emails
    array[string]
    Array of e-mail addresses to send the export to (up to 20). If supplied, the exported PNG or PDF will not be delivered by the API call, but separate e-mails will be sent to each specified e-mail address instead.
    schedule
    object
    Create a scheduled (automatic) export. If schedule options are supplied, you must also specify a list of e-mail addresses to have the export sent to.
    start_at
    date
    Date and time of the first scheduled mail. The export will then continue on the specified frequency. If not specified, the current datetime will be used (i.e. first scheduled mail will be sent right away).
    frequency
    integer
    Frequency (in minutes) with which to send scheduled reports. Specific values such as 60 (hourly) 24 * 60 = 1440 (daily), 24 * 60 * 7 = 10080 (weekly), 24 * 60 * 30 = 43200 (monthly) will take into account calendar days/weeks/months and specifics such as daylight time savings
    filters
    array[object]
    Optional list of data filters to apply to the dashboard. These filters are added on top of any chart, dashboard, row-level or authorization-level filters.
    clause
    string
    Timing of application of the filter. Possible values: where (applied before aggregation/grouping, for example, only select rows with a specific price), having (applied after aggregation/grouping, for example, to select only groups in which the total price exceeds a specific value)
    origin
    string
    Level to apply the filter. Possible values: global (applied to the entire dashboard), chart (applied to a specific chart), initialization (initialize an interactive filter within a dashboard to a particular value)
    securable_id
    uuid
    In case of global or chart filter:
    Dataset id to filter.
    column_id
    uuid
    In case of global or chart filter:
    Column id to filter.
    chart_id
    uuid
    In case of initialization or chart filter:
    Chart id to initialize.
    expression
    *
    Which filter to apply. Possible values: ? = ?, ? > ?, ? >= ?, ? < ?, ? <= ?, ? in ?, ? not in ?, ? is null, ? is not null.
    value
    number, string, boolean, array
    Value to insert in the filter.

    Actions

    Since export is a service it has no associate actions.

    Create
    Get
    List
    Delete

    Action: Create

       Create a one-time PDF export 
    JSONObject export = client.create("export",
    
      ImmutableMap.of(
        "securable_id" , " < your dashboard id >",
        "type" , "pdf"
      ));
    System.out.println("Success! %s%n", export);
    
       Create a one-time PDF export 
    dynamic properties = new ExpandoObject();
    properties.securable_id = " < your dashboard id >";
    properties.type = "pdf";
    
    dynamic export = client.create("export",    properties);
    Console.WriteLine("Success!", export);
    
       Create a one-time PDF export 
    client.create('export',
      {
        securable_id: ' < your dashboard id >',
        type: 'pdf'
    }
    
    )
      .then(function(export) {
        console.log('Success!', export);
      });
    
       Create a one-time PDF export 
    <?php
    $export = $client->create('export',
    
      array (
        'securable_id' => ' < your dashboard id >',
        'type' => 'pdf'
      )
    
    );
    print("Success! { $export }");
    ?>
    
       Create a one-time PDF export 
    curl https://api.luzmo.com/0.1.0/export --output "<name of your file>" \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "securable_id": " < your dashboard id >",
      "type": "pdf"
    }
    }
    EOF
    
    
       Create a scheduled (daily = 24 * 60) pdf export that will be sent to e-mail 
    JSONObject export = client.create("export",
    
      ImmutableMap.of(
        "securable_id" , " < your dashboard id >",
        "type" , "pdf",
        "schedule" , ImmutableMap.of(
          "frequency" , "1440",
          "start_at" , "2018-09-03T12:16:59Z"
        ),
        "emails" , ImmutableList.of(
          "testexport@luzmo.com"
        )
      ));
    System.out.println("Success! %s%n", export);
    
       Create a scheduled (daily = 24 * 60) pdf export that will be sent to e-mail 
    dynamic properties = new ExpandoObject();
    properties.securable_id = " < your dashboard id >";
    properties.type = "pdf";
    properties.schedule = new {
          frequency = "1440",
          start_at = "2018-09-03T12:16:59Z"
        };
    properties.emails = new List<String> {
          "testexport@luzmo.com"
        };
    
    dynamic export = client.create("export",    properties);
    Console.WriteLine("Success!", export);
    
       Create a scheduled (daily = 24 * 60) pdf export that will be sent to e-mail 
    client.create('export',
      {
        securable_id: ' < your dashboard id >',
        type: 'pdf',
        schedule: {
            frequency: 1440,
            start_at: '2018-09-03T12:16:59Z'
        },
        emails: [
            'testexport@luzmo.com'
        ]
    }
    
    )
      .then(function(export) {
        console.log('Success!', export);
      });
    
       Create a scheduled (daily = 24 * 60) pdf export that will be sent to e-mail 
    <?php
    $export = $client->create('export',
    
      array (
        'securable_id' => ' < your dashboard id >',
        'type' => 'pdf',
        'schedule' => array (
          'frequency' => '1440',
          'start_at' => '2018-09-03T12:16:59Z'
        ),
        'emails' => array (
          'testexport@luzmo.com'
        )
      )
    
    );
    print("Success! { $export }");
    ?>
    
       Create a scheduled (daily = 24 * 60) pdf export that will be sent to e-mail 
    curl https://api.luzmo.com/0.1.0/export \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "securable_id": " < your dashboard id >",
      "type": "pdf",
      "schedule": {
        "frequency": 1440,
        "start_at": "2018-09-03T12:16:59Z"
      },
      "emails": [
        "testexport@luzmo.com"
      ]
    }
    }
    EOF
    
    
       Create a scheduled (daily = 24 * 60) pdf export that will be sent to e-mail and add a filter to filter out certain data (e.g. multitenancy filter). 
    JSONObject export = client.create("export",
    
      ImmutableMap.of(
        "securable_id" , " < your dashboard id >",
        "type" , "pdf",
        "schedule" , ImmutableMap.of(
          "frequency" , "1440",
          "start_at" , "2018-09-03T12:16:59Z"
        ),
        "emails" , ImmutableList.of(
          "testexport@luzmo.com"
        ),
        "filters": ImmutableList.of(
          ImmutableMap.of(
            "clause", "where",
            "origin", "global",
            "securable_id", "< dataset id of a dataset used in the dashboard >",
            "column_id", "< column id >",
            "expression", "? = ?",
            "value", "< value to be applied to the expression >"
          )
        )
      ));
    System.out.println("Success! %s%n", export);
    
       Create a scheduled (daily = 24 * 60) pdf export that will be sent to e-mail and add a filter to filter out certain data (e.g. multitenancy filter). 
    dynamic properties = new ExpandoObject();
    properties.securable_id = " < your dashboard id >";
    properties.type = "pdf";
    properties.schedule = new {
          frequency = "1440",
          start_at = "2018-09-03T12:16:59Z"
        };
    properties.emails = new List<String> {
          "testexport@luzmo.com"
        };
    properties.filters = new List<Object> {
        new {
          clause = "where",
          origin = "global",
          securable_id = "< dataset id of a dataset used in the dashboard >",
          column_id = "< column id >",
          expression = "? = ?",
          value = "< value to be applied to the expression >"
        }
    };
    
    dynamic export = client.create("export",    properties);
    Console.WriteLine("Success!", export);
    
       Create a scheduled (daily = 24 * 60) pdf export that will be sent to e-mail and add a filter to filter out certain data (e.g. multitenancy filter). 
    client.create('export',
      {
        securable_id: ' < your dashboard id >',
        type: 'pdf',
        schedule: {
            frequency: 1440,
            start_at: '2018-09-03T12:16:59Z'
        },
        emails: [
            'testexport@luzmo.com'
        ],
        filters: [
          {
            clause = "where",
            origin = "global",
            securable_id = "< dataset id of a dataset used in the dashboard >",
            column_id = "< column id >",
            expression = "? = ?",
            value = "< value to be applied to the expression >"
          }
        ]
    }
    
    )
      .then(function(export) {
        console.log('Success!', export);
      });
    
       Create a scheduled (daily = 24 * 60) pdf export that will be sent to e-mail and add a filter to filter out certain data (e.g. multitenancy filter). 
    <?php
    $export = $client->create('export',
    
      array (
        'securable_id' => ' < your dashboard id >',
        'type' => 'pdf',
        'schedule' => array (
          'frequency' => '1440',
          'start_at' => '2018-09-03T12:16:59Z'
        ),
        'emails' => array (
          'testexport@luzmo.com'
        ),
        'filters': array(
          array(
            'clause' => 'where',
            'origin' => 'global',
            'securable_id' => '< dataset id of a dataset used in the dashboard >',
            'column_id' => '< column id >',
            'expression' => '? = ?',
            'value' => '< value to be applied to the expression >'
          )
        )
      )
    
    );
    print("Success! { $export }");
    ?>
    
       Create a scheduled (daily = 24 * 60) pdf export that will be sent to e-mail and add a filter to filter out certain data (e.g. multitenancy filter). 
    curl https://api.luzmo.com/0.1.0/export \
    -H "Content-Type: application/json" \
    -d @- << EOF
    {
      "action": "create",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "securable_id": " < your dashboard id >",
      "type": "pdf",
      "schedule": {
        "frequency": 1440,
        "start_at": "2018-09-03T12:16:59Z"
      },
      "emails": [
        "testexport@luzmo.com"
      ],
      "filters": [
        {
          "clause": "where",
          "origin": "global",
          "securable_id": "< dataset id of a dataset used in the dashboard >",
          "column_id": "< column id of a column in a dataset used in the dashboard >",  
          "expression": "? = ?",
          "value": "< value to be applied to the expression >"
        }
      ]
    }
    }
    EOF
    
    
    Create
    can be executed by:
    Dashboard Viewer

    Any dashboard viewer can create exports of dashboards and charts, or set up scheduled exports. Dashboard modifiers can modify and delete any scheduled exports for their dashboards, even if they did not create them initially.

    Action: Get

       Retrieve your scheduled exports of a specific type 
    JSONObject data = client.get("export", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "type" , "pdf"
        )
      ));
    
    
       Retrieve your scheduled exports of a specific type 
    dynamic query = new ExpandoObject();
    query.where = new {
          type = "pdf"
        };
    
    dynamic data = client.get("export",     query);
    
    
       Retrieve your scheduled exports of a specific type 
    client.get('export', {
        where: {
            type: 'pdf'
        }
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Retrieve your scheduled exports of a specific type 
    <?php
    $user = $client->get('export', 
      array (
        'where' => array (
          'type' => 'pdf'
        )
      ));
    
    ?>
    
       Retrieve your scheduled exports of a specific type 
    curl https://api.luzmo.com/0.1.0/export  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "type": "pdf"
      }
    }
    }
    EOF
    
    
       Retrieve your scheduled exports of a specific type 
    data = client.get("export", {
        "where": {
          "type": "pdf"
        }
    })
    
    
       Example of the return structure of the query above 
    {
       "count": 1,
       "rows": [
       {
            "id": "7e0899a5-acd5-4235-8017-ff7ae208c88a",
            "task": {
                "type": "png",
                "emails": ["testexport@luzmo.com"]
            },
            "timezone": null,
            "scheduled_at": "2018-09-03T12:17:58.267Z",
            "started_at": "2018-09-03T12:17:58.267Z",
            "completed_at": "2018-09-02T12:17:58.267Z",
            "frequency": 1440,
            "retries": 0,
            "active": true,
            "updated_at": "2018-09-03T12:17:58.282Z",
            "created_at": "2018-09-03T12:17:58.271Z",
            "last_scheduled_at": null,
            "user_id": "fde42af0-57f8-40e3-880c-3464d9a525ce",
            "securable_id": "fb7bbb18-587f-494d-bd00-ff8b8f519941"
      }]
    }
    
    Get
    can be executed by:
    Securable Modifier
    List
    can be executed by:
    Securable Modifier

    Action: Delete

       Delete a scheduled export 
    client.delete("export", "<your export id>");
    
       Delete a scheduled export 
    $client->delete("export", "<your export id>");
    
       Delete a scheduled export 
    let promise = client.delete('export', '<your export id>');
    
       Delete a scheduled export 
    <?php
    $client->delete('export', '<your export id>');
    ?>
    
       Delete a scheduled export 
    curl https://api.luzmo.com/0.1.0/export  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your export id>"
    }
    EOF
    
       Delete a scheduled export 
    client.delete("export", "<your_export_id>")
    
    Delete
    can be executed by:
    Securable Modifier

    Delete an export by providing the id of the group.

    Hierarchy

    Hierarchy is a service to update:

    Colors/ordering can then be used in the dashboards if your column has the correct override flags enabled (see Column properties). Below is an example of a hierarchy that has custom colors and how it is used in the dashboard. If you want to make a tree structure, make sure you add the hierarchy levels first using the HierarchyLevel endpoint. This is not necessary in case you are just changing colors translations or ordering.

    If you enabled hierarchies for your column (see Column properties), you can also use this to create tree structures of your values. This gives you the possibility to drag different levels onto your visualization data slots. The below screenshot shows a hierarchy in the editor and two bar charts that aggregate on different hierarchy levels of the same column.

    Only dataset modifiers can edit the hierarchy of the columns of the dataset. Hierarchy elements are created-on-update if they do not exist (there is no separate create call). The current structure of the hierarchy can be retrieved as a tree via the get call. This result can include hierarchy elements of 2 types:

    Properties

    Parameter
    Description
    id
    uuid
    Unique key of the column to update
    updates
    array[object]
    List of updates to hierarchy elements to perform
    id
    string
    Unique key of the element (equal to the original data value, or uuid when it is a category).
    name
    localized
    Label of this element as shown in data tables and dashboards, translated into different languages.
    color
    string
    Color of this element in dashboards (for consistent coloring between charts & dashboards). Omit to remove the color (will use automatic coloring).
    trace
    array[string]
    List of parent element ids, to set the position within the hierarchy. The first element must be the root All element ''; the last element must be the current element. Eg. for the province Antwerp with id antwerp, this might be ['','europe','belgium','flanders','antwerp'].
    To add the element to a hierarchy without other levels, the "minimal trace" is ['','antwerp'].
    tree_order_index
    integer or double
    Order within a virtual (the same numbers can be used within different virtuals). This is a required property when building a **hierarchy tree**. Can be an integer or a double.
    deletes
    array[object]
    List of hierarchy element identifiers to delete from the hierarchy metadata. This will not delete the elements from the data itself.
    id
    string
    Unique key of the hierarchy element (this will not delete the original value)

    Actions

    Only the Delete, Update and Get actions are used in hierarchies since updates are done in bulk. The update is rather an update-or-create action in the case of hierarchies. Hierarchy operations are not associated, they are directly targeted towards a specific column.

    Delete
    Update
    Get

    Action: Update

       Use name to 'translate' your values or provide user friendlier names for your values, note that traces are required! Here we place the element under the root (root has id "") or in other words, we don't move it 
    JSONObject hierarchy = client.update("hierarchy", "<your column id>", 
      ImmutableMap.of(
        "updates" , ImmutableList.of(
    
          ImmutableMap.of(
            "id" , "Sweet burrito",
            "name" , ImmutableMap.of(
              "en" , "Sweet burrito with banana",
              "nl" , "Zoete burrito met banaan",
              "fr" , "Burrito sucré à la banane"
            ),
            "trace" , ImmutableList.of(
              "",
              "Sweet burrito"
            ),
            "tree_order_index", 0
          )
        )
      ));
    
       Use name to 'translate' your values or provide user friendlier names for your values, note that traces are required! Here we place the element under the root (root has id "") or in other words, we don't move it 
    dynamic properties = new ExpandoObject();
    properties.updates = new List<Object> {
    
          new {
            id = "Sweet burrito",
            name = new {
              en = "Sweet burrito with banana",
              nl = "Zoete burrito met banaan",
              fr = "Burrito sucré à la banane"
            },
            trace = new List<Object> {
              "",
              "Sweet burrito"
            },
            tree_order_index = 0
          }
        };
    
    dynamic hierarchy = client.update("hierarchy", "<your column id>", );
    
       Use name to 'translate' your values or provide user friendlier names for your values, note that traces are required! Here we place the element under the root (root has id "") or in other words, we don't move it 
    client.update('hierarchy',
      '<your column id>',
      {
        updates: [
            {
                id: 'Sweet burrito',
                name: {
                    en: 'Sweet burrito with banana',
                    nl: 'Zoete burrito met banaan',
                    fr: 'Burrito sucré à la banane'
                },
                trace: [
                    '',
                    'Sweet burrito'
                ],
          tree_order_index: 0
            }
        ]
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Use name to 'translate' your values or provide user friendlier names for your values, note that traces are required! Here we place the element under the root (root has id "") or in other words, we don't move it 
    <?php
    $user = $client->update('hierarchy', '<your column id>', 
      array (
        'updates' => array (
    
          array (
            'id' => 'Sweet burrito',
            'name' => array (
              'en' => 'Sweet burrito with banana',
              'nl' => 'Zoete burrito met banaan',
              'fr' => 'Burrito sucré à la banane'
            ),
            'trace' => array (
              '',
              'Sweet burrito'
            ),
            'tree_order_index' => 0
          )
        )
      ));
    ?>
    
       Use name to 'translate' your values or provide user friendlier names for your values, note that traces are required! Here we place the element under the root (root has id "") or in other words, we don't move it 
    curl https://api.luzmo.com/0.1.0/hierarchy  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your column id>",
      "properties": {
      "updates": [
        {
          "id": "Sweet burrito",
          "name": {
            "en": "Sweet burrito with banana",
            "nl": "Zoete burrito met banaan",
            "fr": "Burrito sucré à la banane"
          },
          "trace": [
            "",
            "Sweet burrito"
          ],
          "tree_order_index": 0
        }
      ]
    }
    }
    EOF
    
       Create new virtuals (categories) for 'Savory' and 'Spicy' burritos. 
    JSONObject hierarchy = client.update("hierarchy", "<your column id>", 
      ImmutableMap.of(
        "updates" , ImmutableList.of(
    
          ImmutableMap.of(
            "name" , ImmutableMap.of(
              "en" , "Savory",
              "nl" , "Hartig",
              "fr" , "Savoureux"
            ),
            "id" , "a50160a7-01d1-48c1-bcb1-81cf0ba5e892",
            "trace" , ImmutableList.of(
              "",
              "a50160a7-01d1-48c1-bcb1-81cf0ba5e892"
            ),
            "tree_order_index", 0
          ),
          ImmutableMap.of(
            "name" , ImmutableMap.of(
              "en" , "Spicy",
              "nl" , "Pikant",
              "fr" , "Epicé"
            ),
            "id" , "fd2c9de8-153e-11eb-adc1-0242ac120002",
            "trace" , ImmutableList.of(
              "",
              "fd2c9de8-153e-11eb-adc1-0242ac120002"
            ),
            "tree_order_index", 1
          )
        )
      ));
    
       Create new virtuals (categories) for 'Savory' and 'Spicy' burritos. 
    dynamic properties = new ExpandoObject();
    properties.updates = new List<Object> {
    
          new {
            name = new {
              en = "Savory",
              nl = "Hartig",
              fr = "Savoureux"
            },
            id = "a50160a7-01d1-48c1-bcb1-81cf0ba5e892",
            trace = new List<Object> {
              "",
              "a50160a7-01d1-48c1-bcb1-81cf0ba5e892"
            },
            tree_order_index = 0
          },
          new {
            name = new {
              en = "Spicy",
              nl = "Pikant",
              fr = "Epicé"
            },
            id = "fd2c9de8-153e-11eb-adc1-0242ac120002",
            trace = new List<Object> {
              "",
              "fd2c9de8-153e-11eb-adc1-0242ac120002"
            },
            tree_order_index = 1
          }
        };
    
    dynamic hierarchy = client.update("hierarchy", "<your column id>", );
    
       Create new virtuals (categories) for 'Savory' and 'Spicy' burritos. 
    client.update('hierarchy',
      '<your column id>',
      {
        updates: [
            {
                name: {
                    en: 'Savory',
                    nl: 'Hartig',
                    fr: 'Savoureux'
                },
                id: 'a50160a7-01d1-48c1-bcb1-81cf0ba5e892',
                trace: [
                    '',
                    'a50160a7-01d1-48c1-bcb1-81cf0ba5e892'
                ],
                tree_order_index: 0
            },
            {
                name: {
                    en: 'Spicy',
                    nl: 'Pikant',
                    fr: 'Epicé'
                },
                id: 'fd2c9de8-153e-11eb-adc1-0242ac120002',
                trace: [
                    '',
                    'fd2c9de8-153e-11eb-adc1-0242ac120002'
                ],
                tree_order_index: 1
            }
        ]
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Create new virtuals (categories) for 'Savory' and 'Spicy' burritos. 
    <?php
    $user = $client->update('hierarchy', '<your column id>', 
      array (
        'updates' => array (
    
          array (
            'name' => array (
              'en' => 'Savory',
              'nl' => 'Hartig',
              'fr' => 'Savoureux'
            ),
            'id' => 'a50160a7-01d1-48c1-bcb1-81cf0ba5e892',
            'trace' => array (
              '',
              'a50160a7-01d1-48c1-bcb1-81cf0ba5e892'
            ),
            'tree_order_index' => 0
          ),
          array (
            'name' => array (
              'en' => 'Spicy',
              'nl' => 'Pikant',
              'fr' => 'Epicé'
            ),
            'id' => 'fd2c9de8-153e-11eb-adc1-0242ac120002',
            'trace' => array (
              '',
              'fd2c9de8-153e-11eb-adc1-0242ac120002'
            ),
            'tree_order_index' => 1
          )
        )
      ));
    ?>
    
       Create new virtuals (categories) for 'Savory' and 'Spicy' burritos. 
    curl https://api.luzmo.com/0.1.0/hierarchy  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your column id>",
      "properties": {
      "updates": [
        {
          "name": {
            "en": "Savory",
            "nl": "Hartig",
            "fr": "Savoureux"
          },
          "id": "a50160a7-01d1-48c1-bcb1-81cf0ba5e892",
          "trace": [
            "",
            "a50160a7-01d1-48c1-bcb1-81cf0ba5e892"
          ],
          "tree_order_index": 0
        },
        {
          "name": {
            "en": "Spicy",
            "nl": "Pikant",
            "fr": "Epicé"
          },
          "id": "fd2c9de8-153e-11eb-adc1-0242ac120002",
          "trace": [
            "",
            "fd2c9de8-153e-11eb-adc1-0242ac120002"
          ],
          "tree_order_index": 1
        }
      ]
    }
    }
    EOF
    
       Place the values 'Sweet burrito', 'Hot burrito' and 'Spicy burrito' of your dataset under the corresponding virtuals (categories) and give them translations and a color 
    JSONObject hierarchy = client.update("hierarchy", "<your column id>", 
      ImmutableMap.of(
        "updates" , ImmutableList.of(
    
          ImmutableMap.of(
            "id" , "Sweet burrito",
            "name" , ImmutableMap.of(
              "en" , "Sweet burrito with banana",
              "nl" , "Zoete burrito met banaan",
              "fr" , "Burrito sucré à la banane"
            ),
            "color" , "#00ffdd",
            "trace" , ImmutableList.of(
              "",
              "a50160a7-01d1-48c1-bcb1-81cf0ba5e892",
              "Sweet burrito"
            ),
            "tree_order_index", 0
          ),
          ImmutableMap.of(
            "id" , "Hot burrito",
            "name" , ImmutableMap.of(
              "en" , "Hot burrito with chili peppers",
              "nl" , "Hete burrito met chili pepers",
              "fr" , "Burrito épicé aux piments chili"
            ),
            "color" , "#dd00ff",
            "trace" , ImmutableList.of(
              "",
              "fd2c9de8-153e-11eb-adc1-0242ac120002",
              "Hot burrito"
            ),
            "tree_order_index", 0
          ),
          ImmutableMap.of(
            "id" , "Spicy burrito",
            "name" , ImmutableMap.of(
              "en" , "Spicy burrito with red peppers",
              "nl" , "Pikante burrito met rode pepers",
              "fr" , "Burrito piquant aux poivrons rouges"
            ),
            "color" , "#ddff00",
            "trace" , ImmutableList.of(
              "",
              "fd2c9de8-153e-11eb-adc1-0242ac120002",
              "Spicy burrito"
            ),
            "tree_order_index", 1
          )
        )
      ));
    
       Place the values 'Sweet burrito', 'Hot burrito' and 'Spicy burrito' of your dataset under the corresponding virtuals (categories) and give them translations and a color 
    dynamic properties = new ExpandoObject();
    properties.updates = new List<Object> {
    
          new {
            id = "Sweet burrito",
            name = new {
              en = "Sweet burrito with banana",
              nl = "Zoete burrito met banaan",
              fr = "Burrito sucré à la banane"
            },
            color = "#00ffdd",
            trace = new List<Object> {
              "",
              "a50160a7-01d1-48c1-bcb1-81cf0ba5e892",
              "Sweet burrito"
            },
            tree_order_index = 0
          },
          new {
            id = "Hot burrito",
            name = new {
              en = "Hot burrito with chili peppers",
              nl = "Hete burrito met chili pepers",
              fr = "Burrito épicé aux piments chili"
            },
            color = "#dd00ff",
            trace = new List<Object> {
              "",
              "fd2c9de8-153e-11eb-adc1-0242ac120002",
              "Hot burrito"
            },
            tree_order_index = 0
          },
          new {
            id = "Spicy burrito",
            name = new {
              en = "Spicy burrito with red peppers",
              nl = "Pikante burrito met rode pepers",
              fr = "Burrito piquant aux poivrons rouges"
            },
            color = "#ddff00",
            trace = new List<Object> {
              "",
              "fd2c9de8-153e-11eb-adc1-0242ac120002",
              "Spicy burrito"
            },
            tree_order_index = 1
          }
        };
    
    dynamic hierarchy = client.update("hierarchy", "<your column id>", );
    
       Place the values 'Sweet burrito', 'Hot burrito' and 'Spicy burrito' of your dataset under the corresponding virtuals (categories) and give them translations and a color 
    client.update('hierarchy',
      '<your column id>',
      {
        updates: [
            {
                id: 'Sweet burrito',
                name: {
                    en: 'Sweet burrito with banana',
                    nl: 'Zoete burrito met banaan',
                    fr: 'Burrito sucré à la banane'
                },
                color: '#00ffdd',
                trace: [
                    '',
                    'a50160a7-01d1-48c1-bcb1-81cf0ba5e892',
                    'Sweet burrito'
                ],
                tree_order_index: 0
            },
            {
                id: 'Hot burrito',
                name: {
                    en: 'Hot burrito with chili peppers',
                    nl: 'Hete burrito met chili pepers',
                    fr: 'Burrito épicé aux piments chili'
                },
                color: '#dd00ff',
                trace: [
                    '',
                    'fd2c9de8-153e-11eb-adc1-0242ac120002',
                    'Hot burrito'
                ],
                tree_order_index: 0
            },
            {
                id: 'Spicy burrito',
                name: {
                    en: 'Spicy burrito with red peppers',
                    nl: 'Pikante burrito met rode pepers',
                    fr: 'Burrito piquant aux poivrons rouges'
                },
                color: '#ddff00',
                trace: [
                    '',
                    'fd2c9de8-153e-11eb-adc1-0242ac120002',
                    'Spicy burrito'
                ],
                tree_order_index: 1
            }
        ]
    }
    )
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Place the values 'Sweet burrito', 'Hot burrito' and 'Spicy burrito' of your dataset under the corresponding virtuals (categories) and give them translations and a color 
    <?php
    $user = $client->update('hierarchy', '<your column id>', 
      array (
        'updates' => array (
    
          array (
            'id' => 'Sweet burrito',
            'name' => array (
              'en' => 'Sweet burrito with banana',
              'nl' => 'Zoete burrito met banaan',
              'fr' => 'Burrito sucré à la banane'
            ),
            'color' => '#00ffdd',
            'trace' => array (
              '',
              'a50160a7-01d1-48c1-bcb1-81cf0ba5e892',
              'Sweet burrito'
            ),
            'tree_order_index' => 0
          ),
          array (
            'id' => 'Hot burrito',
            'name' => array (
              'en' => 'Hot burrito with chili peppers',
              'nl' => 'Hete burrito met chili pepers',
              'fr' => 'Burrito épicé aux piments chili'
            ),
            'color' => '#dd00ff',
            'trace' => array (
              '',
              'fd2c9de8-153e-11eb-adc1-0242ac120002',
              'Hot burrito'
            ),
            'tree_order_index' => 0
          ),
          array (
            'id' => 'Spicy burrito',
            'name' => array (
              'en' => 'Spicy burrito with red peppers',
              'nl' => 'Pikante burrito met rode pepers',
              'fr' => 'Burrito piquant aux poivrons rouges'
            ),
            'color' => '#ddff00',
            'trace' => array (
              '',
              'fd2c9de8-153e-11eb-adc1-0242ac120002',
              'Spicy burrito'
            ),
            'tree_order_index' => 1
          )
        )
      ));
    ?>
    
       Place the values 'Sweet burrito', 'Hot burrito' and 'Spicy burrito' of your dataset under the corresponding virtuals (categories) and give them translations and a color 
    curl https://api.luzmo.com/0.1.0/hierarchy  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "update",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "id": "<your column id>",
      "properties": {
      "updates": [
        {
          "id": "Sweet burrito",
          "name": {
            "en": "Sweet burrito with banana",
            "nl": "Zoete burrito met banaan",
            "fr": "Burrito sucré à la banane"
          },
          "color": "#00ffdd",
          "trace": [
            "",
            "a50160a7-01d1-48c1-bcb1-81cf0ba5e892",
            "Sweet burrito"
          ],
          "tree_order_index": 0
        },
        {
          "id": "Hot burrito",
          "name": {
            "en": "Hot burrito with chili peppers",
            "nl": "Hete burrito met chili pepers",
            "fr": "Burrito épicé aux piments chili"
          },
          "color": "#dd00ff",
          "trace": [
            "",
            "fd2c9de8-153e-11eb-adc1-0242ac120002",
            "Hot burrito"
          ],
          "tree_order_index": 0
        },
        {
          "id": "Spicy burrito",
          "name": {
            "en": "Spicy burrito with red peppers",
            "nl": "Pikante burrito met rode pepers",
            "fr": "Burrito piquant aux poivrons rouges"
          },
          "color": "#ddff00",
          "trace": [
            "",
            "fd2c9de8-153e-11eb-adc1-0242ac120002",
            "Spicy burrito"
          ],
          "tree_order_index": 1
        }
      ]
    }
    }
    EOF
    
    Create
    can be executed by:
    Securable Owner

    The update action is used both for creating new elements as for updating existing ones. There are two types of elements you can create:

    If an id does not exist yet, a new id will be created. If it does exist, the existing node will be updated.

    Note that a value node can not be a child of another value node, they can only be leaf nodes. That means that the rest of the structure of the tree has to be build using virtuals. An update can only be done by a user who is owner of the column's dataset (securable) for which the hierarchy is made.

    Action: Get

       Get the hierarchy of a column 
    JSONObject data = client.get("hierarchy", 
      ImmutableMap.of(
        "where" , ImmutableMap.of(
          "securable_id" , "< your dataset id >",
          "column_id" , "< your column id >"
        )
      ));
    
    
       Get the hierarchy of a column 
    dynamic query = new ExpandoObject();
    query.where = new {
          securable_id = "< your dataset id >",
          column_id = "< your column id >"
        };
    
    dynamic data = client.get("hierarchy",     query);
    
    
       Get the hierarchy of a column 
    client.get('hierarchy', {
        where: {
            securable_id: '< your dataset id >',
            column_id: '< your column id >'
        }
    })
      .then(function(data) {
        console.log('Success!', data);
      });
    
       Get the hierarchy of a column 
    <?php
    $user = $client->get('hierarchy', 
      array (
        'where' => array (
          'securable_id' => '< your dataset id >',
          'column_id' => '< your column id >'
        )
      ));
    
    ?>
    
       Get the hierarchy of a column 
    curl https://api.luzmo.com/0.1.0/hierarchy  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "get",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "find": {
      "where": {
        "securable_id": "< your dataset id >",
        "column_id": "< your column id >"
      }
    }
    }
    EOF
    
    
       Add a hierarchylevel to a column 
    data = client.get("hierarchy", {
        "where": {
          "securable_id": "< your dataset id >",
          "column_id": "< your column id >"
        }
    })
    
    
       Example of the return structure of the query above 
    [
      {
        "id": "",
        "name": {
          "nl": "Alle",
          "fr": "Tout",
          "en": "All"
        },
        "color": "#ccc",
        "virtual": true,
        "children": [
          {
            "id": "Navigation",
            "name": {
              "nl": "Navigation",
              "fr": "Navigation",
              "en": "Navigation"
            },
            "color": null,
            "virtual": false,
            "children": [],
            "order_index": null,
            "tree_order_index": 0.5,
            "trace": [
              "",
              "Navigation"
            ]
          },
          {
            "id": "e11b7b80-ac61-11e8-9e69-c3648c19dd02",
            "name": {
              "en": "Objects1"
            },
            "color": null,
            "virtual": true,
            "children": [
              {
                "id": "Safety",
                "name": {
                  "nl": "Safety",
                  "fr": "Safety",
                  "en": "Safety"
                },
                "color": null,
                "virtual": false,
                "children": [],
                "order_index": null,
                "tree_order_index": 9,
                "trace": [
                  "",
                  "e11b7b80-ac61-11e8-9e69-c3648c19dd02",
                  "Safety"
    
            ...
    
    Get
    can be executed by:
    Securable Reader

    To retrieve a hierarchy, you need to provide a securable_id and a column_id for which you want to find the hierarchy. A get can only be done by a user who has read access to the column's dataset (securable) for which the hierarchy is made.

    Action: Delete

       ... 
    JSONObject hierarchy = client.delete("hierarchy", "< your column id >", 
      ImmutableMap.of(
        "deletes" , ImmutableList.of(
    
          ImmutableMap.of(
            "id" , "Sweet burrito"
          ),
    
          ImmutableMap.of(
            "id" , "Salty burrito"
          ),
    
          ImmutableMap.of(
            "id" , "a50160a7-01d1-48c1-bcb1-81cf0ba5e892"
          )
        )
      ));
    
       ... 
    dynamic properties = new ExpandoObject();
    properties.deletes = new List<Object> {
    
          new {
            id = "Sweet burrito"
          },
    
          new {
            id = "Salty burrito"
          },
    
          new {
            id = "a50160a7-01d1-48c1-bcb1-81cf0ba5e892"
          }
        };
    
    dynamic hierarchy = client.delete("hierarchy", "< your column id >", );
    
       ... 
    client.delete('hierarchy',
      "<your column id>",
      {
        deletes: [
            {
                id: 'Sweet burrito'
            },
            {
                id: 'Salty burrito'
            },
            {
                id: 'a50160a7-01d1-48c1-bcb1-81cf0ba5e892'
            }
        ]
    }
    )
    .then(function(data) {
      console.log('Success!', data);
    })
    
       ... 
    <?php
    $user = $client->delete('hierarchy', '< your column id >', 
      array (
        'deletes' => array (
    
          array (
            'id' => 'Sweet burrito'
          ),
    
          array (
            'id' => 'Salty burrito'
          ),
    
          array (
            'id' => 'a50160a7-01d1-48c1-bcb1-81cf0ba5e892'
          )
        )
      ));
    ?>
    
       ... 
    curl https://api.luzmo.com/0.1.0/hierarchy  -H "Content-Type: application/json" -d @- << EOF
    {
      "action": "delete",
      "key": "$LUZMO_API_KEY",
      "token": "$LUZMO_API_TOKEN",
      "version": "0.1.0",
      "properties": {
      "deletes": [
        {
          "id": "Sweet burrito"
        },
        {
          "id": "Salty burrito"
        },
        {
          "id": "a50160a7-01d1-48c1-bcb1-81cf0ba5e892"
        }
      ]
    }
    }
    EOF
    
    Delete
    can be executed by:
    Securable Owner

    The delete action is slightly different from other deletes since it also works in bulk. In the case of hierarchies, you provide a list of ids that have to deleted for a specific column instead of deleting them one by one. Deleting hierarchies is reserved for users who are owner of the column's dataset (securable) for which the hierarchy is made.

    Rate limiting

    Calls to the Core API are rate limited to:

    {
        "type": {
            "code": 429,
            "description": "Too Many Requests"
        },
        "message": "You exceeded the Luzmo API rate limit.",
        "retry_at": 1582801285000     // Next allowed API call (in milliseconds since 1970-01-01)
    }
    

    In case you exceed the rate limit, additional requests will return a 429 Too Many Requests error.

    Take advantage of the extensive Sideloading support and large page sizes to limit the number of API calls you send. If you find yourself having to loop over API calls, this is in many cases an anti-pattern.

    Some sensitive API endpoints might be rate limited more aggressively. We reserve the right to temporarily lower the rate limit to ensure Quality of Service or to retract API access to particular tokens, users or organizations in case of abusive use of the API.

    Embedding

    Introduction

    You can use the embedding libraries to securely embed your dashboard, or a single dashboard item, in any webpage.

    We have the following components available which you can install via npm:

    By default, the component ensures a responsive dashboard layout by automatically switching between the available dashboard screen modes, and resizing the screen mode's layout, based on the available width of the parent container! Next to that, it also enables bidirectional communication between the dashboard and your application/platform.

    The Quick start guide will walk you through the installing and basic usage of the appropriate frontend component, the Component API Reference will contain all information about the available component properties, methods, and events!

    Quick start

    Below you can see an explanation and code snippet to install the appropriate frontend component for your application's framework, and use that component to embed a specific Luzmo dashboard securely.

    The full API reference of all the frontend component's available properties, methods, and events can be found here.

    Installing the component

    1 Install the web component via npm package manager by running the following command in your command line interface. It's recommended to use npm to ensure you can easily get the latest version of our component when available!
    npm i @luzmo/embed
    
     If you're not able to use npm, you can import the minified javascript file in any HTML file using the following code.
    <!--
    You can (programmatically) retrieve the latest version via this link:
    https://cdn.luzmo.com/js/luzmo-embed/latest-version.json
    It is recommended to reference a static version in your application (e.g. "<WEB_COMPONENT_VERSION>"), 
    and periodically verify and upgrade your application's implementation to
    benefit from any improvements in the latest version of the web component.
    -->
    <script
      defer
      src="https://cdn.luzmo.com/js/luzmo-embed/<WEB_COMPONENT_VERSION>/luzmo-embed.min.js"
      charset="utf-8"
    ></script>
    
    1 Install the Angular component via npm package manager by running the following command in your command line interface.
    npm i @luzmo/ngx-embed
    
    1 Install the React component via npm package manager by running the following command in your command line interface.
    npm i @luzmo/react-embed
    
    1 Install the React Native component via npm package manager by running the following command in your command line interface.
    npm i @luzmo/react-native-embed
    
    1 Install the Vue component via npm package manager by running the following command in your command line interface.
    npm i @luzmo/vue-embed
    

    All frontend components are available via npm!

    Embedding a dashboard

    2 Import the component in a JavaScript module.
    import '@luzmo/embed';
    
     You can also import the component in an HTML page.
    <script type="module">
      import './node_modules/@luzmo/embed/index.js';
    </script>
    <!-- OR -->
    <script
      type="module"
      src="./node_modules/@luzmo/embed/index.js">
    </script>
    
    3 Add the Luzmo component to your HTML page.
    <!--
    Clients on our US multi-tenant application environment,
    or a dedicated instance on a specific VPC, should specify:
    - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
    - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
    -->
    <luzmo-dashboard
      appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
      apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
      authKey="< embed authorization key >"
      authToken="< embed authorization token >"
      dashboardId="< dashboard id you want to embed >"
      dashboardSlug="< (for SSO only) instead of dashboardId: a dashboard slug as specified in the Integration. >"
    ></luzmo-dashboard>
    
    2 Import the NgxLuzmoDashboardModule in your NgModule
    import {
      NgxLuzmoDashboardModule
    } from '@luzmo/ngx-embed';
    
    @NgModule({
      ...
      imports: [
        ...,
        NgxLuzmoDashboardModule,
        ...
      ],
      ...
    })
    
    3 Add the Luzmo component in your Angular page
    /*
    Clients on our US multi-tenant application environment,
    or a dedicated instance on a specific VPC, should specify:
    - [appServer]="'https://app.us.luzmo.com/'" (or your VPC-specific address)
    - [apiHost]="'https://api.us.luzmo.com/'" (or your VPC-specific address)
    */
    <luzmo-dashboard
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< embed authorization key >'"
      [authToken]="'< embed authorization token >'"
      [dashboardId]="'< dashboard id you want to embed >'"
      [dashboardSlug]="'< (for SSO only) instead of dashboardId: a dashboard slug as specified in the Integration. >'"
    ></luzmo-dashboard>
    
    2 Minimal required parameters to securely embed a dashboard in a React application
    import { LuzmoDashboardComponent } from '@luzmo/react-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        /*
        Clients on our US multi-tenant application environment,
        or a dedicated instance on a specific VPC, should specify:
        - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
        - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
        */
        return (
          <LuzmoDashboardComponent
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< embed authorization key >"
            authToken="< embed authorization token >"
            dashboardId="< dashboard id you want to embed >"
            dashboardSlug="< (for SSO only) instead of dashboardId: a dashboard slug as specified in the Integration. >"
          ></LuzmoDashboardComponent>
        );
      }
    
    2 Minimal required parameters to securely embed a dashboard in a React Native application
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        /*
        Clients on our US multi-tenant application environment,
        or a dedicated instance on a specific VPC, should specify:
        - appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
        - apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
        */
        return (
          <LuzmoDashboardComponent
            ref={ref}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< embed authorization key >"
            authToken="< embed authorization token >"
            dashboardId="< dashboard id you want to embed >"
            dashboardSlug="< (for SSO only) instead of dashboardId: a dashboard slug as specified in the Integration. >"
          ></LuzmoDashboardComponent>
        );
      }
    
    2 Minimal required parameters to securely embed a dashboard in a Vue 3 application
    import { createApp } from 'vue';
    import App from './App.vue';
    import VueLuzmoDashboard from '@luzmo/vue-embed';
    ...
    
    const app = createApp(App);
    ...
    
    // Defines the component at app level
    app.use(VueLuzmoDashboard);
    ...
    
    app.mount('#app');
    
     You can also use our Vue component in your Vue 2 application
    import Vue from 'vue';
    import App from './App.vue';
    import VueLuzmoDashboard from '@luzmo/vue-embed/vue2';
    ...
    
    Vue.use(VueLuzmoDashboard);
    ...
    
    new Vue({
      render: (h) => h(App),
    }).$mount('#app');
    
    3 In your HTML template of your Vue application
    <template>
      ...
      <!--
      Clients on our US multi-tenant application environment,
      or a dedicated instance on a specific VPC, should specify:
      - :appServer="https://app.us.luzmo.com/" (or your VPC-specific address)
      - :apiHost="https://api.us.luzmo.com/" (or your VPC-specific address)
       -->
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< embed authorization key >"
        authToken="< embed authorization token >"
        dashboardId="< dashboard id you want to embed >"
        dashboardSlug="< (for SSO only) instead of dashboardId: a dashboard slug as specified in the Integration. >"
      ></luzmo-dashboard>
    </template>
    

    The only necessary properties that need to be specified in order to embed a dashboard securely, are:

    The Embed key and token should be requested from your backend each time a specific end-user of your application wants to see an embedded Luzmo dashboard (see the step 'generate an Embed token' in the 'Dashboard embedding' guide), and should be passed along to the frontend component before specifying the dashboardId.

    Parameter Description
    appServer
    string
    Tenancy of Luzmo app to connect to. Defaults to 'https://app.luzmo.com/'.
    For US multi-tenant application, set appServer to 'https://app.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    apiHost
    string
    Tenancy of Luzmo API to connect to. Defaults to 'https://api.luzmo.com/'.
    For US multi-tenant application, set apiHost to 'https://api.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    authKey
    uuid
    The authorization key (i.e. "id") from the response of the authorization request in your backend.
    authToken
    string
    The authorization token from the response of the authorization request in your backend.
    dashboardId
    uuid
    This is the id of the dashboard that you want to embed.
    dashboardSlug
    string
    (Optional) (Available only for SSO tokens not embed) Instead of specifying a dashboardId, you can alternatively specify a dashboard slug. The slug is defined when associating a dashboard with an Integration.
    Specify either the dashboardId or dashboardSlug property.

    Component API Reference

    Below you can find more information about the different properties, methods, and events that our frontend components provide.

    Properties

       All available properties can be seen in the code snippet below 
    <luzmo-dashboard
      appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
      apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
      authKey="< embed authorization key >"
      authToken="< embed authorization token >"
      dashboardId="< dashboard id you want to embed >"
      dashboardSlug="< (for SSO only) instead of dashboardId: a dashboard slug as specified in the Integration. >"
      itemId="< id of a Luzmo item within the dashboard >"
      screenMode="< dashboard screenmode >"
      language="< dashboard language >"
      timezoneId="< dashboard timezone id >"
      loaderBackground="< background color of the loader >"
      loaderFontColor="< font color of the loader >"
      loaderSpinnerColor="< color of the spinner in the loader >"
      loaderSpinnerBackground="< Background color of the spinner in the loader >"
      editMode="< view, editLimited or editFull >"
      mainColor="< Main whitelabeling color of embedded dashboard editor >"
      accentColor="< Accent whitelabeling color of embedded dashboard editor >"
    ></luzmo-dashboard>
    
    <luzmo-dashboard
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< embed authorization key >'"
      [authToken]="'< embed authorization token >'"
      [dashboardId]="'< dashboard id you want to embed >'"
      [dashboardSlug]="'< (for SSO only) instead of dashboardId: a dashboard slug as specified in the Integration. >'"
      [itemId]="'< id of a Luzmo item within the dashboard >'"
      [screenMode]="'< dashboard screenmode >'"
      [language]="'< dashboard language >'"
      [timezoneId]="'< dashboard timezone id >'"
      [loaderBackground]="'< background of the loader >'"
      [loaderFontColor]="'< font color of the loader >'"
      [loaderSpinnerColor]="'< color of the spinner in the loader >'"
      [loaderSpinnerBackground]="'< Background color of the spinner in the loader >'"
      [editMode]="'< view, editLimited or editFull >'"
      [mainColor]="'< main whitelabeling color of embedded dashboard editor >'"
      [accentColor]="'< accent whitelabeling color of embedded dashboard editor >'"
    ></luzmo-dashboard>
    
    import { LuzmoDashboardComponent } from '@luzmo/react-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        return (
          <LuzmoDashboardComponent
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< embed authorization key >"
            authToken="< embed authorization token >"
            dashboardId="< dashboard id you want to embed >"
            dashboardSlug="< (for SSO only) instead of dashboardId: a dashboard slug as specified in the Integration. >"
            itemId="< id of a Luzmo item within the dashboard >"
            screenMode="< dashboard screenmode >"
            language="< dashboard language >"
            timezoneId="< dashboard timezone id >"
            loaderBackground="< background of the loader >"
            loaderFontColor="< font color of the loader >"
            loaderSpinnerColor="< color of the spinner in the loader >"
            loaderSpinnerBackground="< Background color of the spinner in the loader >"
            editMode="< view, editLimited or editFull >"
            mainColor="< main whitelabeling color of embedded dashboard editor >"
            accentColor="< accent whitelabeling color of embedded dashboard editor >"
          ></LuzmoDashboardComponent>
        );
      }
    
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
      function LuzmoWrapper() {
        ...
    
        return (
          <LuzmoDashboardComponent
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< embed authorization key >"
            authToken="< embed authorization token >"
            dashboardId="< dashboard id you want to embed >"
            dashboardSlug="< (for SSO only) instead of dashboardId: a dashboard slug as specified in the Integration. >"
            itemId="< id of a Luzmo item within the dashboard >"
            screenMode="< dashboard screenmode >"
            language="< dashboard language >"
            timezoneId="< dashboard timezone id >"
            loaderBackground="< background of the loader >"
            loaderFontColor="< font color of the loader >"
            loaderSpinnerColor="< color of the spinner in the loader >"
            loaderSpinnerBackground="< Background color of the spinner in the loader >"
            editMode="< view, editLimited or editFull >"
            mainColor="< main whitelabeling color of embedded dashboard editor >"
            accentColor="< accent whitelabeling color of embedded dashboard editor >"
          ></LuzmoDashboardComponent>
        );
      }
    
    <template>
      ...
    
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< embed authorization key >"
        authToken="< embed authorization token >"
        dashboardId="< dashboard id you want to embed >"
        dashboardSlug="< (for SSO only) instead of dashboardId: a dashboard slug as specified in the Integration. >"
        itemId="< id of a Luzmo item within the dashboard >"
        screenMode="< dashboard screenmode >"
        language="< dashboard language >"
        timezoneId="< dashboard timezone id >"
        loaderBackground="< background of the loader >"
        loaderFontColor="< font color of the loader >"
        loaderSpinnerColor="< color of the spinner in the loader >"
        loaderSpinnerBackground="< Background color of the spinner in the loader >"
        editMode="< view, editLimited or editFull >"
        mainColor="< main whitelabeling color of embedded dashboard editor >"
        accentColor="< accent whitelabeling color of embedded dashboard editor >"
      ></luzmo-dashboard>
      ...
    </template>
    

    Below you can find a list of all available properties that you can (optionally) specify in the frontend component, together with their explanation and possible values:

    Parameter Description
    appServer
    string
    Tenancy of Luzmo app to connect to. Defaults to 'https://app.luzmo.com/'.
    For US multi-tenant application, set appServer to 'https://app.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    apiHost
    string
    Tenancy of Luzmo API to connect to. Defaults to 'https://api.luzmo.com/'.
    For US multi-tenant application, set apiHost to 'https://api.us.luzmo.com/'. For dedicated VPC environments, you should point towards your VPC-specific address.
    authKey
    uuid
    The authorization key (i.e. "id") from the response of the authorization request in your backend.
    authToken
    string
    The authorization token from the response of the authorization request in your backend.
    dashboardId
    uuid
    This is the id of the dashboard that you want to embed.
    Specify either the dashboardId or dashboardSlug property.
    dashboardSlug
    string
    (Optional) (Available only for SSO tokens not embed) Instead of specifying a dashboardId, you can alternatively specify a dashboard slug. The slug is defined when associating a dashboard with an Integration.
    Specify either the dashboardId or dashboardSlug property.
    itemId
    uuid
    (Optional) In case you want to embed a single item of a dashboard, you should specify a dashboardId or dashboardSlug, together with this itemId property set to the id of the item that you want to embed.
    The embedded dashboard item will automatically resize based on the parent container's width and height.
    screenMode
    string
    (Optional) By default, the frontend component will automatically switch between the available screen modes of a dashboard based on the available width of the parent container in your application, and resizes the appropriate screen mode to that width (screenMode: 'auto' is the default when not specified).
    In case you'd like your dashboard to only be embedded in one specific screen mode, you can specify either 'fixed', 'mobile', 'tablet', 'desktop', or 'largeScreen'. If the screenMode is set to a specific screen mode, and that screen mode is available, it will be used. This also means that the dashboard will not auto-resize or switch to other screenmodes if the size of the container changes.

    More info on screen modes in a Luzmo dashboard can be found in this Academy article.
    language
    string
    (Optional) The language code that you wish to use in the dashboard instead of the default language of the dashboard. You can specify 'en', 'cs', 'da', 'de', 'es', 'fi', 'fr', 'he', 'hu', 'it', 'ja', 'ko', 'mk', 'nl', 'pl', 'pt', 'ru', 'sv', 'zh_cn' or 'zh_tw'.
    If that language code is not configured in the dashboard, the default language of that dashboard will be used.

    This Academy Webinar goes into more detail about multi-lingual dashboards.
    timezoneId
    string
    (Optional) The timezone id you wish to use in your dashboard, instead of the default timezone of the dashboard (or SSO token). This timezone id needs to be a valid id that is available in the IANA timezone database, for example: Europe/Brussels or America/New_York.

    More info on timezone support in an (embedded) Luzmo dashboard can be found in this Academy article.
    loaderBackground
    string
    (optional) The background color of the container while loading the dashboard.
    This property should be specified as a string of rgb or rgba values, e.g. "rgb(50,50,50)", "rgba(50,50,50, 0.5)", etc.
    loaderFontColor
    string
    (optional) The font color of the message(s) while loading the dashboard.
    This property should be specified as a string of rgb or rgba values, e.g. "rgb(50,50,50)", "rgba(50,50,50, 0.5)", etc.
    loaderSpinnerColor
    string
    (optional) The color of the spinner while loading the dashboard.
    This property should be specified as a string of rgb or rgba values, e.g. "rgb(50,50,50)", "rgba(50,50,50, 0.5)", etc.
    loaderSpinnerBackground
    string
    (optional) The background color of the spinner while loading the dashboard.
    This property should be specified as a string of rgb or rgba values, e.g. "rgb(50,50,50)", "rgba(50,50,50, 0.5)", etc.
    mainColor
    string
    (Optional) Override the main color used in the whitelabeling of the embedded dashboard editor. If not provided, the main color of the whitelabeling colors set on the organization will be used.
    Should be specified as a string of rgb values, e.g. "rgb(50,50,50)".

    A gif showcasing the influence of specifying mainColor can be seen in this Academy article.
    accentColor
    string
    (Optional) Override the accent color used in the whitelabeling of the embedded dashboard editor. If not provided, the accent color of the whitelabeling colors set on the organization will be used.
    Should be specified as a string of rgb values, e.g. "rgb(50,50,50)".

    A gif showcasing the influence of specifying accentColor can be seen in this Academy article.
    editMode
    string DashboardEditMode
    In case you would like to embed our dashboard editor, you will need to switch to an edit mode by providing either 'editLimited' or 'editFull' as value for this property (or using the setEditMode method to pass along that value). If not specified, the default mode is "view" (i.e. no editor).
    • "view"
      This mode enables your users to view and interact with an embedded dashboard, without having the option to change the dashboard itself.
    • "editLimited"
      This mode is useful if you have your own dashboard navigation in your application (e.g. a sidebar containing dashboard tabs or a dropdown) and would like the user to edit (some of) the dashboards (e.g. by adding an “Edit” button that toggles the editMode between “view” and “editLimited” mode). Users will be able to create variants of the dashboard or edit the dashboard itself (depending on the access rights you defined for the dashboard) and share these dashboard (variants) with other users in their organization.
    • "editFull"
      If you have a dedicated place in your application where users should be able to create & edit all their accessible dashboard(s) (e.g. in your navigation bar you have a “Dashboard editor” tab that should show the embedded dashboard editor). The user will be able to create edit, duplicate and create a variant of existing dashboards (depending on the access rights you defined for the dashboard) as well as create new dashboards and share these dashboard (variants) with other users in their organization.

    Methods

    The embed libraries offer some methods you can use to trigger actions on the dashboard, or receive information/data from the dashboard.

    We currently provide the following methods:

    setAuthorization

      Replaces the authorization key & token of an embedded dashboard when the button is clicked.
    ...
      <button id="set-authorization-button">Set authorization</button>
      <luzmo-dashboard
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
    ...
    <script>
      // Get the button reference
      const setAuthorizationButton = document.getElementById("set-authorization-button");
    
      // Get the component reference
      // Note: only returns the first occurrence of a Luzmo component within the document.
      const dashboardComponent = document.querySelector("luzmo-dashboard");
    
      // Add an event listener to the click event on the button
      setAuthorizationButton.onclick = () => {
        // Set the new SSO Authorization token via the setAuthorization method
        dashboardComponent.setAuthorization(
          "< New SSO Authorization key >",
          "< New SSO Authorization token >"
        ).then(() => {
          // Successfully set the new SSO Authorization key and token!
          // Either retrigger the data queries of one/all dashboard items,
          return dashboardComponent.refreshData(
            "< (Optional) id of a specific dashboard item to refresh >"
          );
          // OR, reload the dashboard itself
          // return dashboardComponent.reloadDashboard();
        }).then(() => {
          // Success!
        });
      };
    </script>
    
    1 We define a button and the Luzmo component in an Angular page
    <button (click)="setAuthorization()">Set authorization</button>
    <luzmo-dashboard
      #dashboardInstance
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< Initial SSO Authorization key >'"
      [authToken]="'< Initial SSO Authorization token >'"
      [dashboardId]="'< Dashboard ID >'"
    ></luzmo-dashboard>
    
    2 In the Angular Component file, we used the setAuthorization method to replace the SSO key and token when the button is clicked
    import {  Component, ViewChild } from '@angular/core';
    import { take, switchMap } from 'rxjs/operators';
    ...
    import {
      NgxLuzmoDashboardModule
    } from '@luzmo/ngx-embed';
    ...
    
    @Component({
      ...
    })
    
    export class LuzmoEmbeddingComponent {
      // Component reference
      @ViewChild('dashboardInstance') dashboardInstance: NgxLuzmoDashboardModule;
    
      setAuthorization(): void {
        // Set the new SSO Authorization token via the setAuthorization method
        this.dashboardInstance.setAuthorization(
          "< New SSO Authorization key >",
          "< New SSO Authorization token >"
        ).pipe(take(1))
        .pipe(switchMap(()=> {
          // Successfully set the new SSO Authorization key and token!
          // Either retrigger the data queries of one/all dashboard items,
          return this.dashboardInstance.refreshData(
            "< (Optional) id of a specific dashboard item to refresh >"
          );
          // OR, reload the dashboard itself.
          // return this.dashboardInstance.reloadDashboard();
        })).subscribe(() => {
          // Success!
        });
      }
    }
    
     Replaces the authorization key & token of an embedded dashboard when the button is clicked.
    import { useRef } from 'react';
    ...
    import {
      LuzmoDashboardComponent
    } from '@luzmo/react-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const setAuthorization = () => {
        // Set the new SSO Authorization token via the setAuthorization method
        dashboardInstance.current.setAuthorization(
          "< New SSO Authorization key >",
          "< New SSO Authorization token >"
        ).then(() => {
          // Successfully set the new SSO Authorization key and token!
          // Either retrigger the data queries of one/all dashboard items,
          return dashboardInstance.current.refreshData("< (Optional) id of a specific dashboard item to refresh >");
          // OR, reload the dashboard itself
          // return dashboardInstance.current.reloadDashboard();
        }).then(() => {
          // Success!
        });
      };
    
      return (
        <div>
          <button onClick={() => setAuthorization()}>Set Authorization</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    }
    
     Replaces the authorization key & token of an embedded dashboard when the button is clicked.
    import { useRef } from 'react';
    ...
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const setAuthorization = () => {
        // Set the new SSO Authorization token via the setAuthorization method
        dashboardInstance.current.setAuthorization(
          "< New SSO Authorization key >",
          "< New SSO Authorization token >"
        ).then(() => {
          // Successfully set the new SSO Authorization key and token!
          // Either retrigger the data queries of one/all dashboard items,
          return dashboardInstance.current.refreshData("< (Optional) id of a specific dashboard item to refresh >");
          // OR, reload the dashboard itself.
          // return dashboardInstance.current.reloadDashboard();
        }).then(() => {
          // Success!
        });
      };
    
      return (
        <div>
          <button onClick={() => setAuthorization()}>Set Authorization</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    
     Replaces the authorization key & token of an embedded dashboard when the button is clicked.
    <template>
      ...
      <button @click="setAuthorization">Set authorization</button>
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
      ...
    </template>
    <script>
      export default {
        methods: {
          setAuthorization() {
            // Set the new SSO Authorization token via the setAuthorization method
            this.$refs.dashboardInstance.setAuthorization(
              "< New SSO Authorization key >",
              "< New SSO Authorization token >"
            ).then(() => {
              // Successfully set the new SSO Authorization key and token!
              // Either retrigger the data queries of one/all dashboard items,
              return this.$refs.dashboardInstance.refreshData(
                "< (Optional) id of a specific dashboard item to refresh >"
              );
              // OR, reload the dashboard itself.
              // return this.$refs.dashboardInstance.reloadDashboard();
            }).then(() => {
              // Success!
            });
          },
          ...
        },
        ...
      }
    </script>
    

    The setAuthorization method allows you to replace the SSO authorization token that is currently used to embed a dashboard. This can be useful if the new SSO authorization token has different properties that should be taken into account in the dashboard (e.g. different (initialization) filter values, different theme, etc.).
    You pass along a new SSO Authorization key and token pair as arguments to the setAuthorization method. Once the promise is resolved, you will always want to call either:

    Parameter Description
    authKey
    string
    The new SSO Authorization key (the 'id' property in the response of the SSO Authorization request).
    authToken
    string
    The new SSO authorization token.

    In Angular, the setAuthorization method is an Observable to which you can subscribe an observer function to. The observable will deliver no value.

    The setAuthorization method returns a Promise that "resolves" with no value.

    reloadDashboard

      Reloads an embedded dashboard when the button is clicked
    ...
      <button id="reload-dashboard-button">Reload dashboard</button>
      <luzmo-dashboard
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
    ...
    <script>
      // Get the button reference
      const reloadDashboardButton = document.getElementById("reload-dashboard-button");
    
      // Get the component reference
      // Note: only returns the first occurrence of a Luzmo component within the document.
      const dashboardComponent = document.querySelector("luzmo-dashboard");
    
      // Add an event listener to the click event on the button
      reloadDashboardButton.onclick = () => {
        // Reload the dashboard using the reloadDashboard method
        dashboardComponent.reloadDashboard()
          .then(() => {
            // Successfully reloaded the embedded dashboard!
          });
      };
    </script>
    
    1 We define a button and the Luzmo component in an Angular page
    <button (click)="reloadDashboard()">Reload dashboard</button>
    <luzmo-dashboard
      #dashboardInstance
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< Initial SSO Authorization key >'"
      [authToken]="'< Initial SSO Authorization token >'"
      [dashboardId]="'< Dashboard ID >'"
    ></luzmo-dashboard>
    
    2 In the Angular Component file, we used the reloadDashboard method to reload the embedded dashboard
    import {  Component, ViewChild } from '@angular/core';
    import { take } from 'rxjs/operators';
    ...
    import {
      NgxLuzmoDashboardModule
    } from '@luzmo/ngx-embed';
    ...
    
    @Component({
      ...
    })
    
    export class LuzmoEmbeddingComponent {
      // Component reference
      @ViewChild('dashboardInstance') dashboardInstance: NgxLuzmoDashboardModule;
    
      reloadDashboard(): void {
        // Reload the dashboard using the reloadDashboard method
        this.dashboardInstance.reloadDashboard()
          .pipe(take(1))
          .subscribe(() => {
            // Successfully reloaded the dashboard!
          });
      }
    }
    
     Reloads an embedded dashboard when the button is clicked.
    import { useRef } from 'react';
    ...
    import {
      LuzmoDashboardComponent
    } from '@luzmo/react-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const reloadDashboard = () => {
        // Reload the dashboard using the reloadDashboard method
        dashboardInstance.current.reloadDashboard()
          .then(() => {
            // Successfully reloaded the dashboard!
          });
      };
    
      return (
        <div>
          <button onClick={() => reloadDashboard()}>Reload dashboard</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    }
    
     Reloads an embedded dashboard when the button is clicked.
    import { useRef } from 'react';
    ...
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const reloadDashboard = () => {
        // Reload the dashboard using the reloadDashboard method
        dashboardInstance.current.reloadDashboard()
          .then(() => {
            // Successfully reloaded the dashboard!
          });
      };
    
      return (
        <div>
          <button onClick={() => reloadDashboard()}>Reload dashboard</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    
     Reloads an embedded dashboard when the button is clicked
    <template>
      ...
      <button @click="reloadDashboard">Reload dashboard</button>
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
      ...
    </template>
    <script>
      export default {
        methods: {
          reloadDashboard() {
            // Reload the dashboard using the reloadDashboard method
            this.$refs.dashboardInstance.reloadDashboard()
              .then(() => {
                // Successfully reloaded the dashboard!
              });
          },
          ...
        },
        ...
      }
    </script>
    

    The reloadDashboard method is used to reload an embedded dashboard without reloading the whole embedded frame. This is useful when e.g. the authorization has changed (by using setAuthorization) and the dashboard itself needs to be updated.

    In Angular, the reloadDashboard method is an Observable to which you can subscribe an observer function to. The observable will deliver no value.

    The reloadDashboard method returns a Promise that "resolves" with no value.

    refreshData

      Refreshes the data when the button is clicked
    ...
      <button id="refresh-data-button">Refresh data</button>
      <luzmo-dashboard
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
    ...
    <script>
      // Get the button reference
      const refreshDataButton = document.getElementById("refresh-data-button");
    
      // Get the component reference
      // Note: only returns the first occurrence of a Luzmo component within the document.
      const dashboardComponent = document.querySelector("luzmo-dashboard");
    
      // Add an event listener to the click event on the button
      refreshDataButton.onclick = () => {
        // Refresh the data of all items using the refreshData method
        dashboardComponent.refreshData().then(() => {
          // Successfully refreshed the data of all items in the embedded dashboard!
        });
    
        // Alternatively, you could also refresh the data of a specific dashboard item
        // dashboardComponent.refreshData(
        //   "< (Optional) id of a specific dashboard item to refresh >"
        // ).then(() => {
          // Successfully refreshed the data of a specific dashboard item!
        // });
      };
    </script>
    
    1 We define a button and the Luzmo component in an Angular page
    <button (click)="refreshData()">Refresh data</button>
    <luzmo-dashboard
      #dashboardInstance
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< Initial SSO Authorization key >'"
      [authToken]="'< Initial SSO Authorization token >'"
      [dashboardId]="'< Dashboard ID >'"
    ></luzmo-dashboard>
    
    2 In the Angular Component file, we used the refreshData method to refresh the data when the button is clicked
    import {  Component, ViewChild } from '@angular/core';
    import { take } from 'rxjs/operators';
    ...
    import {
      NgxLuzmoDashboardModule
    } from '@luzmo/ngx-embed';
    ...
    
    @Component({
      ...
    })
    
    export class LuzmoEmbeddingComponent {
      // Component reference
      @ViewChild('dashboardInstance') dashboardInstance: NgxLuzmoDashboardModule;
    
      refreshData(): void {
        // Refresh the data of all items using the refreshData method
        this.dashboardInstance.refreshData()
          .pipe(take(1))
          .subscribe(() => {
            // Successfully refreshed the data of all items in the embedded dashboard!
          });
    
        // Alternatively, you could also refresh the data of a specific dashboard item
        // this.dashboardInstance.refreshData(
        //   "< (Optional) id of a specific dashboard item to refresh >"
        // ).pipe(take(1))
        // .subscribe(() => {
            // Successfully refreshed the data of a specific dashboard item!
        // });
      }
    }
    
     Refreshes the data when the button is clicked.
    import { useRef } from 'react';
    ...
    import {
      LuzmoDashboardComponent
    } from '@luzmo/react-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const refreshData = () => {
        // Refresh the data of all items using the refreshData method
        dashboardInstance.current.refreshData()
          .then(() => {
            // Successfully refreshed the data of all items in the embedded dashboard!
          });
    
        // Alternatively, you could also refresh the data of a specific dashboard item
        // dashboardInstance.current.refreshData(
        //   "< (Optional) id of a specific dashboard item to refresh >"
        // ).then(() => {
        //     // Successfully refreshed the data of a specific dashboard item!
        //   });
      };
    
      return (
        <div>
          <button onClick={() => refreshData()}>Refresh data</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    }
    
     Refreshes the data when the button is clicked.
    import { useRef } from 'react';
    ...
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const refreshData = () => {
        // Refresh the data of all items using the refreshData method
        dashboardInstance.current.refreshData()
          .then(() => {
            // Successfully refreshed the data of all items in the embedded dashboard!
          });
    
        // Alternatively, you could also refresh the data of a specific dashboard item
        // dashboardInstance.current.refreshData(
        //   "< (Optional) id of a specific dashboard item to refresh >"
        // ).then(() => {
          // Successfully refreshed the data of a specific dashboard item!
        // });
      };
    
      return (
        <div>
          <button onClick={() => refreshData()}>Refresh data</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    
     Refreshes the data when the button is clicked
    <template>
      ...
      <button @click="refreshData">Refresh data</button>
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
      ...
    </template>
    <script>
      export default {
        methods: {
          refreshData() {
            // Refresh the data of all items using the refreshData method
            this.$refs.dashboardInstance.refreshData()
              .then(() => {
                // Successfully refreshed the data of all items in the embedded dashboard!
              });
    
            // Alternatively, you could also refresh the data of a specific dashboard item
            // this.$refs.dashboardInstance.refreshData(
            //   "< (Optional) id of a specific dashboard item to refresh >"
            // ).then(() => {
              // Successfully refreshed the data of a specific dashboard item!
            // });
          },
          ...
        },
        ...
      }
    </script>
    

    The refreshData method is used to refresh the data of all items in an embedded dashboard. If the itemId argument is specified, only this specific dashboard item's data will be refreshed.

    Parameter Description
    itemId
    uuid
    (Optional) The id of the dashboard item for which the data needs to be refreshed. Here we explain how to find the UUID of a dashboard item in our dashboard editor.

    In Angular, the refreshData method is an Observable to which you can subscribe an observer function to. The observable will deliver no value.

    The refreshData method returns a Promise that "resolves" with no value.

    getFilters

    The getFilters method is used to get all active filters in an embedded dashboard. It can be useful when using bi-directional communication with an embedded dashboard, e.g. if you'd like to enable your users to save the currently applied filters of an embedded dashboard (a step-by-step guide for this setup can be found in this Academy article).

    Usage
      Get all active filters when the button is clicked
    ...
      <button id="get-filters-button">Get active filters</button>
      <luzmo-dashboard
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
    ...
    <script>
      // Get the button reference
      const getFiltersButton = document.getElementById("get-filters-button");
    
      // Get the component reference
      // Note: only returns the first occurrence of a Luzmo component within the document.
      const dashboardComponent = document.querySelector("luzmo-dashboard");
    
      // Add an event listener to the click event on the button
      getFiltersButton.onclick = () => {
        // Get all active filters using the getFilters method
        dashboardComponent.getFilters().then((activeFilters) => {
          // Do something with the active filters of the embedded dashboard
        });
      };
    </script>
    
    1 We define a button and the Luzmo component in an Angular page
    <button (click)="getFilters()">Get active filters</button>
    <luzmo-dashboard
      #dashboardInstance
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< Initial SSO Authorization key >'"
      [authToken]="'< Initial SSO Authorization token >'"
      [dashboardId]="'< Dashboard ID >'"
    ></luzmo-dashboard>
    
    2 In the Angular Component file, we used the getFilters method to get all active filters when the button is clicked
    import {  Component, ViewChild } from '@angular/core';
    import { take } from 'rxjs/operators';
    ...
    import {
      NgxLuzmoDashboardModule,
      FilterGroup
    } from '@luzmo/ngx-embed';
    ...
    
    @Component({
      ...
    })
    
    export class LuzmoEmbeddingComponent {
      // Component reference
      @ViewChild('dashboardInstance') dashboardInstance: NgxLuzmoDashboardModule;
    
      getFilters(): void {
        // Get all active filters using the getFilters method
        this.dashboardInstance.getFilters()
          .pipe(take(1))
          .subscribe((activeFilters: FilterGroup[]) => {
            // Do something with the active filters of the embedded dashboard!
          });
      }
    }
    
     Get all active filters when the button is clicked.
    import { useRef } from 'react';
    ...
    import {
      LuzmoDashboardComponent
    } from '@luzmo/react-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const getFilters = () => {
        // Get all active filters using the getFilters method
        dashboardInstance.current.getFilters()
          .then((activeFilters) => {
            // Do something with the active filters of the embedded dashboard!
          });
      };
    
      return (
        <div>
          <button onClick={() => getFilters()}>Get active filters</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    }
    
     Get all active filters when the button is clicked.
    import { useRef } from 'react';
    ...
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const getFilters = () => {
        // Get all active filters using the getFilters method
        dashboardInstance.current.getFilters()
          .then((activeFilters) => {
            // Do something with the active filters of the embedded dashboard!
          });
      };
    
      return (
        <div>
          <button onClick={() => getFilters()}>Get active filters</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    
     Get all active filters when the button is clicked
    <template>
      ...
      <button @click="getFilters">Get active filters</button>
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
      ...
    </template>
    <script>
      export default {
        methods: {
          getFilters() {
            // Get all active filters using the getFilters method
            this.$refs.dashboardInstance.getFilters()
              .then((activeFilters) => {
                // Do something with the active filters of the embedded dashboard!
              });
          },
          ...
        },
        ...
      }
    </script>
    

    The getFilters method does not have any arguments to specify.

    Response
       Once the getFilters promise is resolved, an array of filter groups will be returned as value 
       The getFilters Observable will deliver an array value containing all the filter groups 
    [
      {
        "id": "<auto_generated_filter_group_id>",
        "origin": "< 'filterFromVizItem', 'filterFromFilterItem', 'itemFilter', or 'global' >",
        "condition": "< 'and', or 'or' >",
        "filters": [
          {
            "expression": "< filter expression >",
            "parameters": [
              {
                "datasetId": "< dataset id >",
                "columnId": "< dataset column id >"
              },
              < filter value(s) >
            ],
            "properties": {
              "id": "<auto_generated_filter_id>",
              "origin": "< 'filterFromVizItem', 'filterFromFilterItem', 'itemFilter', or 'global' >",
              "type": "< 'having', or 'where' >",
              "itemId": "< dashboard item id (not available for filters with origin 'global')>"
            }
          }
        ],
        "subGroups": [
          // Filter groups within filter group
        ],
        "itemId": "< dashboard item id (not available for filter groups with origin 'global') >",
        "datasetId": "< dataset id (only available for filter groups with origin 'global') >"
      },
      ... // Other filter groups
    ]
    

    In Angular, the getFilters method is an Observable to which you can subscribe an observer function to. The observable will deliver an array of FilterGroup elements containing the active filters.

    The getFilters method returns a Promise that resolves with an array value containing the active filters as objects.

    Property Description
    id
    uuid
    (Auto-generated) The UUID of the filter group.
    origin
    string
    The resource type from where the filter group originates from, either:
    • "itemFilter": A static filter that has been set up on a dashboard item when designing the dashboard. Also called a chart filter.
    • "global": A static filter that has been set up on a dataset in the dashboard when designing the dashboard. Also called a dashboard filter (in side bar of the dashboard editor -> filters -> dashboard filters)..
    condition
    string
    The filter condition between the different filters in this group, either and or or.
    filters
    array[object]
    A list of the different filters in the filter group.
    expression
    string
    The filter expression of the filter that is applied.
    See this Academy article for a list of supported filter expressions per column type).
    parameters
    array
    The parameters of the filter.
    • The first element in this array is an object containing the datasetId, columnId, and level (only for datetime and hierarchy columns) of the filter.
    • The second element is the filter value itself.
      See this Academy article for the different values to expect for different filter expressions.
    properties
    object
    The properties related to the filter.
    id
    uuid
    (Auto-generated) The UUID of the filter.
    origin
    string
    The resource type from where the filter itself originates from, either:
    • "filterFromVizItem": A runtime filter from a non-filter dashboard item (i.e. filter from an interactive chart widget).
    • "filterFromFilterItem": A runtime filter from a filter dashboard item (i.e. from a 'Date filter', 'Slider', or '(Rank) Slicer' widget).
    • "itemFilter": A static filter that has been set up on a dashboard item when designing the dashboard. Also called a chart filter.
    • "global": A static filter that has been set up on a dataset in the dashboard when designing the dashboard. Also called a dashboard filter (can be found in side bar of the dashboard editor -> filters -> dashboard filters).
    type
    string
    The filter type of the filter. Depending on the filter origin and expression, this would be either having or where.
    itemId
    uuid
    The id of the dashboard item where this filter originates from.
    Note: this is not available for filters with origin global. These filters do not originate from a specific dashboard item, and are instead applied on a dataset level (i.e. all dashboard items querying that dataset will be filtered by this filter).
    subGroups
    array[object]
    A list of the filter subgroups within this filter group. Each of these objects is a filter group itself.
    itemId
    uuid
    The id of the dashboard item where this filter group has been set up.
    Note: this is not available for filter groups with origin global (instead of an itemId, filter groups with origin global would contain a datasetId, see property below). Such filter groups were not set up on a specific dashboard item, but on a dataset level in the dashboard editor (i.e. all dashboard items querying that dataset will be filtered by this filter group).
    datasetId
    uuid
    The id of the dataset where this filter group has been set up.
    Note: this is only available for filter groups with origin global.

    getData

    The getData method is used to get the data of the specific dashboard item as it is visualized in an embedded dashboard (i.e. taking into account all active filters applied on this dashboard item).

    Usage
      Gets the data of a specific dashboard item when the button is clicked.
    ...
      <button id="get-data-button">Get dashboard item data</button>
      <luzmo-dashboard
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
    ...
    <script>
      // Get the button reference
      const getDataButton = document.getElementById("get-data-button");
    
      // Get the component reference
      // Note: only returns the first occurrence of a Luzmo component within the document.
      const dashboardComponent = document.querySelector("luzmo-dashboard");
    
      // Add an event listener to the click event on the button
      getDataButton.onclick = () => {
        // Get the data of a specific dashboard item
        dashboardComponent.getData(
          "< id of a specific dashboard item to retrieve the data from >"
        ).then((data) => {
          // Do something with the data of the dashboard item
        });
      };
    </script>
    
    1 We define a button and the Luzmo component in an Angular page
    <button (click)="getData()">Get dashboard item data</button>
    <luzmo-dashboard
      #dashboardInstance
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< Initial SSO Authorization key >'"
      [authToken]="'< Initial SSO Authorization token >'"
      [dashboardId]="'< Dashboard ID >'"
    ></luzmo-dashboard>
    
    2 In the Angular Component file, we use the getData method to get the data of a specific dashboard item when the button is clicked.
    import {  Component, ViewChild } from '@angular/core';
    import { take } from 'rxjs/operators';
    ...
    import {
      NgxLuzmoDashboardModule,
      ItemData
    } from '@luzmo/ngx-embed';
    ...
    
    @Component({
      ...
    })
    
    export class LuzmoEmbeddingComponent {
      // Component reference
      @ViewChild('dashboardInstance') dashboardInstance: NgxLuzmoDashboardModule;
    
      getData(): void {
        // Get the data of a specific dashboard item
        this.dashboardInstance.getData(
          "< id of a specific dashboard item to retrieve the data from >"
        ).pipe(take(1))
        .subscribe((data: ItemData) => {
          // Do something with the data of the dashboard item
        });
      }
    }
    
     Gets the data of a specific dashboard item when the button is clicked.
    import { useRef } from 'react';
    ...
    import {
      LuzmoDashboardComponent
    } from '@luzmo/react-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const getData = () => {
        // Get the data of a specific dashboard item
        dashboardInstance.current.getData(
          "< id of a specific dashboard item to retrieve the data from >"
        ).then((data) => {
          // Do something with the data of the dashboard item
        });
      };
    
      return (
        <div>
          <button onClick={() => getData()}>Get dashboard item data</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    }
    
     Gets the data of a specific dashboard item when the button is clicked.
    import { useRef } from 'react';
    ...
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const getData = () => {
        // Get the data of a specific dashboard item
        dashboardInstance.current.getData(
          "< id of a specific dashboard item to retrieve the data from >"
        ).then((data) => {
          // Do something with the data of the dashboard item
        });
      };
    
      return (
        <div>
          <button onClick={() => getData()}>Get dashboard item data</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    
     Gets the data of a specific dashboard item when the button is clicked.
    <template>
      ...
      <button @click="getData">Get dashboard item data</button>
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
      ...
    </template>
    <script>
      export default {
        methods: {
          getData() {
            // Get the data of a specific dashboard item
            this.$refs.dashboardInstance.getData(
              "< id of a specific dashboard item to retrieve the data from >"
            ).then((data) => {
              // Do something with the data of the dashboard item
            });
          },
          ...
        },
        ...
      }
    </script>
    
    Parameter Description
    itemId
    uuid REQUIRED
    The id of the dashboard item for which you'd like to retrieve the data shown. Here we explain how to find the UUID of a dashboard item in our dashboard editor.
    Response
      Once the getData promise is resolved, an array of the data points will be returned as value. 
    Below you can see an example of the response of getData on a line chart that visualizes the total clicks per year (for 2022 and 2023) per transaction type (Online and Offline).
    [
      [
        "2022-01-01T00:00:00.000Z",
        {
          "id": "Online",
          "name": {
            "nl": "Online",
            "fr": "En ligne",
            "en": "Online"
          },
          "color": "rgb(0,255,0)"
        },
        2010843
      ],
      [
        "2022-01-01T00:00:00.000Z",
        {
          "id": "Offline",
          "name": {
            "nl": "Offline",
            "fr": "Hors ligne",
            "en": "Offline"
          },
          "color": "rgb(255,0,0)"
        },
        1912666
      ],
      [
        "2023-01-01T00:00:00.000Z",
        {
          "id": "Online",
          "name": {
            "nl": "Online",
            "fr": "En ligne",
            "en": "Online"
          },
          "color": "rgb(0,255,0)"
        },
        5323286
      ],
      [
        "2023-01-01T00:00:00.000Z",
        {
          "id": "Offline",
          "name": {
            "nl": "Offline",
            "fr": "Hors ligne",
            "en": "Offline"
          },
          "color": "rgb(255,0,0)"
        },
        5093799
      ]
    ]
    

    In Angular, the getData method is an Observable to which you can subscribe an observer function to. The observable will deliver an ItemData value, which is an array of arrays that includes the values of the data points in the dashboard item.

    The getData method returns a Promise that resolves with an array of arrays value, where each inner array contains the values of a specific data point in the dashboard item.

    The actual data returned will depend on the specific dashboard item and slot configuration.

    exportDashboard

    The exportDashboard method is used to download a snapshot of the embedded dashboard in either PNG or PDF format.

    Usage
      Creates a PNG/PDF export of an embedded dashboard when the button is clicked.
    ...
      <button id="export-dashboard-button">Export dashboard</button>
      <luzmo-dashboard
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
    ...
    <script>
      // Get the button reference
      const exportDashboardButton = document.getElementById("export-dashboard-button");
    
      // Get the component reference
      // Note: only returns the first occurrence of a Luzmo component within the document.
      const dashboardComponent = document.querySelector("luzmo-dashboard");
    
      // Add an event listener to the click event on the button
      exportDashboardButton.onclick = () => {
        // Call the exportDashboard method (specifying the desired export type as argument)
        dashboardComponent.exportDashboard(
          "< export type, either 'pdf' or 'png' >"
        ).then((exportMetadataObject) => {
          // Started downloading export!
          // The exportMetadataObject will contain some metadata about the export itself
        });
      };
    </script>
    
    1 We define a button and the Luzmo component in an Angular page
    <button (click)="exportDashboard()">Export dashboard</button>
    <luzmo-dashboard
      #dashboardInstance
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< Initial SSO Authorization key >'"
      [authToken]="'< Initial SSO Authorization token >'"
      [dashboardId]="'< Dashboard ID >'"
    ></luzmo-dashboard>
    
    2 In the Angular Component file, we use the getData method to get the data of a specific dashboard item when the button is clicked.
    import {  Component, ViewChild } from '@angular/core';
    import { take } from 'rxjs/operators';
    ...
    import {
      NgxLuzmoDashboardModule,
      ExportType,
      ExportDashboard
    } from '@luzmo/ngx-embed';
    ...
    
    @Component({
      ...
    })
    
    export class LuzmoEmbeddingComponent {
      // Component reference
      @ViewChild('dashboardInstance') dashboardInstance: NgxLuzmoDashboardModule;
    
      desiredExportType: ExportType = "pdf";
    
      exportDashboard(): void {
        // Get the data of a specific dashboard item
        this.dashboardInstance.exportDashboard(this.desiredExportType).pipe(take(1))
        .subscribe((exportMetadataObject: ExportDashboard) => {
          // Started downloading export!
          // The exportMetadataObject will contain some metadata about the export itself
        });
      }
    }
    
     Creates a PNG/PDF export of an embedded dashboard when the button is clicked.
    import { useRef } from 'react';
    ...
    import {
      LuzmoDashboardComponent
    } from '@luzmo/react-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const exportDashboard = () => {
        // Call the exportDashboard method (specifying the desired export type as argument)
        dashboardInstance.current.exportDashboard(
          "< export type, either 'pdf' or 'png' >"
        ).then((exportMetadataObject) => {
          // Started downloading export!
          // The exportMetadataObject will contain some metadata about the export itself
        });
      };
    
      return (
        <div>
          <button onClick={() => exportDashboard()}>Export dashboard</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    }
    
     Creates a PNG/PDF export of an embedded dashboard when the button is clicked.
    import { useRef } from 'react';
    ...
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const exportDashboard = () => {
        // Call the exportDashboard method (specifying the desired export type as argument)
        dashboardInstance.current.exportDashboard(
          "< export type, either 'pdf' or 'png' >"
        ).then((exportMetadataObject) => {
          // Started downloading export!
          // The exportMetadataObject will contain some metadata about the export itself
        });
      };
    
      return (
        <div>
          <button onClick={() => exportDashboard()}>Export dashboard</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    
     Creates a PNG/PDF export of an embedded dashboard when the button is clicked.
    <template>
      ...
      <button @click="exportDashboard">Export dashboard</button>
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
      ...
    </template>
    <script>
      export default {
        methods: {
          exportDashboard() {
            // Call the exportDashboard method (specifying the desired export type as argument)
            this.$refs.dashboardInstance.exportDashboard(
              "< export type, either 'pdf' or 'png' >"
            ).then((exportMetadataObject) => {
              // Started downloading export!
              // The exportMetadataObject will contain some metadata about the export itself
            });
          },
          ...
        },
        ...
      }
    </script>
    
    Parameter Description
    format
    string
    (Optional) File format of the exported dashboard. Can be either 'png' or 'pdf'. If not specified, the format defaults to 'png'.
    We recommend to specify 'pdf' for the highest export quality, as most of our dashboard items will be rendered as SVGs without quality loss!
    Response
      Once the exportDashboard promise is resolved, the export will immediately download. The following object will be resolved as value and contains some metadata about the export.
    {
      "name": "<autogenerated_dashboard_embed_element_name>",
      "language": "< dashboard language identifier, e.g. 'en', 'fr', etc. >",
      "requestId": "<autogenerated_export_request_id>",
      "type": "export",
      "dashboardId": "< dashboard ID >",
      "screenMode": "< screen mode of the export >"
    }
    

    In Angular, the exportDashboard method is an Observable to which you can subscribe an observer function to. Once the export has been prepared, the export file will download as 'export.pdf' or 'export.png'. Next to that, the observable will deliver an ExportDashboard value containing some metadata about the export: the dashboard language (language), the dashboard screen mode (screenMode), and the dashboard ID (dashboardId).

    The exportDashboard method returns a Promise, once resolved it will download the export file as 'export.pdf' or 'export.png'.
    It will also resolve an object value containing some metadata about the export: the dashboard language (language), the dashboard screen mode (screenMode), and the dashboard ID (dashboardId).

    getAccessibleDashboards

    You can make use of the getAccessibleDashboards method in your frontend to dynamically retrieve a list of dashboards. The dashboards that are returned are associated with the specific integration that the SSO key and token has access to, the Suborganization the SSO user is part of, and the bootstrapped SSO user.
    This is particularly useful if you'd like to have a dynamic way of retrieving and providing dashboards in your frontend! Some use-cases are described in this Academy article.

    Usage
       First we pass along a SSO key and token to the Web component, and then we call the getAccessibleDashboards method to retrieve the dashboards that are accessible to that key-token pair
    <html>
      <luzmo-dashboard
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
      ></luzmo-dashboard>
    </html>
    
    <script>
      // Get the component reference
      // Note: only returns the first occurrence of a Luzmo component within the document.
      const dashboardElement = document.querySelector("luzmo-dashboard");
    
      // Set the SSO Authorization key and token pair
      dashboardElement.authKey = "< SSO Authorization Key >";
      dashboardElement.authToken = "< SSO Authorization Token >";
    
      // Retrieve the dashboards that are accessible to the SSO Authorization token
      dashboardElement.getAccessibleDashboards()
          .then(dashboards => {
              // Do something with the response, e.g. dynamically fill your application's navigation
              console.log(dashboards);
          });
    </script>
    
    1 Add the Luzmo component in your Angular page
    <luzmo-dashboard
      #dashboardInstance
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
    ></luzmo-dashboard>
    
    2 In your Angular Component file, add the following code to set a SSO key & token, and then retrieve the accessible dashboards
    import {  OnInit, Component, ViewChild } from '@angular/core';
    ...
    import {
      NgxLuzmoDashboardModule,
      AccessibleDashboard
    } from '@luzmo/ngx-embed';
    ...
    
    @Component({
      ...
    })
    
    export class LuzmoEmbeddingComponent implements OnInit {
      // Component reference
      @ViewChild('dashboardInstance') dashboardInstance: NgxLuzmoDashboardModule;
    
      ngOnInit(): void {
        // Set the SSO Authorization key and token pair
        this.dashboardInstance.authKey = "< SSO Authorization Key >";
        this.dashboardInstance.authToken = "< SSO Authorization Token >";
    
        // Retrieve the dashboards that are accessible to the SSO Authorization token
        this.dashboardInstance.getAccessibleDashboards().pipe(take(1)).subscribe((dashboards: AccessibleDashboard[]) => {
          // Do something with the response, e.g. dynamically fill your application's navigation
          console.log(dashboards);
        });
      }
    }
    
     First we pass along a SSO key and token to the React component, and then we call the getAccessibleDashboards method to retrieve the dashboards that are accessible to that key-token pair
    import { useRef } from 'react';
    ...
    import {
      LuzmoDashboardComponent
    } from "@luzmo/react-embed";
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      // Set the SSO Authorization key and token pair
      dashboardInstance.current.authKey = = "< SSO Authorization Key >";
      dashboardInstance.current.authToken = "< SSO Authorization Token >";
    
      // Retrieve the dashboards that are accessible to the SSO Authorization token
      dashboardInstance.current.getAccessibleDashboards().then(dashboards => {
        // Do something with the response, e.g. dynamically fill your application's navigation
        console.log(dashboards);
      });
    
      return (
        <LuzmoDashboardComponent
          ref={dashboardInstance}
          appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
          apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        ></LuzmoDashboardComponent>
      );
    }
    
     First we pass along a SSO key and token to the React Native component, and then we call the getAccessibleDashboards method to retrieve the dashboards that are accessible to that key-token pair
    import { useRef } from 'react';
    ...
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      // Set the SSO Authorization key and token pair
      dashboardInstance.current.authKey = = "< SSO Authorization Key >";
      dashboardInstance.current.authToken = "< SSO Authorization Token >";
    
      // Retrieve the dashboards that are accessible to the SSO Authorization token
      dashboardInstance.current.getAccessibleDashboards().then(dashboards => {
        // Do something with the response, e.g. dynamically fill your application's navigation
        console.log(dashboards);
      });
    
      return (
        <LuzmoDashboardComponent
          ref={dashboardInstance}
          appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
          apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        ></LuzmoDashboardComponent>
      );
    
     First we pass along a SSO key and token to the Vue component, and then we call the getAccessibleDashboards method to retrieve the dashboards that are accessible to that key-token pair
    <template>
      ...
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
      ></luzmo-dashboard>
      ...
    </template>
    <script>
      export default {
        mounted() {
          // Set the SSO Authorization key and token pair
          this.$refs.dashboardInstance.authKey = = "< SSO Authorization Key >";
          this.$refs.dashboardInstance.authToken = "< SSO Authorization Token >";
    
          // Retrieve the dashboards that are accessible to the SSO Authorization token
          this.$refs.dashboardInstance.getAccessibleDashboards().then(dashboards => {
            // Do something with the response, e.g. dynamically fill your application's navigation
            console.log(dashboards);
          });
        },
        ...
      }
    </script>
    

    The getAccessibleDashboards method does not have any arguments to specify.

    Response
       This returns an array of dashboards, together with some relevant information related to each dashboard: 
    [
        {
            "id": "< dashboard_1_id >",
            "modifiedAt": "2021-02-10T09:13:27.114Z",
            "name": "< dashboard_1_name >",
            "slug": null,
            "tags": [
                "< dashboard_1_tag_1 >",
                "< dashboard_1_tag_2 >"
            ],
            "accessibleBy": [
                {
                    "model": "User",
                    "id": "< user_A_id >",
                    "name": "< user_A_name >"
                },
                {
                    "model": "User",
                    "id": "< user_B_id >",
                    "name": "< user_B_name >"
                },
                {
                    "model": "Group",
                    "id": "< group_id >",
                    "name": "< group_name >"
                },
                {
                    "model": "Integration",
                    "id": "< integration_id >",
                    "name": "< integration_name >"
                }
            ],
            "accessRights": {
                "flagRead": true,
                "flagUse": true,
                "flagModify": false,
                "flagOwn": false
            }
        },
        ...
    ]
    

    In Angular, the getAccessibleDashboards method is an Observable to which you can subscribe an observer function to. The observable will deliver an array of AccessibleDashboard elements.

    The getAccessibleDashboards method returns a Promise that resolves with an array value containing the accessible dashboards.

    Property Description
    id
    UUID
    The ID of the dashboard.
    modifiedAt
    datetime
    RFC3339 datetime value on which the dashboard was last modified.
    name
    string
    The name of the dashboard.
    slug
    string
    The slug of the dashboard (as set up in the Integration).
    tags
    array[string]
    The list of tags associated to the dashboard.
    More information about tags can be found in this Academy article!
    accessibleBy
    array[object]
    The list of resources through which this dashboard is accessible. Each object in this list will contain a model property that mentions the resources' model name, an id property that references the specific resource's UUID, and a name property that references the specific resource's name!
    More information about the different access granularity can be found in this Academy article.
    accessRights
    object
    The highest access right the SSO Authorization token has on the dashboard, based on all access rights given to one or multiple of the 'accessibleBy' resources.
    More information about the different access rights on a dashboard can be found in here.

    setEditMode

    You can use the setEditMode method to programmatically switch an embedded dashboard to the desired view or edit mode. This might be interesting in case your application's navigation allows a user to switch from one embedded dashboard to another, and the dashboard's edit mode should not be persisted when loading another dashboard with the same component.
    Alternatively, changing the editMode property of the frontend component will result in a persisted edit mode when specifying another dashboardId or dashboardSlug property.

      Sets the edit mode of the currently embedded dashboard when the button is clicked.
    ...
      <button id="set-edit-mode-button">Set edit mode</button>
      <luzmo-dashboard
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
    ...
    <script>
      // Get the button reference
      const setEditModeButton = document.getElementById("set-edit-mode-button");
    
      // Get the component reference
      // Note: only returns the first occurrence of a Luzmo component within the document.
      const dashboardComponent = document.querySelector("luzmo-dashboard");
    
      // Add an event listener to the click event on the button
      setEditModeButton.onclick = () => {
        // Set the edit mode of the currently embedded dashboard
        dashboardComponent.setEditMode(
          "< edit mode, either 'view', 'editLimited' or 'editFull' >"
        ).then(() => {
          // Successfully switched to the edit mode specified!
        }).catch((error) => {
          // Switching to the edit mode failed
          console.log("Error: ", error.msg);
        });
      };
    </script>
    
    1 We define a button and the Luzmo component in an Angular page
    <button (click)="setEditMode()">Export dashboard</button>
    <luzmo-dashboard
      #dashboardInstance
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< Initial SSO Authorization key >'"
      [authToken]="'< Initial SSO Authorization token >'"
      [dashboardId]="'< Dashboard ID >'"
    ></luzmo-dashboard>
    
    2 In the Angular Component file, we use the setEditMode method to set the edit mode of the currently embedded dashboard when the button is clicked.
    import {  Component, ViewChild } from '@angular/core';
    import { take } from 'rxjs/operators';
    ...
    import {
      NgxLuzmoDashboardModule,
      SetEditMode
    } from '@luzmo/ngx-embed';
    ...
    
    @Component({
      ...
    })
    
    export class LuzmoEmbeddingComponent {
      // Component reference
      @ViewChild('dashboardInstance') dashboardInstance: NgxLuzmoDashboardModule;
    
      newEditMode: SetEditMode = {
        editMode: "editLimited"
      };
    
      setEditMode(): void {
        // Set the edit mode of the currently embedded dashboard
        this.dashboardInstance.setEditMode(this.newEditMode.editMode).pipe(take(1))
        .subscribe(
          () => {
            // Successfully switched to the edit mode specified!
          },
          (error: any) => {
            // Switching to the edit mode failed
            console.log("Error: ", error.msg);
          }
        );
      }
    }
    
     Sets the edit mode of the currently embedded dashboard when the button is clicked.
    import { useRef } from 'react';
    ...
    import {
      LuzmoDashboardComponent
    } from '@luzmo/react-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const setEditMode = () => {
        // Set the edit mode of the currently embedded dashboard
        dashboardInstance.current.setEditMode(
          "< edit mode, either 'view', 'editLimited' or 'editFull' >"
        ).then(() => {
          // Successfully switched to the edit mode specified!
        }).catch((error: any) => {
          // Switching to the edit mode failed
          console.log("Error: ", error.msg);
        });
      };
    
      return (
        <div>
          <button onClick={() => setEditMode()}>Export dashboard</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    }
    
     Sets the edit mode of the currently embedded dashboard when the button is clicked.
    import { useRef } from 'react';
    ...
    import LuzmoDashboardComponent from '@luzmo/react-native-embed';
    ...
    
    export function LuzmoWrapper() {
      // Component reference
      const dashboardInstance = useRef(null);
    
      const setEditMode = () => {
        // Set the edit mode of the currently embedded dashboard
        dashboardInstance.current.setEditMode(
          "< edit mode, either 'view', 'editLimited' or 'editFull' >"
        ).then(() => {
          // Successfully switched to the edit mode specified!
        }).catch((error: any) => {
          // Switching to the edit mode failed
          console.log("Error: ", error.msg);
        });
      };
    
      return (
        <div>
          <button onClick={() => setEditMode()}>Export dashboard</button>
          <LuzmoDashboardComponent
            ref={dashboardInstance}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< Initial SSO Authorization key >"
            authToken="< Initial SSO Authorization token >"
            dashboardId="< Dashboard ID >"
          ></LuzmoDashboardComponent>
        </div>
      );
    
     Sets the edit mode of the currently embedded dashboard when the button is clicked.
    <template>
      ...
      <button @click="setEditMode">Export dashboard</button>
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
      ...
    </template>
    <script>
      export default {
        methods: {
          setEditMode() {
            // Set the edit mode of the currently embedded dashboard
            this.$refs.dashboardInstance.setEditMode(
              "< edit mode, either 'view', 'editLimited' or 'editFull' >"
            ).then(() => {
              // Successfully switched to the edit mode specified!
            }).catch((error: any) => {
              // Switching to the edit mode failed
              console.log("Error: ", error.msg);
            });
          },
          ...
        },
        ...
      }
    </script>
    
    Parameter Description
    editMode
    string REQUIRED
    The desired edit mode the dashboard should switch to.
    Accepted values for this parameter:
    • view
      This mode enables your users to view and interact with an embedded dashboard, without having the option to change the dashboard itself.
    • editLimited
      This mode is useful if you have your own dashboard navigation in your application (e.g. a sidebar containing dashboard tabs or a dropdown) and would like the user to edit (some of) the dashboards (e.g. by adding an “Edit” button that toggles the editMode between “view” and “editLimited” mode). Users will be able to create variants of the dashboard or edit the dashboard itself (depending on the access rights you defined for the dashboard) and share these dashboard (variants) with other users in their organization.
    • editFull
      If you have a dedicated place in your application where users should be able to create & edit all their accessible dashboard(s) (e.g. in your navigation bar you have a “Dashboard editor” tab that should show the embedded dashboard editor). The user will be able to create edit, duplicate and create a variant of existing dashboards (depending on the access rights you defined for the dashboard) as well as create new dashboards and share these dashboard (variants) with other users in their organization.



    In Angular, the refreshData method is an Observable to which you can subscribe an observer function to. The observable will deliver no value if the dashboard's edit mode switched successfully, the handler for an error notification will receive an error if it failed to switch to the specified edit mode.

    The setEditMode method returns a Promise that "resolves" with no value if the dashboard's edit mode switched successfully, or with an error if it failed to switch to the specified edit mode.

    Failing to switch can happen in the following cases:

    Events

    The embed libraries emit events when certain actions in an embedded dashboard take place. Below you can find more information about how to set up an event listener to these events, as well as details on each of the available events you can optionally listen to!

    We currently expose the following events:

    Listening to events

    In the code example you can see how you can set up an event listener to listen to one or more of the desired events!

      Setting up event listeners to all available dashboard events.
    ...
      <luzmo-dashboard
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< Initial SSO Authorization key >"
        authToken="< Initial SSO Authorization token >"
        dashboardId="< Dashboard ID >"
      ></luzmo-dashboard>
    ...
    <script>
      // Get the component reference
      // Note: only returns the first occurrence of a Luzmo component within the document.
      const dashboardComponent = document.querySelector("luzmo-dashboard");
    
      // Add an event listener to the load event
      dashboardComponent.addEventListener("load", (event) => {
        // Do something after the dashboard has loaded
      });
    
      // Add an event listener to the changedFilters event
      dashboardComponent.addEventListener("changedFilters", (event) => {
        // Do something if an interactivity filter in the dashboard has changed
      });
    
      // Add an event listener to the itemsRendered event
      dashboardComponent.addEventListener("itemsRendered", (event) => {
        // Do something after all dashboard items have rendered
      });
    
      // Add an event listener to the exported event
      dashboardComponent.addEventListener("exported", (event) => {
        // Do something after a dashboard (item) has been exported
      });
    
      // Add an event listener to the customEvent event
      dashboardComponent.addEventListener("customEvent", (event) => {
        // Do something if a custom event is thrown from a dashboard item
      });
    </script>
    
    1 We the Luzmo component in an Angular page, and set up the appropriate callback methods for the available dashboard events
    <luzmo-dashboard
      [appServer]="'< Luzmo App server, defaults to https://app.luzmo.com >'"
      [apiHost]="'< Luzmo API server, defaults to https://api.luzmo.com >'"
      [authKey]="'< SSO authorization key >'"
      [authToken]="'< SSO authorization token >'"
      [dashboardId]="'< dashboard id you want to embed >'"
      (load)="actUponLoadEvent($event)"
      (changedFilters)="actUponChangedFiltersEvent($event)"
      (itemsRendered)="actUponItemsRenderedEvent($event)"
      (exported)="actUponExportedEvent($event)"
      (customEvent)="actUponCustomEventsEvent($event)"
    ></luzmo-dashboard>
    
    2 In the Angular Component file, we defined the callback methods that should be called every time a specific event is emitted
    ...
    import {
      LoadEvent,
      ChangedFiltersEvent,
      ItemsRenderedEvent,
      ExportedEvent,
      CustomEvent
    } from '@luzmo/ngx-embed';
    
    @Component({
      ...
    })
    
    export class LuzmoEmbeddingComponent {
      ...
    
      actUponLoadEvent(loadEvent: LoadEvent): void {
        // Do something after the dashboard has loaded
      }
    
      actUponChangedFiltersEvent(changedFiltersEvent: ChangedFiltersEvent): void {
        // Do something if an interactivity filter in the dashboard has changed
      }
    
      actUponItemsRenderedEvent(itemsRenderedEvent: ItemsRenderedEvent): void {
        // Do something after all dashboard items have rendered
      }
    
      actUponCustomEventsEvent(exportedEvent: ExportedEvent): void {
        // Do something after a dashboard (item) has been exported
      }
    
      actUponCustomEventsEvent(customEventsEvent: CustomEvent): void {
        // Do something if a custom event is thrown from a dashboard item
      }
    }
    
    ...
    
      function LuzmoWrapper() {
        ...
    
        const actUponLoadEvent = (loadEvent) => {
          // Do something after the dashboard has loaded
        }
    
        const actUponChangedFiltersEvent = (changedFiltersEvent) => {
          // Do something if an interactivity filter in the dashboard has changed
        }
    
        const actUponItemsRenderedEvent = (itemsRenderedEvent) => {
          // Do something after all dashboard items have rendered
        }
    
        const actUponCustomEventsEvent = (exportedEvent) {
          // Do something after a dashboard (item) has been exported
        }
    
        const actUponCustomEventsEvent = (customEventsEvent) => {
          // Do something if a custom event is thrown from a dashboard item
        }
        ...
    
        return (
          <LuzmoDashboardComponent
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< SSO authorization key >"
            authToken="< SSO authorization token >"
            dashboardId="< dashboard id you want to embed >"
            dashboardSlug="< instead of dashboardId: a dashboard slug as specified in the Integration. >"
            load="actUponLoadEvent"
            changedFilters="actUponChangedFiltersEvent"
            itemsRendered="actUponItemsRenderedEvent"
            customEvent="actUponCustomEventsEvent"
          ></LuzmoDashboardComponent>
        );
      }
    
    ...
    
      function LuzmoWrapper() {
        ...
        const actUponLoadEvent = (loadEvent) => {
          // Do something after the dashboard has loaded
        }
    
        const actUponChangedFiltersEvent = (changedFiltersEvent) => {
          // Do something if an interactivity filter in the dashboard has changed
        }
    
        const actUponItemsRenderedEvent = (itemsRenderedEvent) => {
          // Do something after all dashboard items have rendered
        }
    
        const actUponCustomEventsEvent = (exportedEvent) {
          // Do something after a dashboard (item) has been exported
        }
    
        const actUponCustomEventsEvent = (customEventsEvent) => {
          // Do something if a custom event is thrown from a dashboard item
        }
        ...
    
        return (
          <LuzmoDashboardComponent
            ref={ref}
            appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
            apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
            authKey="< SSO authorization key >"
            authToken="< SSO authorization token >"
            dashboardId="< dashboard id you want to embed >"
            dashboardSlug="< instead of dashboardId: a dashboard slug as specified in the Integration. >"
            load="actUponLoadEvent"
            changedFilters="actUponChangedFiltersEvent"
            itemsRendered="actUponItemsRenderedEvent"
            customEvent="actUponCustomEventsEvent"
          ></LuzmoDashboardComponent>
        );
      }
    
    <template>
      ...
      <luzmo-dashboard
        ref="dashboardInstance"
        appServer="< Luzmo App server, defaults to https://app.luzmo.com >"
        apiHost="< Luzmo API server, defaults to https://api.luzmo.com >"
        authKey="< SSO authorization key >"
        authToken="< SSO authorization token >"
        dashboardId="< dashboard id you want to embed >"
        dashboardSlug="< instead of dashboardId: a dashboard slug as specified in the Integration. >"
        @load="actUponLoadEvent"
        @changedFilters="actUponChangedFiltersEvent"
        @itemsRendered="actUponItemsRenderedEvent"
        @customEvent="actUponCustomEventsEvent"
      ></luzmo-dashboard>
    </template>
    <script>
      export default {
        methods: {
          actUponLoadEvent(loadEvent: any) {
            // Do something after the dashboard has loaded
          },
          actUponChangedFiltersEvent(changedFiltersEvent: any) {
            // Do something if an interactivity filter in the dashboard has changed
          },
          actUponItemsRenderedEvent(itemsRenderedEvent: any) {
            // Do something after all dashboard items have rendered
          },
          actUponCustomEventsEvent(exportedEvent: any) {
            // Do something after a dashboard (item) has been exported
          },
          actUponCustomEventsEvent(customEventsEvent: any) {
            // Do something if a custom event is thrown from a dashboard item
          },
          ...
        },
        ...
      }
    </script>
    

    Event: load

       The following payload will be included every time the 'load' event is emitted
    {
      "data": {
        "name": "cio-dashboard-H1682506540137",
        "language": "< dashboard language >",
        "type": "load",
        "dashboardId": "< dashboard ID >",
        "screenMode": "< dashboard screen mode >"
      }
    }
    

    This event is emitted when a dashboard has loaded (i.e. the dashboard's resources have been retrieved, but the dashboard items still need to query data).

    The emitted load event contains the following meaningful payload in the data property:

    Property Description
    language
    string
    (Optional) The language in which the dashboard has loaded (either the default language of the dashboard, or the language specified as language property of the component.

    This Academy Webinar goes into more detail about multi-lingual dashboards.
    type
    string
    The type of the event, in this case load.
    dashboardId
    UUID
    The ID of the dashboard that has loaded.
    screenMode
    string
    The screen mode in which the dashboard is currently loaded: either mobile, tablet, desktop, largeScreen, or fixed.

    Event: changedFilters

       The following payload will be included every time the 'changedFilters' event is emitted, including the changed filter groups and all active filter groups in the dashboard
    {
      "data": {
        "name": "cio-dashboard-H1682506540137",
        "language": "< dashboard language >",
        "origin": "< origin of filter change >",
        "changed": [{...}, ...],
        "filters": [{...}, ...],
        "type": "changedFilters",
        "dashboardId": "< dashboard ID >",
        "screenMode": "< dashboard screen mode >",
        "itemId": "< dashboard item ID that triggered the filter change >"
      }
    }
    

    This event is emitted each time an interactivity filter in a dashboard has changed (e.g. a user selects "value 1" and "value 2" in a dashboard item). If the filter state of an embedded dashboard should be known by your application, you should set up an event listener to the changedFilters event.
    You can also programmatically retrieve the filter state of an embedded dashboard using the getFilters() method.

    The emitted changedFilters event contains the following meaningful payload in the data property:

    Property Description
    language
    string
    (Optional) The language in which the dashboard has loaded (either the default language of the dashboard, or the language specified as language property of the component.

    This Academy Webinar goes into more detail about multi-lingual dashboards.
    origin
    string
    The resource type from where the filter change originates from, either:
    • "filterFromVizItem": A runtime filter from a non-filter dashboard item (i.e. filter from an interactive chart widget).
    • "filterFromFilterItem": A runtime filter from a filter dashboard item (i.e. from a 'Date filter', 'Slider', or '(Rank) Slicer' widget).
    changed
    array[object]
    The list of filter groups that changed and caused this event to be emitted. More information about the different properties of the filter groups can be found in the response of the getFilters() method.
    filters
    array[object]
    The list of all active filter groups that are applied in this dashboard. More information about the different properties of the filter groups can be found in the response of the getFilters() method.
    itemId
    uuid
    The ID of the dashboard item that caused this event to be emitted.
    type
    string
    The type of the event, in this case changedFilters.
    dashboardId
    UUID
    The ID of the dashboard where this event has been triggered from.
    screenMode
    string
    The screen mode in which the dashboard is currently shown: either mobile, tablet, desktop, largeScreen, or fixed.

    Event: itemsRendered

       The following payload will be included every time the 'itemsRendered' event is emitted
    {
      "data": {
        "name": "cio-dashboard-H1682506540137",
        "language": "< dashboard language >",
        "type": "itemsRendered",
        "dashboardId": "< dashboard ID >",
        "screenMode": "< dashboard screen mode >"
      }
    }
    

    This event is emitted when all items in a dashboard have rendered (i.e. the data has been queried and visualized). It could be used to e.g. show a custom loader until the event is triggered, gather statistics on load times, etc.

    The emitted itemsRendered event contains the following meaningful payload in the data property:

    Property Description
    language
    string
    (Optional) The language in which the dashboard has loaded (either the default language of the dashboard, or the language specified as language property of the component.

    This Academy Webinar goes into more detail about multi-lingual dashboards.
    type
    string
    The type of the event, in this case itemsRendered.
    dashboardId
    UUID
    The ID of the dashboard where the dashboard items have been rendered.
    screenMode
    string
    The screen mode in which the dashboard is currently shown: either mobile, tablet, desktop, largeScreen, or fixed.

    Event: exported

       The following payload will be included every time the 'exported' event is emitted
    {
      "data": {
        "name": "cio-dashboard-H1682506540137",
        "language": "< dashboard language >",
        "type": "export",
        "dashboardId": "< dashboard ID >",
        "itemId": "< dashboard item ID (only in case of an item export) >",
        "screenMode": "< dashboard screen mode >",
        "exportType": "< dashboard (item) export type >"
      }
    }
    

    This event is emitted when a dashboard (item) has been exported, either via:

    The emitted exported event contains the following meaningful payload in the data property:

    Property Description
    language
    string
    (Optional) The language in which the dashboard (item) has been exported (either the default language of the dashboard, or the language specified as language property of the component.

    This Academy Webinar goes into more detail about multi-lingual dashboards.
    type
    string
    The type of the event, in this case export.
    dashboardId
    UUID
    The ID of the dashboard that has been exported.
    itemId
    UUID
    (Only for dashboard item exports) The ID of the dashboard item that has been exported.
    screenMode
    string
    The screen mode in which the dashboard is currently loaded: either mobile, tablet, desktop, largeScreen, or fixed.
    exportType
    string
    The export type in which the dashboard (item) is exported: either pdf, png, csv, csv-raw, xlsx, or xlsx-raw.

    Event: customEvent

    Custom Events allow you to perform actions in your platform based on what a user has clicked in a dashboard item. This means you can re-use the item's selected data point in your platform, or even include additional data that is not shown in the dashboard item itself. You could for instance open a new dashboard with extra information, filtered to the data point a user has clicked.

    The first step is to set up one or more custom events in your dashboard item(s). When a custom event is triggered from a specific item in the embedded dashboard, a customEvent event will be emitted from the Luzmo component. You should set up an event listener to the customEvent event, and implement the desired interactivity and actionability based on the event and emitted data!

    In the example shown below, the first custom event is used to open a modal in the parent application. Depending on the specific bar a user has clicked on, a the model will show more in-depth insights in another dashboard filtered to the Category value of the bar. Another custom event is used to redirect the user to another part of the parent application, where they can alter the campaign where the custom event originated from!

    Enabling in a dashboard item

    To set up one or multiple Custom events on a dashboard item, open your desired dashboard in our editor and navigate to the item's settings (by hovering over the item and clicking on the gear wheel). You can enable Custom events under the Interactivity section, which will open a modal to set up the custom events.

    Where to find and enable custom events in Luzmo

    Below you can see the event that is emitted by the frontend component when the custom event set up on the column chart above is triggered.

    Payload
      The structure returned by the column chart's custom event as set up in the example screenshot above.
    {
      "data": {
        "name": "cio-dashboard-O1680172026057",
        "language": "en",
        "type": "customEvent",
        "data": {
          "event": "name_of_custom_event",
          "language": "en",
          "measure": {
            "value": 8305.960329,
            "formattedValue": "8.31k",
            "label": "Population density (per km²)"
          },
          "category": {
            "id": "Singapore",
            "value": "Singapore",
            "label": "Country"
          },
          "extraData": {
            "continent": {
              "value": {
                "id": "Asia"
              },
              "datasetId": "< dataset ID >",
              "columnId": "< continent column ID >",
              "aggregation": {
                "type": "min"
              }
            },
            "region": {
              "value": {
                "id": "East Asia & Pacific"
              },
              "datasetId": "< dataset ID>",
              "columnId": "< region column ID >",
              "aggregation": {
                "type": "min"
              }
            },
            "subregion": {
              "value": {
                "id": "South-Eastern Asia"
              },
              "datasetId": "< dataset ID>",
              "columnId": "< subregion column ID >",
              "aggregation": {
                "type": "min"
              }
            },
            "number_of_customers": {
              "value": 12054,
              "datasetId": "< dataset ID>",
              "columnId": "< name column ID >",
              "aggregation": {
                "type": "count"
              }
            }
          }
        },
        "dashboardId": "< dashboard ID >",
        "screenMode": "largeScreen",
        "itemId": "< dashboard item ID >"
      }
    }
    
      A generic structure of a custom event message's data property, including some extra data properties. Note that the exact property names will depend on the specific dashboard item and custom events setup.
    {
      "data": {
        "name": "cio-dashboard-O1680172026057",
        "language": "< dashboard language, e.g. 'en' >",
        "type": "customEvent",
        "data": {
          "language": "< current dashboard language, e.g. 'en' >",
          "<item-specific slot name>": {
            "value": < numeric value >,
            // The "formattedValue" for e.g. SI units would be "8.31k"
            "formattedValue": "< formatted value >",
            "label": "< slot column label >"
          },
          "<another item-specific slot name>": {
            // The "id" would be identical to the data value in your data source
            "id": "< data text value >",
            // If the data value is adapted via our hierarchy editor,
            // the adapted value would be exposed as "value".
            "value": "< hierarchy data text value >",
            "label": "< slot column label >"
          },
          // Other item-specific slots used in your dashboard item
          ...,
          "extraData": {
            "<extra data property name>": {
              "value": {
                // The "id" would be identical to the data value in your data source
                "id": "< data text value >"
              },
              "datasetId": "< dataset ID >",
              "columnId": "< hierarchy-column ID >",
              "aggregation": {
                "type": "< 'min' or 'max' >"
              }
            },
            "<another extra data property name>": {
              "value": <numeric value>,
              "datasetId": "< dataset ID >",
              "columnId": "< column ID >",
              "aggregation": {
                "type": "count"
              }
            },
            "<another extra data property name>": {
              "value": <numeric value>,
              "datasetId": "< dataset ID >",
              "columnId": "< numeric-column ID >",
              "aggregation": {
                "type": "< 'rate' / 'weightedaverage' >",
                "columnId": "< denominator/weight column ID >",
                "datasetId": "< denominator/weight dataset ID >"
              }
            },
            // Any other extra data properties set up for this item's custom events.
            ...
          },
          // The "event" name is defined in the dashboard editor,
          // and specific to dropdown element (i.e. custom event) the user clicked on.
          "event": "< custom event name >"
        },
        "dashboardId": "< dashboard ID >",
        "screenMode": "< screen mode, e.g. 'largeScreen' >",
        "itemId": "< dashboard item ID >"
      }
    }
    

    The emitted event contains information about the dashboard item, the specific data point that was clicked on, as well as all extra data properties you set up in the custom events modal of that item.

    The emitted customEvent event contains the following meaningful payload in the data property:

    Property Description
    language
    string
    (Optional) The language in which the dashboard has loaded (either the default language of the dashboard, or the language specified as language property of the component.
    This Academy Webinar goes into more detail about multi-lingual dashboards.
    type
    string
    The type of the event, in this case customEvent.
    data
    object
    The actual data that is emitted from the dashboard item. The event name, as specified in the 'Custom events' modal, will be included in its name property.
    The properties inside this data object are highly dependent on the specific dashboard item type, item slot(s) usage, and item slot(s) configuration; typically, you could expect properties that are named similar as the dashboard item's slot names (e.g. 'measure', 'category', 'x-axis', etc.). Next to that, it will include an extraData property that will contain all the extra data properties that were set up in the "Custom events" modal (see this Academy article).
    It's recommended to test your specific setup with an event listener on the customEvent event, and investigate its specific payload when emitted!
    dashboardId
    UUID
    The ID of the dashboard where this event has been triggered from.
    screenMode
    string
    The screen mode in which the dashboard is currently shown: either mobile, tablet, desktop, largeScreen, or fixed.
    itemId
    uuid
    The ID of the dashboard item that caused this event to be emitted.

    Plugin API

    With Luzmo's Plugin API, you can connect arbitrary data sources, private or public APIs or open data sources for which Luzmo does not offer a native connector (yet).

    Each Plugin is a small RESTful API that acts as an adapter between Luzmo and a source system. It consists of 2 mandatory and 2 optional endpoints, and can optionally call webhooks to notify Luzmo of events.

    Example Plugin implementations are available:

    During development of a new Plugin, you might want to use a service like ngrok to tunnel HTTPS requests to your local environment.

    Registering a Plugin

    To register a new Plugin in Luzmo, go to Settings > Plugins and click 'Create plugin'.

    Alternatively, you can register a Plugin via the Core API.

    Property Description
    id
    uuid REQUIRED
    Unique key of your Plugin (automatically assigned)
    slug
    string REQUIRED
    Unique slug (textual identifier) of your Plugin. A slug must be unique across Luzmo, between 1 and 50 (inclusive) characters long and can only contain alphanumeric characters. There are several reserved slugs, including athena, cassandra, googleanalytics, googledrive, local, mailchimp, mariadb, mysql, pipelinedb, postgresql, quandl, redshift, rdbms, salesforce, sqlserver, stripe, teamleader and zendesk
    name
    localized REQUIRED
    Name of your Plugin, as shown in the Luzmo UI
    description
    localized REQUIRED
    Description of your Plugin, as shown in the Luzmo UI
    base_url
    string REQUIRED
    Base URL of your Plugin that is used to construct /datasets, /query, ... endpoints. This URL must be reachable by Luzmo (publicly routable) -- endpoints like localhost, 192.186.0.0 or 10.0.0.0 will be rejected. To safeguard our customers, your Plugin must be called over HTTPS. A base URL can be at most 1000 characters long.
    url
    string
    URL where more information about your product or Plugin can be found, as shown in the Luzmo UI.
    license
    string
    License under which end-users can use, re-use, modify or publish data exposed via your Plugin.
    secret
    string
    Plugin secret that can be verified by a Plugin to check whether calls originate from Luzmo, or vice-versa. (automatically assigned)
    authorize
    string REQUIRED
    Determines which properties can be set by a user when connecting to your Plugin. Can be either:
    • none: don't use plugin properties. Use this for open data sources, or when you want to handle authentication/authorization fully on your Plugins side, eg. based on the 'user context', metadata or 'authorization overrides'.
    • oauth2: offer a single-click connect to your plugin. In this case, you must implement an /authorize and /exchange endpoint.
    • custom: use a specific set of properties (eg. key, token, host, ...). The properties are defined in properties.
    properties
    array REQUIRED
    List of properties that can be set by a user.
    id
    string REQUIRED
    Unique identifier of the property. This identifier is used to set the properties, and will be sent along in X-Property-<Property ID> headers. This identifier can only contain alphanumeric characters or the following special characters: - and _.
    name
    localized REQUIRED
    Localized name of the property, as shown in the interface.
    sensitive
    boolean
    Whether this property might contain sensitive data, like passwords or tokens. This will cause the properties to be masked in logs and input fields.
    tiles
    boolean
    Whether to show a tile-based layout (= true) or a list-based layout (false). For a dynamic (personalized per user) or large set of datasets, a list-based layout is advised. Defaults to false.
    search
    boolean
    Whether to show a search box to limit the dataset selection. For a dynamic (personalized per user) or large set of datasets, search functionality is advised. Defaults to false.
    public
    boolean
    Whether to make this plugin available to all Luzmo users (pending review by the Luzmo team). Defaults to false.
    reviewed
    boolean
    (Read-only) Whether this Plugin has been reviewed positively by the Luzmo team on security, branding and usability characteristics.
    color
    rgb
    Key hexadecimal or RGB color value of this Plugin, as applied to the Luzmo UI.
    pushdown
    boolean
    Whether your Plugin supports pushdown behaviour. Setting this to true entails specific support in the handling of /query calls, as described in detail in 2. Pushdown-enabled Plugin. Defaults to false.

    1. Basic Plugin

    The base version of a Plugin:

    Use this Plugin mode to quickly connect a new data source, for relatively small datasets or when your data source does not support aggregation (eg. time-series databases, ...). There is also a blogpost available with a complete step by step tutorial on how to write a basic plugin here.

    POST /authorize

    This endpoint is called whenever a customer tries to create a new Account for your Plugin. You can check the provided credentials for validity. By returning an error code, the customer can be alerted timely (during the connection setup vs. receiving an error later when retrieving datasets).

    Request parameters

    POST /authorize
    
    Content-Type: application/json
    X-Secret: m2c0vilcn9q1qkeph06oycynp
    X-Property-Key: my_key
    X-Property-Token: my_token
    X-Property-Host: https://my.personal.example
    
    {
      "id": "098b9355-d043-46d5-be27-a511a04e46b7",
      "name": "Bill Murray",
      "email": "bill.murray@example.com"
    }
    

    The following headers are sent:

    Header Description
    X-Secret
    string
    Plugin secret assigned by Luzmo. Verify this on each request to check the request originates from Luzmo.
    X-Property-<Property>
    string
    Value for a Plugin property. Typical property id's are host, key, token, ...

    The following payload is sent with Content-Type application/json:

    Property Description
    id
    uuid
    Identifier of the user connecting to the Plugin
    name
    string
    Full name of the user connecting to the Plugin
    email
    string
    E-mail address of the user connecting to the Plugin

    Response format

    {
      "auth_url": "https://www.facebook.com/v3.0/dialog/oauth
        ?client_id=< your Facebook app id >
        &redirect_uri=https://app.luzmo.com/start/connect/< your plugin slug >"
    }
    

    The following status codes are handled:

    In case of an OAuth2 authorization, a payload of Content-Type application/json should have the following property:

    Property Description
    auth_url
    string
    The URL where Luzmo should redirect the customer to start the OAuth2 connect. Eg: https://www.facebook.com/v3.0/dialog/oauth?client_id=<your Facebook app id>&redirect_uri=https://app.luzmo.com/start/connect/<your plugin slug>

    POST /exchange

    POST /exchange
    
    Content-Type: application/json
    X-Secret: m2c0vilcn9q1qkeph06oycynp
    
    {
      "id": "098b9355-d043-46d5-be27-a511a04e46b7",
      "name": "Bill Murray",
      "email": "bill.murray@example.com",
      "code": "received_oauth2_code"
    }
    

    This endpoint is called after the client has confirmed connecting your app via OAuth2 and will send the code value. You can now exchange the code for an OAuth2 identifier, token and refresh_token and send it back to Luzmo to be stored.

    The following headers are sent:

    Header Description
    X-Secret
    string
    Plugin secret assigned by Luzmo. Verify this on each request to check the request originates from Luzmo.

    The following payload is sent with Content-Type application/json:

    Property Description
    id
    uuid
    Identifier of the user connecting to the Plugin
    name
    string
    Full name of the user connecting to the Plugin
    email
    string
    E-mail address of the user connecting to the Plugin
    code
    string
    One-time code of the OAuth2 flow, as sent by the 3rd party service.

    Response format

    {
      "access_token": "received_oauth2_access_token",
      "refresh_token": "received_oauth2_refresh_token"
    }
    

    The payload of Content-Type application/json should have the following properties:

    Property Description
    access_token
    string
    The OAuth2 access token
    refresh_token
    string
    The Oauth2 refresh token

    POST /datasets

    This endpoint is called to retrieve a list of datasets and their columns that this Plugin makes available for a particular end-user.

    Request parameters

    POST /datasets
    
    Content-Type: application/json
    X-Secret: m2c0vilcn9q1qkeph06oycynp
    X-Property-Key: my_key
    X-Property-Token: my_token
    X-Property-Host: https://my.personal.example
    
    {
      "user": {
        "id": "098b9355-d043-46d5-be27-a511a04e46b7",
        "name": "Bill Murray",
        "email": "bill.murray@example.com",
        "authorization_id": "d18b1f35-c53b-439b-b1aa-fd6db4d04c51",
        "metadata": {
          "client_id": 5
        }
      }
    }
    
    Header Description
    X-Secret
    string
    Plugin secret assigned by Luzmo. Verify this on each request to check the request originates from Luzmo.
    X-Property-<Property>
    string
    Value for a Plugin property. Typical property id's are host, key, token, ...

    The following payload is sent with Content-Type application/json:

    Property Description
    user
    object
    User context, describing who is requesting data from the Plugin. You can use this data to apply filters or personalize the result set.
    id
    uuid
    User identifier of the Luzmo user query'ing, or;
    The supplied username of the Authorization query'ing
    name
    string
    Name of the Luzmo user query'ing, or;
    The supplied name of the Authorization query'ing
    email
    string
    E-mail address of the Luzmo user query'ing, or;
    The supplied email of the Authorization query'ing
    authorization_id
    uuid
    Empty or;
    The identifier of the Authorization query'ing
    metadata
    object
    Empty or;
    The metadata associated with the Authorization query'ing, so you can transport data from your backend creating the Authorization to your Plugin.

    Response format

    The response should be a payload with Content-Type application/json, with an array of dataset objects:

    [
      {
        "id": "canonical_dataset_id",
        "name": {
          "en": "Dataset name",
          "fr": "Nom du dataset"
        },
        "description": {
          "en": "A long-form description of this dataset.",
          "fr": "Une description longue de ce dataset."
        },
        "columns": [
          {
            "id": "Column id",
            "name": {
              "en": "Column name",
              "fr": "Nom de la colonne"
            },
            "type": "hierarchy"
          },
          ...
        ]
      },
      ...
    ]
    
    Property Description
    array[object] List of dataset objects:
    id
    string
    Unique 'canonical' name of this dataset.
    name
    localized
    Localized name, shown to the customer in the Luzmo UI. Per locale, a name can be at most 150 characters long.
    description
    localized
    Localized description, shown to the customer in the Luzmo UI. Per locale, a description can be at most 4000 characters long.
    columns
    array[object]
    List of column objects:
    id
    string
    Canonical identifier of this column. Must be unique within this dataset. The identifier can be at most 255 characters long. The identifier must be lowercase.
    name
    localized
    Localized name of this column. Each name can be at most 150 characters long.
    type
    string
    Data type of this column. Valid values are:
    • hierarchy: for textual data. In Luzmo, all textual data can be organized in hierarchical layers
    • numeric: for integer or floating point numeric data
    • datetime: for date or timestamp data
    Depending on the data type, data in the /query endpoint should be formatted in a particular way.

    POST /query

    This endpoint is called to request a particular slice of data from one dataset. All columns should be returned, in the same order as defined in the /datasets metadata for this set.

    A set of filters is also sent along with the /query, but applying them to the data is fully optional for the Plugin. After all, not every data store or API supports these operations. Applying the filters can reduce the number of rows to be sent, however, and thus positively impact the query performance.

    In any case, Luzmo will still apply all filters (including eg. authorization filters that ensure customers cannot see particular data), as some filters might only be applicable after linking multiple sets which can potentially be sourced from different data sources or Plugins.

    Request parameters

    POST /query
    
    Content-Type: application/json
    X-Secret: m2c0vilcn9q1qkeph06oycynp
    X-Property-Key: my_key
    X-Property-Token: my_token
    X-Property-Host: https://my.personal.example
    
    {
      "id": "burrito_stats",
      "filters": [
        {
          "column_id": "date",
          "expression": ">",
          "value": "2018-01-01"
        }
      ],
      "user": {
        "id": "098b9355-d043-46d5-be27-a511a04e46b7",
        "name": "Bill Murray",
        "email": "bill.murray@example.com",
        "authorization_id": "d18b1f35-c53b-439b-b1aa-fd6db4d04c51",
        "metadata": {
          "client_id": 5
        }
      }
    }
    

    The following headers are sent:

    Header Description
    X-Secret
    string
    Plugin secret assigned by Luzmo. Verify this on each request to check the request originates from Luzmo.
    X-Property-Property
    string
    Value for a Plugin property. Typical property id's are Host, Key, Token, ...

    The following payload is sent with Content-Type application/json:

    Property Description
    id
    string
    Dataset to retrieve data from
    filters
    array[object]
    List of filter objects to optionally apply:
    column_id
    string
    Column identifier to filter
    expression
    string
    Specific filter type. Possible values are =, >, >=, <, <=, is null, is not null, in and not in. As applying filters in Basic Plugins is optional, you can choose to only apply a subset of the expressions and ignore others that are not supported by your data store or API.
    value
    array[string] or array[numeric] or array[datetime]
    Value(s) to compare. This field is omitted for is null and is not null expressions. Value will be an array of string, numeric or datetime (in RFC 3339 format, like 2018-05-05T12:23:45.000Z) values, depending on the type of the column.
    user
    object
    User context, describing who is requesting data from the Plugin. You can use this data to apply filters or personalize the result set.
    id
    uuid
    User identifier of the Luzmo user query'ing, or;
    The supplied username of the Authorization query'ing
    name
    string
    Name of the Luzmo user query'ing, or;
    The supplied name of the Authorization query'ing
    email
    string
    E-mail address of the Luzmo user query'ing, or;
    The supplied email of the Authorization query'ing
    authorization_id
    uuid
    Empty or;
    The identifier of the Authorization query'ing
    metadata
    object
    Empty or;
    The metadata associated with the Authorization query'ing, so you can transport data from your backend creating the Authorization to your Plugin.

    Response format

    The return should be a payload of Content-Type application/json with an array of arrays (list of rows, with each row a list of columns). Columns should all be sent, and be in the same order as defined in the /metadata call.

    Date/time data should be sent in RFC 3339 format, like 2018-05-05T12:23:45.000Z.

       Example plugin response to return 2 rows of data, each with a text element, a numeric element, and a datetime element.
    [
      ["Text value 1", 1, "2018-01-01T12:34:56.789Z"],
      ["Text value 2", 1, "2019-01-01T12:34:56.789Z"]
    ]
    

    In case you'd like to return a specific error message when e.g. an Internal Server Error happens, you should return a JSON response as shown in the code example.

       Example error response from the plugin when an internal error happens upon receiving a /query request. The message will be shown to the end-user when hovering over the "Query failed" error in a dashboard widget.
    {
        "type": {
            "code": 500,
            "description": "Internal Server Error"
        },
        "message": "<message_displayed_upon_query_failed_hover>"
    }
    

    Example

    Given the following dataset, an example /query request and response for a basic plugin can be found on the right:

       Example query sent to a basic plugin 
    {
      "id": "burrito_stats",
      "filters": [
        {
          "column_id": "date",
          "expression": ">",
          "value": "2018-01-01"
        }
      ],
      "user": {
        "id": "098b9355-d043-46d5-be27-a511a04e46b7",
        "name": "Bill Murray",
        "email": "bill.murray@example.com",
        "authorization_id": "d18b1f35-c53b-439b-b1aa-fd6db4d04c51",
        "metadata": {
          "client_id": 5
        }
      },
      "pushdown": false
    }
    
    Type of burrito Date savoured Weight
    Salty 2018-06-10 173
    Spicy 2018-06-12 217
    Sweet 2018-06-13 187
    Salty 2018-06-10 301
    Spicy 2018-06-11 255
    Sweet 2017-10-28 190
       Row level data is being sent as response, optionally filtered (in this example, the filter is not applied to the response). 
    [
      ["salty", "2018-06-10T00:00:00.000Z", 173],
      ["spicy", "2018-06-12T00:00:00.000Z", 187],
      ["sweet", "2018-06-13T00:00:00.000Z", 301],
      ["salty", "2018-06-10T00:00:00.000Z", 301],
      ["spicy", "2018-06-11T00:00:00.000Z", 255],
      ["sweet", "2017-10-28T00:00:00.000Z", 190]
    ]
    

    2. Pushdown-enabled Plugin

    For large datasets that are predominantly used in dashboards in an aggregated way, retrieving all rows may be wasteful.

    A pushdown-enabled Plugin:

    Use this mode when you are connecting to a data source that supports high-performance aggregation and filtering, eg. a multi-dimensional data store, OLAP cube, ... You can switch a Plugin to this mode by setting the pushdown field to true.

    POST /query

    Request parameters

    POST /query
    
    Content-Type: application/json
    X-Secret: m2c0vilcn9q1qkeph06oycynp
    X-Property-Key: my_key
    X-Property-Token: my_token
    X-Property-Host: https://my.personal.example
    
    {
      "id": "burrito_stats",
      "columns": [
        {
          "column_id": "type_of_burrito"
        },
        {
          "column_id": "date_savoured",
          "level": "year"
        },
        {
          "column_id": "weight",
          "aggregation": "sum"
        }
      ],
      "filters": [
        {
          "column_id": "date",
          "expression": ">",
          "value": ["2018-01-01"]
        }
      ],
      "user": {
        "id": "098b9355-d043-46d5-be27-a511a04e46b7",
        "name": "Bill Murray",
        "email": "bill.murray@example.com"
      },
      "pushdown": true
    }
    

    The following payload is sent with Content-Type application/json. Differences with Basic Plugin are highlighted.

    Property Description
    id
    string
    Dataset to retrieve data from
    columns
    array[object]
    List of columns (dimensions to group by or measures to aggregate) to select in the order they should be returned:
    column_id
    string
    Column identifier to select
    aggregation
    string
    Aggregation to apply to data of this column. Possible values are sum, count, distinctcount, max and min.
    level
    string
    Applicable to columns of type datetime only. This is the granularity on which the column should be selected and grouped. It ensures that grouping on eg. a datetime column with millisecond precision would not cause the cardinality of the result set to explode.
    Possible values are year, quarter, month, week, day, hour, minute, second and millisecond.
    filters
    array[object]
    List of filter objects your Plugin must apply:
    column_id
    string
    Column identifier to filter
    expression
    string
    Specific filter type. Possible values are =, >, >=, <, <=, is null, is not null, in and not in.
    value
    array[string] or array[numeric] or array[datetime]
    Value(s) to compare. This field is omitted for is null and is not null expressions. Value will be an array of string, numeric or datetime (in RFC 3339 format, like 2018-05-05T12:23:45.000Z) values, depending on the type of the column.
    user
    object
    User context, describing who is requesting data from the Plugin. You can use this data to apply filters or personalize the result set.
    id
    uuid
    User identifier of the Luzmo user query'ing, or;
    The supplied username of the Authorization query'ing
    name
    string
    Name of the Luzmo user query'ing, or;
    The supplied name of the Authorization query'ing
    email
    string
    E-mail address of the Luzmo user query'ing, or;
    The supplied email of the Authorization query'ing
    authorization_id
    uuid
    Empty or;
    The identifier of the Authorization query'ing
    metadata
    object
    Empty or;
    The metadata associated with the Authorization query'ing, so you can transport data from your backend creating the Authorization to your Plugin.
    options
    object
    pushdown
    boolean
    Whether pushdown mode is enabled for this query. If true, aggregations and grouping must be applied. If false, you should return the non-aggregated rows. This will be the case for eg. the dataset preview (databoard) that shows non-aggregated rows.
    Query pseudo-code algorithm

    The following pseudo-code algorithm shows what an equivalent SQL query for a /query call would look like:

    for each column in columns
      if !options.pushdown
        (select) <- column.id
      else if column.level
        (select, groupby) <- DATE_TRUNC(column.level, column.id)
      else if column.aggregation
        (select) <- column.aggregation(column.id)
      else
        (select, groupby) <- column.id
    end
    sql <- `SELECT select FROM id GROUP BY groupby`
    

    Response format

    The return should be a payload of Content-Type application/json with an array of arrays (list of aggregated rows, with each row a list of the requested columns). Data should be filtered and aggregated.

       Example plugin response to return 2 rows of data, each with a text element, a numeric element, and a datetime element.
    [
      ["Text value 1", 1, "2018-01-01T12:34:56.789Z"],
      ["Text value 2", 1, "2019-01-01T12:34:56.789Z"]
    ]
    

    In case you'd like to return a specific error message when e.g. an Internal Server Error happens, you should return a JSON response as shown in the code example.

       Example error response from the plugin when an internal error happens upon receiving a /query request. The message will be shown to the end-user when hovering over the "Query failed" error in a dashboard widget.
    {
        "type": {
            "code": 500,
            "description": "Internal Server Error"
        },
        "message": "<message_displayed_upon_query_failed_hover>"
    }
    

    Example

    Given the following dataset, an example /query request and response for a pushdown-enabled plugin can be found on the right:

       Example query sent to a pushdown-enabled plugin 
    {
      "id": "burrito_stats",
      "columns": [
        {
          "column_id": "type_of_burrito"
        },
        {
          "column_id": "date_savoured",
          "level": "year"
        },
        {
          "column_id": "weight",
          "aggregation": "sum"
        }
      ],
      "filters": [
        {
          "column_id": "date",
          "expression": ">",
          "value": ["2018-01-01"]
        }
      ],
      "user": {
        "id": "098b9355-d043-46d5-be27-a511a04e46b7",
        "name": "Bill Murray",
        "email": "bill.murray@example.com"
      },
      "pushdown": true
    }
    
    Type of burrito Date savoured Weight
    Salty 2018-06-10 173
    Spicy 2018-06-12 217
    Sweet 2018-06-13 187
    Salty 2018-06-10 301
    Spicy 2018-06-11 255
    Sweet 2017-10-28 190
       SQL equivalent query of the example above: 
    SELECT
        type_of_burrito
        , DATE_TRUNC("year", date_savoured)
        , SUM(weight)
    FROM burrito_stats
    WHERE
        date > "2018-01-01"
    GROUP BY
        type_of_burrito
        , DATE_TRUNC("year", date_savoured)
    
       Aggregated and filtered data is being sent as response. 
    [
      ["salty", "2018-01-01T00:00:00.000Z", 474],
      ["spicy", "2018-01-01T00:00:00.000Z", 472],
      ["sweet", "2018-01-01T00:00:00.000Z", 187]
    ]
    

    Version history

    The Plugin API specification is versioned to enable new functionality without breaking existing Plugins.

    You can change the protocol version of a Plugin in the user interface or by updating the protocol_version property on the Plugin entity.

    Version Changes
    1.0.0 Initial version
    1.1.0 The filters_all property is introduced, containing all active filters on datasets of this plugin (vs. filters which only contains filters that are applicable to the specific dataset ID requested in the query.
    2.0.0 The request method of the /datasets endpoint is modified from GET to POST.

    Webhooks

    Plugins are typically called by Luzmo for setting up accounts, retrieving metadata or data. In some cases, it can be useful to directly notify Luzmo of events related to your Plugin. Therefore, we support the following webhooks:

    data_available

    In case your Plugin caches data of a 3rd party provider (eg. Facebook, Pipedrive, ..) for a user instead of query'ing an API directly, synchronizing a user's data can take a while after the first call to /authorize. Calling this webhook will inform the user when this process is finished and they can start dashboarding.

    POST https://api.luzmo.com/0.1.0/webhook/plugin/data_available
    
    Content-Type: application/json
    X-Secret: m2c0vilcn9q1qkeph06oycynp
    
    {
      "slug": "your_plugin_slug",
      "user_id": "098b9355-d043-46d5-be27-a511a04e46b7",
      "key": "my_key"
    }
    

    The following headers should be sent:

    Property Description
    X-Secret
    string
    Plugin secret assigned by Luzmo. Luzmo will verify this on each request to check the request originates from your Plugin.

    The following payload should be sent with Content-Type application/json:

    Property Description
    slug
    string
    Slug of your Plugin.
    user_id
    string
    User identifier for which the data is available.
    key
    string
    Key for which the data is available (to disambiguate between multiple Accounts a user might have for your Plugin).

    data_updated

    This webhook can be called whenever a dataset for a particular account has new data available (eg. because your Plugin re-synchronized data or because it received a webhook from an upstream data source). Calling this webhook will immediately update all open dashboards using this data.

    POST https://api.luzmo.com/0.1.0/webhook/plugin/data_updated
    
    Content-Type: application/json
    X-Secret: m2c0vilcn9q1qkeph06oycynp
    
    {
      "slug": "your_plugin_slug",
      "user_id": "098b9355-d043-46d5-be27-a511a04e46b7",
      "key": "my_key",
      "dataset_id": "burrito_stats"
    }
    

    The following headers should be sent:

    Property Description
    X-Secret
    string
    Plugin secret assigned by Luzmo. Luzmo will verify this on each request to check the request originates from your Plugin.

    The following payload should be sent with Content-Type application/json:

    Property Description
    slug
    string
    Slug of your Plugin.
    user_id
    string
    User identifier for which new data is available.
    key
    string
    Key for which new data is available (to disambiguate between multiple Accounts a user might have for your Plugin).
    dataset_id
    string
    The canonical dataset identifier of the updated dataset.

    account_deleted

    This webhook can be called whenever the end-user deleted the Luzmo app from the 3rd parties side. Luzmo will then also remove the account, so a full reconnection can be made if desired.

    POST https://api.luzmo.com/0.1.0/webhook/plugin/account_deleted
    
    Content-Type: application/json
    X-Secret: m2c0vilcn9q1qkeph06oycynp
    
    {
      "slug": "your_plugin_slug",
      "user_id": "098b9355-d043-46d5-be27-a511a04e46b7",
      "key": "my_key"
    }
    

    The following headers should be sent:

    Property Description
    X-Secret
    string
    Plugin secret assigned by Luzmo. Luzmo will verify this on each request to check the request originates from your Plugin.

    The following payload should be sent with Content-Type application/json:

    Property Description
    slug
    string
    Slug of your Plugin.
    user_id
    string
    User identifier that wishes to disconnect their account.
    key
    string
    Key to disconnect.