🕐 4 min read
To query a data source with VizQL Data Service (VDS), you must first assign the API Access capability in the Permission dialog. For information about setting up this data source capability in the Tableau user interface, see the Permission Capabilities and Templates topic in either Tableau Cloud Help or Tableau Server Help.
For information about setting up this data source capability using the REST API, see Permissions.
To query a data source in a workbook with VDS, the following is required:
The workbook must be published.
The user must have View, API Access, and Full Data Query capabilities on the workbook.
If the workbook data source is a published datasource, the user must have View, API Access, and Connect capabilities on the upstream data source.
For information about setting up workbook permissions, see the Permission Capabilities and Templates topic in either Tableau Cloud Help or Tableau Server Help.
VDS requires that you send an authentication token with each request. The token lets Tableau Cloud or Tableau Server verify your identity and makes sure that you’re signed in. To get a token, you can call the Tableau REST API Sign In method, in one of three ways.
To sign in using a PAT, see Make a Sign In Request with a Personal Access Token in the Tableau REST API Help for more information.
If you use a JWT, set the scope (scp) in the JWT to tableau:viz_data_service:read. The permissions of the user in the JWT determine query results.
See Make a Sign In Request with a JWT in the Tableau REST API Help for more information on using a JWT to create a credentials token that you can use with VDS.
See Make a Sign In Request with Username and Password in the Tableau REST API Help for more information.
For information about token expiration, changing the token timeout value, and more, see Using the Authentication Token In Subsequent Calls in the Tableau REST API Help.
To run a VDS method, you must know the locally unique identifier (LUID) of the published data source you’re requesting information about. There are two options for finding the data source LUID.
The LUID is at the bottom of the Data Source Details screen.

Use the Query Data Sources method to return a list of data sources on your site. This method returns the official data source name in the contentURL attribute. The associated id of the contentURL is your data source LUID.
A workbook data source is any data source that exists a inside a Tableau workbook. A workbook data source could include an embedded data source, or the published data source that the workbook is connected to. If the workbook is connected to a published data source, and the user makes edits to that published data source inside the workbook, those edits are available as part of the workbook data source.
To call a VDS method in an interactive session with a workbook on Tableau Server or Tableau Online, you must know the workbook session ID and the ID of the data source you’re requesting information about.
If you are embedding a Tableau Viz and also running queries using the VizQL Data Services API, you can programmatically get the session ID using the Tableau Embedding API method, getVizQLDataServiceSessionInfo().
For example, the following code snippet shows a method that takes a Tableau viz object and extracts the session ID (vizqlServerSessionId) and the global session header (globalSessionHeader). The global session header is needed if you are using Tableau Cloud. These values correspond to the X-Session-Id and the Global-Session-Header headers that you need to send when you query workbook data sources.
let vizqlServerSessionId = '';
let globalSessionHeader = '';
const getVizQLDataServiceSessionInfo = (viz) => {
vizqlServerSessionId = viz.getVizQLDataServiceSessionInfo().vizqlServerSessionId;
console.log('vizQLServerSessionId:' + viz.getVizQLDataServiceSessionInfo().vizqlServerSessionId);
globalSessionHeader = viz.getVizQLDataServiceSessionInfo().globalSessionHeader;
console.log('globalSessionHeader:' + viz.getVizQLDataServiceSessionInfo().globalSessionHeader);
};
You can get the workbook data source IDs associated with the worksheet(s) in the viz. This example code snippet shows a method that gets the data source ID for a specific worksheet in a workbook. This workbook data source value is captured in the datasourceInternalName variable. This is the value that you use in a VDS call for workbookDatasourceId.
let datasourceInternalName = '';
const getDataSourceInternalName = async (viz) => {
console.log(`Logging datasourceInternalName for worksheet for ${viz.workbook.name}...`);
try {
const salesSheet = viz.workbook.activeSheet.worksheets.find(sheet => sheet.name === 'Sale Map');
const dataSources = await salesSheet.getDataSourcesAsync();
datasourceInternalName = dataSources[0].id;
console.log(`datasourceInternalName is:${datasourceInternalName}`);
} catch (error) {
console.log('Error fetching datasource:', error);
}
};
After you’ve found the session ID, the global session header (Tableau Cloud only), and the workbook data source ID, you can call VDS.
The following example shows how you include the session ID (X-Session-Id) and global session header (Global-Session-Header) in a JavaScript Fetch() API to query the workbook data source. The values vizqlServerSessionId, globalSessionHeader, and datasourceInternalName were obtained in the preceding Embedding API examples.
// set the VDS_BASE_PATH that corresponds to your Tableau instance
const VDS_QUERY_DATASOURCE = '/query-datasource';
async function callVizQLDataService() {
try {
const res = await fetch(VDS_QUERY_DATASOURCE, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'X-Session-Id': vizqlServerSessionId,
'Global-Session-Header': globalSessionHeader
},
body: JSON.stringify({
datasource: {
workbookDatasourceId: datasourceInternalName,
},
query: {
fields: [
{
fieldCaption: "Category"
},
{
fieldCaption: "Sales",
function: "SUM"
}
]
}
}),
});
} catch (err) {
console.error("Request failed.");
}
}
The following shows a complete listing of a web page that embeds a Tableau viz and extracts the session and workbook data source ID.
<!DOCTYPE html>
<html>
<head>
<title>Simple getSessionInfo</title>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script type="module" >
import { TableauEventType } from 'https:///javascripts/api/tableau.embedding.3.latest.js'
const tableauViz = document.getElementById('tableauViz');
let vizqlServerSessionId = '';
let globalSessionHeader = '';
let datasourceInternalName = '';
tableauViz.addEventListener(TableauEventType.FirstInteractive, async () => {
getVizQLDataServiceSessionInfo(tableauViz);
await getDataSourceInternalName(tableauViz);
}, { once: true });
const getVizQLDataServiceSessionInfo = (viz) => {
vizqlServerSessionId = viz.getVizQLDataServiceSessionInfo().vizqlServerSessionId;
console.log('vizQLServerSessionId:' + viz.getVizQLDataServiceSessionInfo().vizqlServerSessionId);
globalSessionHeader = viz.getVizQLDataServiceSessionInfo().globalSessionHeader;
console.log('globalSessionHeader:' + viz.getVizQLDataServiceSessionInfo().globalSessionHeader);
};
const getDataSourceInternalName = async (viz) => {
console.log(`Logging datasourceInternalName for worksheet for ${viz.workbook.name}...`);
try {
const salesSheet = viz.workbook.activeSheet.worksheets.find(sheet => sheet.name === 'Sale Map');
const dataSources = await salesSheet.getDataSourcesAsync();
datasourceInternalName = dataSources[0].id;
console.log(`datasourceInternalName is:${datasourceInternalName}`);
} catch (error) {
console.log('Error fetching datasource:', error);
}
};
</script>
</head>
<body>
<tableau-viz id="tableauViz" src="{YOUR_SITE}/views/Superstore/Overview"></tableau-viz>
</body>
</html>