Important Note:
The information in this post is current as of July 2nd, 2024. I will update with significant changes as applicable
Already know which method you prefer? Skip ahead:
A.P…I…?
An application programming interface (API) is system or service that allows users and developers to query data from or perform operations for the application it supports. This might enable a user or external application to perform tasks in bulk or automate repeatable processes that would otherwise be very time-consuming, etc.
The concept of an API originated in the 1940s โ how crazy is that?! Of course, this means that there are many dozens of โflavorsโ of them to be found. In the context of Tableau though, youโre likely to come across the REST API, Embedding API or even the new (as of June 2024) Viz Extensions API at some point in your journey. No matter whether youโre looking to extend dashboard functionality, query metadata about your content, or build your own custom connectors, all of the Tableau Developer Tools can supercharge your ability to get stuff done, find an answer or create an experience that vanilla Tableau canโt offer you.
Sign In, Blast Off! ๐
It makes no difference whether youโre a total API newbie or a seasoned DataDev. If you want to work some API magic, youโre going to have to show some ID, i.e. authenticate. In many cases, this might mean something like sending an initial that returns a token, which youโll use for your upcoming tasks. Other times, you might create a different type of token on your own, using keys/secrets you and the API already agreed on. Donโt worry, this will make more sense soon.
Weโre in luck though — Tableau offers multiple options for how to make this initial handshake happen! Iโll be focusing on three methods: User ID/Password, Personal Access Token (PAT), and JSON Web Token (JWT). Each option offers different advantages. Choosing the right option might seem clear as mud right now, but stick with me here. The goal is to help you decide how to pick the best option for your use case!
I will include code/request samples and links to the documentation in each section. If demos/IRL examples are more your speed, feel free to skip to the bottom for a video explaining them, as well!
Option #1: User ID + Password
This authentication method doesnโt need a lot of explanation. You supply Tableau with your user ID and password via an initial call to the REST API. Once verified, a token is returned to you. Youโll simply include this token in subsequent requests. Thatโs how the API knows who you are and what youโre allowed to do. In the case of query endpoints, this is also how Tableau knows which information youโre entitled to see.
This approach is straightforward, and thus easiest for beginners and simple tasks, but there are some very important things to consider:
- User ID + Password authentication carries inherent risk:
- If youโre sharing requests/code with others, care should be taken that your and otherโs credentials are not accidentally exposed
- DONโT HARDCODE PASSWORDS IN SHARED REQUESTS/CODE
- Instead use a service that can encrypt/decrypt on demand and keep the keys and secrets in an isolated location
- If your credentials are compromised or change, youโll need to make updates to any saved requests/code
- This can be a colossal time suck at best, and if used for large or frequent automation tasks, may cause severe downstream effects until remediated
- Any actions performed will be logged as being done by the authenticated user
- This isnโt inherently bad on its own, but if someone is able to authenticate as you, it may obscure who has taken certain actions
Examples/Code Samples
REST API w/ Postman
Requirements: Postman | Reference: Tableau REST API Documentation Tableau Postman Collection |
Postman is a great tool for getting started with just about any API! It allows you to make REST API calls and examine their responses without writing any code!
METHOD | POST |
URL | https://<YOUR-TABLEAU-URL>/api/<API-VERSION>/auth/signin e.g. https://10ax.online.tableau.com/api/3.22/auth/signin |
Additional Headers | Accept: application/json (optional, API will respond with XML if not present) |
Body (XML) | <tsRequest> |
Response (XML) | <?xml version='1.0' encoding='UTF-8'?> |
Body (JSON) | { |
Response (JSON) | { |
NOTES: | โข The Tableau REST API will respond with XML by default, add/modify the ‘Accept’ header to get JSON โข Your site’s name and content URL may not be the same, check the URL in your browser for the correct value โข You will use the API token in the response for subsequent requests, via the X-Tableau-Auth header |
Python w/ tableauserverclient (TSC)
Requirements: Python, tableauserverclient (TSC) | Reference: TSC API Documentation |
Code Example |
import tableauserverclient as TSC def sign_in(): server_url = 'YOUR-TABLEAU-URL' # e.g. https://10ax.online.tableau.com uid = 'YOUR-USER-ID' pw = 'YOUR-PASSWORD' site_content_url = 'YOUR-SITE-CONTENT-URL' server = TSC.Server(server_url, use_server_version=True) tab_auth = TSC.TableauAuth(uid, pw, site_id=site_content_url) with server.auth.sign_in(tab_auth): workbooks, paginator = server.workbooks.get() for wb in workbooks: print(wb.name) sign_in()
The Good and The Bad
+ Easy, no additional setup required
+ Individual accounts can perform multiple actions simultaneously
– UID/PW authentication has inherent risk
– Not suitable for shared/production code without proper, external credential management
– Code changes may be required in the event of compromise
Option #2: Personal Access Token (PAT)
Personal Access Tokens, aka PATs, are a popular way to sign into many APIs. In a nutshell, youโll log into Tableau Server/Cloud and visit your Account Settings page. Once here, youโll create a new token. There are two components: the PAT name and the PAT secret. Be absolutely sure to make note of the secret โ you only get once chance to view it. If you lose it, youโll have to create another PAT! Take a look at this clip to learn how to create your very own PAT:
With your PAT details in hand, youโll make your sign in request to Tableau, and once again, the response will contain a token youโll use moving forward. From this point on, youโll continue on just as you would with user ID and password authentication.
As above, there are some important things to know about choosing PATs:
- Personal Access Token authentication must be enabled by your admins
- By default, PATs expire if not used for 15 consecutive days
- BUT they are valid for one year if used regularly
- Server Admins can adjust these settings
- While more secure than user ID + password, PATs can still be compromised without proper due diligence
- Luckily, PATs can be revoked by server/site administrators
- DONโT STORE PAT SECRETS IN SHARED REQUESTS/CODE
- Server Administrator PATs support user impersonation (Tableau Server only)
- Useful for embedding or automation, where the actual account performing the actions may be an admin but capabilities or results should be limited to those of another user
- Concurrent sessions are not supported with PATs!
- If you use a PAT to sign in and do something, donโt you dare sign in again with that token before that action completes โ your first operation will be aborted if still in-flight!
- This makes PAT somewhat cumbersome for automation when multiple actions need to happen at once and cadence cannot be directly controlled
- Example: An automation portal that allows end users to perform actions their site role/permissions might not otherwise allow
- Changing a userโs authentication method, e.g. turning MFA on/off or switching to SAML, will invalidate any and all existing PATs for their account
Examples/Code Samples
REST API w/ Postman
Requirements: Postman | Reference: Tableau REST API Documentation Tableau Postman Collection |
METHOD | POST |
URL | https://<YOUR-TABLEAU-URL>/api/<API-VERSION>/auth/signin e.g. https://10ax.online.tableau.com/api/3.22/auth/signin |
Additional Headers | Accept: application/json (optional, API will respond with XML if not present) |
Body (XML) | <tsRequest> |
Response (XML) | <?xml version='1.0' encoding='UTF-8'?> |
Body (JSON) | { |
Response (JSON) | { |
NOTES: | โข The Tableau REST API will respond with XML by default, add/modify the ‘Accept’ header to get JSON โข Your site’s name and content URL may not be the same, check the URL in your browser for the correct value โข You will use the API token in the response for subsequent requests, via the X-Tableau-Auth header |
Python w/ tableauserverclient (TSC)
Requirements: Python, tableauserverclient (TSC) | Reference: TSC API Documentation |
Code Example |
import tableauserverclient as TSC def sign_in(): server_url = 'YOUR-TABLEAU-URL' # e.g. https://10ax.online.tableau.com pat_name = 'YOUR-PAT-NAME' pat_secret = 'YOUR-PAT-SECRET' site_content_url = 'YOUR-SITE-CONTENT-URL' server = TSC.Server(server_url, use_server_version=True) tab_auth = TSC.PersonalAccessTokenAuth( pat_name, pat_secret, site_id=site_content_url) with server.auth.sign_in(tab_auth): workbooks, paginator = server.workbooks.get() for wb in workbooks: print(wb.name) sign_in()
The Good and The Bad
+ More secure than user ID + password
+ Changes to username or password do not affect PATs, i.e. will not require code changes
+ Admins can revoke PATs without affecting userโs profile
+ PATs are automatically revoked if not used
– PAT name/secret compromise is still possible without proper management
– Automation challenges due to single session limitation
– Since PATs are automatically revoked if unused, care must be taken to avoid unexpected oopsies
Option #3: JSON Web Tokens (JWTs)
In normal people speak, JWTs allow information such as originating user/system, application unique identifiers, roles, and so on to be signed (and even encrypted) and transmitted between parties. A shared secret, such an application key/value pair, ensures that JWTs can only be understood by their intended recipient. These tokens are typically short-lived, and may even expire once used; however, there is very limited overheard when creating them and many, many options for whichever language or environment you prefer!
When using a JWT for Tableau API authentication, youโll make use of Connected Apps. These allow us to establish trust between Tableau Server/Cloud and other applications or code, which is the primary mechanism behind this authentication method.
The video below shows you how to create and enable a Connected App for Tableau, and then use it to generate a JSON Web Token for API authentication:
As with the first two methods, youโll send an initial request that contains your JWT, and in return Tableau will give you a token to forge ahead with.
As you might expect, there are some caveats to using JWTs, as well:
- Connected Apps for Tableau can be configured two ways: Direct Trust and OAuth 2.0:
- Both options provide similar functionality, but OAuth requires connectivity with an OAuth provider, while Direct Trust does not require an additional IdP (Identity Provider)
- As with PATs, you should not hard code the secret ID and value anywhere where they might be exposed
- These serve as the metaphorical โlock and keyโ between JWTs you generate and Tableau
- Up to two secrets can be generated per App; howeverโฆ
- Concurrent operations using the same Connected App are allowed โ just be sure to generate a new JWT for each request
- While โ strictly speaking โ impersonation is not supported, you determine which user the JWT is created for
- Example: Users come to your site or application already authenticated by some other means, you can pass their Tableau username while generating their token, thereby restricting them to only the content/actions you would expect them to be able to perform
Examples/Code Samples
JWT Generation with Python
Requirements: Python, PyJWT | Reference: TSC API Documentation |
Code Example |
import jwt import tableauserverclient as TSC import datetime import uuid def generate_login_jwt(): token = jwt.encode( { "iss": "YOUR-CONNECTED-APP-CLIENT-ID", "exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=10), "jti": str(uuid.uuid4()), "aud": "tableau", "sub": "YOUR-USER-ID", # SCOPES EXPLAINED: # https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm "scp": ["tableau:projects:*", "tableau:content:read"], }, "YOUR-CONNECTED-APP-SECRET-VALUE", algorithm="HS256", headers={ 'kid': "CLIENT_SECRET_ID", 'iss': "YOUR-CONNECTED-APP-CLIENT-ID" } ) return token generate_login_jwt()
REST API w/ Postman
Requirements: Postman | Reference: Tableau REST API Documentation Tableau Postman Collection |
METHOD | POST |
URL | https://<YOUR-TABLEAU-URL>/api/<API-VERSION>/auth/signin e.g. https://10ax.online.tableau.com/api/3.22/auth/signin |
Additional Headers | Accept: application/json (optional, API will respond with XML if not present) |
Body (XML) | <tsRequest> |
Response (XML) | <?xml version='1.0' encoding='UTF-8'?> |
Body (JSON) | { |
Response (JSON) | { |
NOTES: | โข The Tableau REST API will respond with XML by default, add/modify the ‘Accept’ header to get JSON โข Your site’s name and content URL may not be the same, check the URL in your browser for the correct value โข You will use the API token in the response for subsequent requests, via the X-Tableau-Auth header |
Python w/ tableauserverclient (TCS)
Requirements: Python, tableauserverclient (TSC) | Reference: TSC API Documentation Tableau JWT Scopes |
Code Example |
import tableauserverclient as TSC def sign_in(jwt): server_url = 'YOUR-TABLEAU-URL' # e.g. https://10ax.online.tableau.com site_content_url = 'YOUR-SITE-CONTENT-URL' server = TSC.Server(server_url, use_server_version=True) tab_auth = TSC.JWTAuth( jwt, site_id=site_content_url) with server.auth.sign_in(tab_auth): workbooks, paginator = server.workbooks.get() for wb in workbooks: print(wb.name) sign_in("YOUR-JWT")
The Good and The Bad
+ Shorter-lived tokens are generally preferable, more secure
+ Scope can be limited during generation per action or user, supporting PoLP ideals
+ Most modern approach, using a web standard
+ JWT libraries exist in many, many languages
+ Connected Apps don’t have a single concurrent session limit
– Connected App authentication needs/concerns should be determined in advance
– JWT generation requires some additional coding time, knowledge
So, Which Option is Best?
Youโre going to be disappointed here, but โ like so many things in life โ the honest answer is: โIt depends.โ ๐
If youโre just getting started with the APIs and just want to experiment, just go with username and password, especially if you donโt plan on sharing or publishing your code just yet.
PATs are a better solution if you need multiple people to use the same code but want their individual permissions to restrict what theyโre capable of.
For automation at-scale with users who are authenticated via OAuth or some other provider, JWTs via Connected Apps give you more robust customizability, the ability to perform multiple actions simultaneously, and shorter-lived tokens that expire in a predictable fashion, whether theyโre used or not.
The needs and requirements of your users or application(s) will dictate which approach is most appropriate, but all three are viable and capable solutions, provided proper care regarding credentials/secrets is taken.
It may seem like a lot to consider, especially since all of this just enables us to begin using the APIs, but a sturdy foundational knowledge of your authentication options is the best way to begin your journey!
Questions/Comments/Feedback?
I hope the information and examples above have helped shed some light on ways you can authenticate with the Tableau APIs, as well as their associated pros, cons and caveats. Now that you know how to sign in with confidence, you can begin to fully harness the power of these services. Have fun out there โ I canโt wait to see what you come up with! ๐
Please feel free to leave a comment or reach out via Twitter/X, LinkedIn or Slack with questions!