Skip to main content

Hello,

I'm trying to get all users from a subsite of our server via the API using a Server Admin PAT. But for some reason I'm getting 403 errors:

<?xml version='1.0' encoding='UTF-8'?>

<tsResponse xmlns="http://tableau.com/api"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api https://help.tableau.com/samples/en-us/rest_api/ts-api_3_21.xsd">

<error code="403010">

<summary>Forbidden</summary>

<detail>User 'administrator' is authenticated for site 'defaultsite-id' and may not access or modify resources on site 'subsite-id'.</detail>

</error>

</tsResponse>

I'm getting the xml via this url: users_url = f"{server_name}/api/{version}/sites/subsite-id/users"

 

I have already set the conentUrl to the subsite during authentication:

if use_pat_flag:

# The following code constructs the body for the request. The resulting element will

# look similar to the following example:

#

#

# <tsRequest>

# <credentials personalAccessTokenName="TOKEN_NAME"

# personalAccessTokenSecret="TOKEN_VALUE" >

# <site contentUrl="SITE_SUBPATH" />

# </credentials>

# </tsRequest>

#

 

request_xml = ET.Element('tsRequest')

credentials = ET.SubElement(request_xml, 'credentials',

personalAccessTokenName=personal_access_token_name,

personalAccessTokenSecret=personal_access_token_secret)

site_element = ET.SubElement(credentials, 'site', contentUrl=site_url_id)

I tried authenticating with a site-admin PAT for the subsite, but I'm only getting 401 errors when I try to sign in to the server (also set the contentUrl to the subsite).

How can I successfully authenticate for the subsite?

Thank you

9 respostas
  1. 19 de jun. de 2025, 21:52

    @Thea Baldewein​ 

    Hi, as you cannot share your code, use tableau server client:

    https://tableau.github.io/server-client-python/

    import tableauserverclient as TSC

    import csv

    from datetime import datetime,timezone

     

    # server admin creds

    HOST = "https://prod-useast-b.online.tableau.com/"

    TOKEN_NAME = "Python"

    TOKEN_VALUE = "b5iXybhg==:lc65QDPxx6M"

    CONTENT_URL = "yoursitename"

     

    tableau_auth = TSC.PersonalAccessTokenAuth(TOKEN_NAME, TOKEN_VALUE, site_id=CONTENT_URL)

    server = TSC.Server(HOST, use_server_version=True)

     

    #Create the csv file and open it in write mode

    f = open('usuarios.csv', 'w', encoding='UTF8', newline='')

     

    #delimiter with semicolon if need change to comma, and write header

    writer = csv.writer(f, delimiter=";")

    header = ['User','Site Role','Last Login','Difference']

    writer.writerow(header)

     

    today_date = datetime.now(timezone.utc)

     

    with server.auth.sign_in(tableau_auth):

    for user in TSC.Pager(server.users):

    if user.last_login is None:

    row=[user.name,user.site_role,"NA","NA"]

    print(user.name, user.site_role, "NA", "NA")

    #write the row

    writer.writerow(row)

    else:

    last_login = user.last_login

    difference = (today_date - last_login).total_seconds() / (60 * 60 * 24)

    row=[user.name,user.site_role,user.last_login,difference]

    print(user.name, user.site_role, user.last_login, difference)

    writer.writerow(row)

    #Close file connection and sign out

    f.close()

    server.auth.sign_out()

    If this post resolves the question, would you be so kind to "Select as Best"?. This will help other users find the same answer/resolution and help community keep track of answered questions. Thank you.

     

    Regards,

     

    Diego Martinez

    Tableau Visionary and Forums Ambassador

0/9000