How to apply relationship filters in a dashboard programmatically [Linux]
Introduction
This article demonstrates how to programmatically apply filter relationships (e.g., OR logic between filters) in a Sisense dashboard using a dashboard script and the REST API. The solution is tested on Sisense L2026.2.1-c and works for both cloud and on-premises deployments. By following this guide, you can automate the application of filter relationship logic without manual UI configuration according to your needs.
Step-by-step guide
1. Understand the filter relationship editor
You can replicate the Relationship Filters behavior applied via UI the following way: in any dashboard, go to the filters panel, click the three dots menu → Filter relationship editor, apply the desired relationship to your existing filters, and save. You will see a PUT request is made to your dashboard adding the desired filter relations.

Tip: The payload structure will vary depending on the relationship logic you need (OR, AND, nested expressions, etc.). The easiest approach is to first configure it manually in the UI, inspect the PUT request in your browser's network tab, copy the payload, and adapt it in your script.
2. Prepare your environment
Create a new dashboard or go to an existing dashboard. Make sure you have at least two filters already added to the dashboard that you want to relate (e.g., Brand and Category).
3. Apply the code
Go to your dashboard, click on the three dots menu at the dashboard level and select Edit Script, then paste the following code:
dashboard.on("initialized", function (scope, args) {
var dash = args.dashboard;
var dashboardId = dash.oid;
var $internalHttp = prism.$injector.get("base.factories.internalHttp");
// GET current dashboard filterRelations to check if OR is already applied
$internalHttp(
{
url: "/api/dashboards/" + dashboardId + "?fields=filterRelations",
method: "GET",
dataType: "json",
},
false,
)
.then(function (response) {
var existingRelations = response.data && response.data.filterRelations;
// Check if OR logic is already present
var alreadyApplied =
existingRelations &&
existingRelations.length > 0 &&
existingRelations[0].filterRelations &&
existingRelations[0].filterRelations.value &&
existingRelations[0].filterRelations.value.operator === "OR";
if (alreadyApplied) {
console.log("filterRelations OR already set. No action needed.");
return;
}
// OR logic not present - apply it and reload
console.log("filterRelations OR not set. Applying now...");
applyFilterRelationsAndReload(dash, dashboardId, $internalHttp);
})
.catch(function (err) {
console.error("Error checking current filterRelations:", err);
});
});
function applyFilterRelationsAndReload(dash, dashboardId, $internalHttp) {
var filters = dash.filters.$$items;
var firstFilter = filters.find(function (f) {
return f.jaql && f.jaql.dim === "[Brand.Brand]"; // Change to your required filter
});
var secondFilter = filters.find(function (f) {
return f.jaql && f.jaql.dim === "[Category.Category]"; // Change to your required filter
});
if (!firstFilter || !secondFilter) {
console.warn(
"Could not find Brand or Category filter on dashboard. Aborting.", // Both filters should be present in the dashboard so we can apply the OR relation
);
return;
}
var firstFilterInstanceId = firstFilter.instanceid;
var secondFilterInstanceId = secondFilter.instanceid;
var payload = {
filterRelations: [
{
datasource: "Sample ECommerce", // Change to your datasource accordingly, and your desired filter relations structure.
filterRelations: {
type: "ParenthesizedLogicalExpression",
value: {
type: "LogicalExpression",
operator: "OR",
left: { type: "Identifier", instanceId: firstFilterInstanceId },
right: { type: "Identifier", instanceId: secondFilterInstanceId },
},
},
},
],
filters: [
{
jaql: firstFilter.jaql,
instanceid: firstFilterInstanceId,
isCascading: firstFilter.isCascading || false,
},
{
jaql: secondFilter.jaql,
instanceid: secondFilterInstanceId,
isCascading: secondFilter.isCascading || false,
},
],
};
$internalHttp(
{
url: "/api/dashboards/" + dashboardId,
method: "PUT",
data: JSON.stringify(payload),
contentType: "application/json",
dataType: "json",
},
false,
)
.then(function () {
console.log(
"filterRelations OR logic applied successfully. Reloading...",
);
location.reload();
})
.catch(function (err) {
console.error("Failed to apply filterRelations:", err);
});
}
4. Code explanation
This is a dashboard script that runs on the initialized event. When the dashboard loads, the script:
Checks existing relations — It performs a GET request to the dashboard API to verify if the OR filter relationship is already applied. If it is, no action is taken.
Finds the target filters — It locates the two filters on the dashboard by their dimension (
[Brand.Brand]and[Category.Category]in this example) and retrieves their instance IDs.Builds the payload — It constructs the
filterRelationspayload with the OR operator linking both filters via their instance IDs.Applies via PUT — It sends a PUT request to the dashboard API with the payload, then reloads the page to reflect the changes.
The check-before-apply logic ensures the script doesn't unnecessarily re-apply the relationship or trigger repeated reloads on every dashboard load.
Conclusion
By leveraging the initialized dashboard event and the Sisense REST API, you can programmatically apply filter relationship logic that would otherwise require manual configuration through the UI. This is especially useful when you need to enforce specific filter relationships across multiple dashboards or ensure the logic persists regardless of user changes. Remember to adjust the dimension names, datasource, and payload structure to match your specific environment and requirements.
References/Related content
Disclaimer: This post outlines a potential custom workaround for a specific use case or provides instructions regarding a specific task. The solution may not work in all scenarios or Sisense versions, so we strongly recommend testing it in your environment before deployment. If you need further assistance with this, please let us know.