---
schema_version: "1"
id: 93402de1258ab7705008be018cbf2152f37f343ecbb7f9677b1cd0cd20bf1e41
title: Data Sources Methods
collection: tableau
version: next
locale: en-us
portal_url: https://docs.salesforce.com/tableau/next/en-us/api/rest_api/REST/rest_api_ref_data_sources.md
canonical_url: https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref_data_sources.htm
source_site: help.tableau.com
content_type: documentation
content_hash: 11c7ff3e79ea4130490050501397e9ebfe8a84ac36ad3cf0b3e5577c27d8c4ac
description: "Using the data sources methods of the Tableau Server REST API you can:"
---
[Skip to main content](#main-content)

# Data Sources Methods

Using the data sources methods of the Tableau Server REST API you can:

- Publish, update metadata, delete, or refresh the extract of a data source of a site
- Add and delete tags of a data source
- Get a list of data sources and the details of each
- Get and update the connection information for a data source
- Get the revision history of a data source or remove specific revisions
- Download the current data source or one of its past revisions
- Incrementally update specified portions of data from a live-to-Hyper connection.
- Download an encrypted keychain for a data source that is migrating to another site.
- Upload an encrypted keychain for a data source migrated to another site.
- Create a work copy of a published data source, read and edit its elements, and publish the changes

This functionality relates to the UI elements and concepts described at: [Connect to Your Data](https://help.tableau.com/current/pro/desktop/en-us/basicconnectoverview.htm).

  
  

The [Tableau Server Client library](https://tableau.github.io/server-client-python/), a Python wrapper for the REST API, offers the following related items: [Data Sources](https://tableau.github.io/server-client-python/docs/api-ref#data-sources); and [Populate connections for Data Sources](https://tableau.github.io/server-client-python/docs/populate-connections-views#populate-connections-for-data-sources).

## Use Postman

Our Postman collection of requests enables you to construct, send, and examine HTTP requests to the Tableau Server or Tableau Cloud API without writing initial code. Postman is a free online app used by many developers for prototyping API calls, investigating issues, and generating request code in a variety of languages.

[Postman: Data Sources](https://www.postman.com/salesforce-developers/salesforce-developers/folder/gl07jsz/data-sources)

## Add Tags to Data Source

Adds one or more tags to the specified data source.

#### URI

PUT /api/api-version/sites/site-id/datasources/datasource-id/tags

#### Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-id</span></td><td>The ID of the site that contains the data source.</td></tr><tr><td><span class="api-placeholder">datasource-id</span></td><td>The ID of the data source to add tags to.</td></tr></tbody></table>

#### Request Body

```
<tsRequest>
  <tags>
    <tag label="tag" />
    ... additional tags ...
  </tags>
</tsRequest>
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1"> <col></colgroup><tbody><tr><td><span class="api-placeholder">datasource-id</span></td><td>The data source to add the tag to. If the data source is already tagged with a tag that's included in the request body, those tags are ignored and the data source retains them. If the <span class="api-command-ref">&lt;tags&gt;</span> element is empty, no new tags are added to the data source.</td></tr><tr><td><span class="api-placeholder">tag</span></td><td>The text of the tag.</td></tr></tbody></table>

#### Permissions

Tableau Server users who are not server administrators or site administrators can call this method only if they have Read permissions for the data source (either explicitly or implicitly).

#### Access Scope

Scope added in API 3.27 (Tableau Cloud December 2025 / Server 2025.3).

```
tableau:datasource_tags:update
```

For more information, see [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud) and access scopes for connected apps: [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm), or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### Response Code

200

#### Response Body

```
<tsResponse>
  <tags>
    <tag label="tag"/>
        ... additional new tags ...
        ... existing tags ...
  </tags>
</tsResponse>
```

#### Version

Version 1.0 and later. For more information, see [REST API and Resource Versions](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm).

#### Errors

<table class="api-error-table">
                                <colgroup>
                                    <col class="api-error-table-col-1">
                                    <col class="api-error-table-col-2">
                                    <col class="api-error-table-col-3">
                                    <col>
                                </colgroup>
                                <tbody>
                                    <tr>
                                        <th>HTTP status</th>
                                        <th><code>error</code> Code</th>
                                        <th>Condition</th>
                                        <th>Details</th>
                                    </tr>
                                    <tr>
                                        <td>400</td>
                                        <td>400000</td>
                                        <td>Bad request</td>
                                        <td>The content of the request body is missing or incomplete, or contains malformed XML.</td>
                                    </tr>
                                    <tr>
                                        <td>400</td>
                                        <td>400075</td>
                                        <td>Error adding tags</td>
                                        <td>There was a problem adding tags to the specified data source.</td>
                                    </tr>
                                    <tr>
                                        <td>403</td>
                                        <td>403004</td>
                                        <td>Adding tags forbidden</td>
                                        <td>
                                            <p>
                                            A non-administrator user called this method but doesn't have permission to add tags. This error is raised even if
                                            the <span class="api-command-ref">&lt;tags&gt;</span> element is empty.
                                        </p>
                                        </td>
                                    </tr>
                                    <tr>
                                        <td>404</td>
                                        <td>404000</td>
                                        <td>Site not found</td>
                                        <td>
                                            <p>The site ID in the URI is not for an existing site.</p>
                                        </td>
                                    </tr>
                                    <tr>
                                        <td>404</td>
                                        <td>404004</td>
                                        <td>Data source not found</td>
                                        <td>The data source ID in URI doesn't correspond to an existing data source.</td>
                                    </tr>
                                    <tr>
                                        <td>404</td>
                                        <td>404009</td>
                                        <td>Data source ID mismatch</td>
                                        <td>The request body contains a data source ID (which is optional) and it doesn't match the ID in the URI.</td>
                                    </tr>
                                    <tr>
                                        <td>404</td>
                                        <td>405000</td>
                                        <td>Invalid request method</td>
                                        <td>Request type was not <span class="api-command-ref">PUT</span>.</td>
                                    </tr>
                                </tbody>
                            </table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

#### Example

`curl "http://MY-SERVER/api/3.29/sites/9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d/datasources/1a2a3b4b-5c6c-7d8d-9e0e-1f2f3a4a5b6b/tags" -X PUT -H "X-Tableau-Auth:12ab34cd56ef78ab90cd12ef34ab56cd" -d @add-tags-to-datasource.xml`

**Content of add-tags-to-datasource.xml:**

```
<tsRequest>
    <tags>
      <tag label="GDP" />
      <tag label="Health" />
    </tags>
</tsRequest>
```

**Example response:**

```
<tsResponse version-and-namespace-settings>
  <tags>
    <tag label="GDP"/>
    <tag label="Health"/>
    <tag label="Spending"/>
  </tags>
</tsResponse>
```

## Add Work Copy Elements

Adds field descriptions or table descriptions to a work copy. Returns HTTP 201 when every element is added. The success body omits the elements that succeeded.

If any element fails, the HTTP status is the status of the first failure and the body lists only the failed elements. A `Column` entry is not added by this method.

**Version**: Available in API 3.30 (Tableau Cloud October 2026 / Server 2026.3) and later.

**License**: Data Management or Tableau+.

**Permissions**: Users who are not server administrators or site administrators can call this method only if they have Connect, Write (save), and VizqlDataApiAccess (API Access) permissions for the data source that the work copy was created from (either explicitly or implicitly).

**Access Scope**: `tableau:datasources:update`

For more information, see [Versions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm), [Permissions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm), [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud), and access scopes for [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows,](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm) or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### URI

POST /api/api-version/tds/sites/site-luid/workcopy/workcopy-luid

#### URI Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use. These TDS Edit methods are available in API 3.30 and later. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-luid</span></td><td>The LUID of the site in the URI. This handler does not bind the path variable — the service uses the authenticated user's site LUID (<code>authUser.getSiteLuid()</code>).</td></tr><tr><td><span class="api-placeholder">workcopy-luid</span></td><td>The LUID of the work copy. Must be a UUID (8-4-4-4-12 hexadecimal digits), matching <code>[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}</code>.</td></tr></tbody></table>

#### Request Body

```
<tsRequest>
  <tdsElementList>
    <elementType>FieldDescription</elementType>
    <name>Sales</name>
    <description>Total sales amount.</description>
  </tdsElementList>
  <tdsElementList>
    <elementType>TableDescription</elementType>
    <name>Orders</name>
    <description>Order line items.</description>
  </tdsElementList>
</tsRequest>
```

```
{
  "tdsElementList": [
    {
      "elementType": "FieldDescription",
      "name": "Sales",
      "description": "Total sales amount."
    },
    {
      "elementType": "TableDescription",
      "name": "Orders",
      "description": "Order line items."
    }
  ]
}
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1"> <col></colgroup><tbody><tr><td><span class="api-placeholder">tdsElementList[]</span></td><td>Required. Elements to add. Must contain at least one element. An empty or missing list is HTTP 400 with error code <code>400008</code>.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].elementType</span></td><td>Optional. Element type sent to the TDS service. For this operation, use <code>FieldDescription</code> or <code>TableDescription</code>. Any other value is forwarded and reported as a per-element failure.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].name</span></td><td>Required. Element name.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column</span></td><td>Not applicable to this method. The add converter has no <code>Column</code> branch, so a <code>column</code> payload on an add element is not copied and the element is reported as a per-element failure.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].description</span></td><td>Required for this method. Description text for a <code>FieldDescription</code> or <code>TableDescription</code> element. When <code>description</code> is null, the field is left unset so the TDS service can report a per-element failure instead of HTTP 500.</td></tr></tbody></table>

#### Response Code

201 Created

#### Response Body

On full success the response is an empty `tsResponse` — `tdsElementResult` is omitted entirely rather than returned as an empty list. When one or more elements fail, the HTTP status is the status of the first failure and the body carries `tdsElementResult` for the failed elements only; see the Attribute Values table below and the Errors table for the failure shape.

```
<tsResponse/>
```

```
{}
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1"> <col></colgroup><tbody><tr><td><span class="api-placeholder">tdsElementResult[]</span></td><td>Failed elements only. Omitted on full success, including omitted rather than returned as an empty array.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].elementType</span></td><td>Required. Element type of the failed element, copied from the request.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].name</span></td><td>Required. Name of the failed element, copied from the request.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].status</span></td><td>Required. Failure status for this element.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].status.code</span></td><td>Required (within <code>status</code>). The translated HTTP status for this element (200, 400, 401, 403, 404, 409, 500, or 503). Not a Tableau 6-digit error sub-code.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].status.message</span></td><td>Optional. Error message from the TDS service.</td></tr></tbody></table>

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td>400008</td><td>Missing tdsElementList</td><td><code>tdsElementList</code> is missing or empty. The list is required and must contain at least one element.</td></tr><tr><td>400</td><td></td><td>Invalid work copy LUID</td><td>The work copy LUID in the URI is not a UUID (8-4-4-4-12 hexadecimal digits).</td></tr><tr><td>400</td><td></td><td>Per-element invalid argument</td><td>One or more elements were rejected as invalid. The body lists only the failed elements, and each <code>status.code</code> is the HTTP status 400.</td></tr><tr><td>400</td><td></td><td>Unmapped per-element gRPC status</td><td>The TDS service returned a status that maps to HTTP 400. The body lists only the failed elements.</td></tr><tr><td>401</td><td>401000 / 401002</td><td>Missing or invalid authentication</td><td>No authentication token provided, or token is expired or invalid.</td></tr><tr><td>401</td><td></td><td>Per-element unauthenticated</td><td>The TDS service rejected an element as unauthenticated. The body lists only the failed elements.</td></tr><tr><td>403</td><td>403004</td><td>Data Management Bundle not licensed</td><td>On Tableau Server the TDS Edit API requires a Data Management Bundle license. The call is rejected when that license is absent.</td></tr><tr><td>403</td><td>403004</td><td>Unable to resolve tenant</td><td>On Tableau Cloud the subscription could not be checked because the tenant id for the site could not be retrieved.</td></tr><tr><td>403</td><td>403004</td><td>No cloud entitlements</td><td>On Tableau Cloud no entitlements were found for the tenant. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>403</td><td>403004</td><td>Subscription not entitled</td><td>On Tableau Cloud the site edition is not Tableau+. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>403</td><td></td><td>Per-element permission denied</td><td>The TDS service rejected an element because permission was denied. The body lists only the failed elements.</td></tr><tr><td>404</td><td></td><td>Per-element not found</td><td>One or more elements were not found. The body lists only the failed elements. This is not error code 404065, which the read methods return for a missing named element.</td></tr><tr><td>405</td><td>405000</td><td>Method not allowed</td><td>The HTTP method is not supported for this resource.</td></tr><tr><td>409</td><td></td><td>Per-element already exists</td><td>One or more elements already exist. The body lists only the failed elements.</td></tr><tr><td>429</td><td>429000</td><td>Rate limit exceeded</td><td>Too many requests sent in a given time period.</td></tr><tr><td>500</td><td></td><td>Per-element internal error</td><td>The TDS service failed while editing an element. The body lists only the failed elements.</td></tr><tr><td>503</td><td></td><td>Per-element unavailable</td><td>The TDS service was unavailable while editing an element. The body lists only the failed elements.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Create Work Copy

Creates a work copy of a published data source and returns the work copy LUID. Composable data sources and Semantic Data Model (SDM) data sources are not supported. The call is rejected when the caller already has the maximum number of open work copies.

**Version**: Available in API 3.30 (Tableau Cloud October 2026 / Server 2026.3) and later.

**License**: Data Management or Tableau+.

**Permissions**: Users who are not server administrators or site administrators can call this method only if they have Connect, Write (save), and VizqlDataApiAccess (API Access) permissions for the data source (either explicitly or implicitly).

**Access Scope**: `tableau:datasources:create`

For more information, see [Versions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm), [Permissions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm), [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud), and access scopes for [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows,](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm) or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### URI

POST /api/api-version/tds/sites/site-luid/datasource/datasource-luid/workcopy

#### URI Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use. These TDS Edit methods are available in API 3.30 and later. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-luid</span></td><td>The LUID of the site in the URI. This handler does not bind the path variable — the service uses the authenticated user's site LUID (<code>authUser.getSiteLuid()</code>).</td></tr><tr><td><span class="api-placeholder">datasource-luid</span></td><td>The LUID of the data source. Must be a UUID (8-4-4-4-12 hexadecimal digits), matching <code>[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}</code>.</td></tr></tbody></table>

#### Response Code

201 Created

#### Response Body

Returns the created work copy's identifiers in `tdsWorkCopy`. The response includes `workCopyLuid` but not `datasourceLuid`, which only Publish Work Copy returns.

```
<tsResponse>
  <tdsWorkCopy>
    <workCopyLuid>d9e8f7a6-b5c4-3210-fedc-ba9876543210</workCopyLuid>
  </tdsWorkCopy>
</tsResponse>
```

```
{
  "tdsWorkCopy": {
    "workCopyLuid": "d9e8f7a6-b5c4-3210-fedc-ba9876543210"
  }
}
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1"> <col></colgroup><tbody><tr><td><span class="api-placeholder">tdsWorkCopy</span></td><td>Required. Work copy identifiers.</td></tr><tr><td><span class="api-placeholder">tdsWorkCopy.workCopyLuid</span></td><td>LUID of the new work copy.</td></tr><tr><td><span class="api-placeholder">tdsWorkCopy.datasourceLuid</span></td><td>Optional. LUID of the published data source. Not returned by this method; returned by Publish Work Copy.</td></tr></tbody></table>

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td></td><td>Invalid data source LUID</td><td>The data source LUID in the URI is not a UUID (8-4-4-4-12 hexadecimal digits).</td></tr><tr><td>401</td><td>401000 / 401002</td><td>Missing or invalid authentication</td><td>No authentication token provided, or token is expired or invalid.</td></tr><tr><td>403</td><td>403004</td><td>Data Management Bundle not licensed</td><td>On Tableau Server the TDS Edit API requires a Data Management Bundle license. The call is rejected when that license is absent.</td></tr><tr><td>403</td><td>403004</td><td>Unable to resolve tenant</td><td>On Tableau Cloud the subscription could not be checked because the tenant id for the site could not be retrieved.</td></tr><tr><td>403</td><td>403004</td><td>No cloud entitlements</td><td>On Tableau Cloud no entitlements were found for the tenant. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>403</td><td>403004</td><td>Subscription not entitled</td><td>On Tableau Cloud the site edition is not Tableau+. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>404</td><td></td><td>Data source not found or not visible to the caller</td><td>The data source LUID in the URI doesn't correspond to an existing data source in the site, or the caller doesn't have permission to access it.</td></tr><tr><td>405</td><td>405000</td><td>Method not allowed</td><td>The HTTP method is not supported for this resource.</td></tr><tr><td>405</td><td>405003</td><td>Composable data source</td><td>Creating a work copy is not supported for composable data sources (data sources that have one or more immediate parent published data sources).</td></tr><tr><td>405</td><td>405004</td><td>Semantic Data Model (SDM) data source</td><td>Creating a work copy is not supported for Semantic Data Model (SDM) data sources.</td></tr><tr><td>429</td><td>429000</td><td>Rate limit exceeded</td><td>Too many requests sent in a given time period.</td></tr><tr><td>429</td><td></td><td>Work copy limit exceeded</td><td>The maximum number of open work copies is reached. Publish an existing work copy before creating a new one.</td></tr><tr><td>500</td><td></td><td>Unknown error</td><td>There was an internal server error.</td></tr><tr><td>503</td><td></td><td>Service unavailable</td><td>Service unavailable.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Delete Data Source

Deletes the specified data source from a site. When a data source is deleted, its associated data connection is also deleted. Workbooks that use the data source are not deleted, but they will no longer work properly.

#### URI

DELETE /api/api-version/sites/site-id/datasources/datasource-id

#### Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-id</span></td><td>The ID of the site that contains the data source.</td></tr><tr><td><span class="api-placeholder">datasource-id</span></td><td>The ID of the data source to delete.</td></tr></tbody></table>

#### Request Body

None

#### Permissions

Tableau Server users who are not server administrators or site administrators can delete a data source for which they have Read (view) and Delete permissions (either explicitly or implicitly).

#### Access Scope

Scope added in API 3.27 (Tableau Cloud December 2025 / Server 2025.3).

```
tableau:datasources:delete
```

For more information, see [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud) and access scopes for connected apps: [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm), or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### Response Code

204

#### Response Body

None

#### Version

Version 2.0 and later. For more information, see [REST API and Resource Versions](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm).

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>403</td><td>403004</td><td>Deletion forbidden</td><td>A non-administrator user called this method but doesn't have <span class="api-command-ref">Read</span> (view) and <span class="api-command-ref">Delete</span> permission for the data source.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID or URL namespace in the URI doesn't correspond to an existing site.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The data source ID in the URI doesn't correspond to an existing data source in the site.</td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">DELETE</span>.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Delete Tag from Data Source

Deletes a tag from the specified data source.

#### URI

DELETE /api/api-version/sites/site-id/datasources/datasource-id/tags/tag-name

#### Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-id</span></td><td>The ID of the site that contains the data source.</td></tr><tr><td><span class="api-placeholder">datasource-id</span></td><td>The ID of the data source to remove the tag from.</td></tr><tr><td><span class="api-placeholder">tag-name</span></td><td>The name of the tag to remove from the data source.</td></tr></tbody></table>

#### Request Body

None

#### Permissions

Tableau Server users who are not server administrators, site administrators, or data source owners can delete a tag from a data source only if they are project leaders or if they originally added the tag.

#### Access Scope

Scope added in API 3.27 (Tableau Cloud December 2025 / Server 2025.3).

```
tableau:datasource_tags:delete
```

For more information, see [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud) and access scopes for connected apps: [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm), or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### Response Code

204

#### Response Body

None

#### Version

Version 1.0 and later. For more information, see [REST API and Resource Versions](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm).

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td>400077</td><td>Error deleting tag</td><td>There was a problem deleting the tag from the specified data source.</td></tr><tr><td>403</td><td>403004</td><td>Deleting tags forbidden</td><td>A non-administrator user called this method but doesn't have permission to delete a tag from the specified data source.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID or URL namespace in the URI doesn't correspond to an existing site.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The data source ID in the URI doesn't correspond to an existing data source.</td></tr><tr><td>404</td><td>404007</td><td>Tag not found</td><td>The tag in the URI doesn't exist for the specified data source.</td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">DELETE</span>.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Delete Work Copy Elements

Deletes elements from a work copy. Send `elementType` and `name` for each element. Other content is ignored. Returns HTTP 200 when every element is deleted. The success body omits the elements that succeeded.

If any element fails, the HTTP status is the status of the first failure and the body lists only the failed elements.

**Version**: Available in API 3.30 (Tableau Cloud October 2026 / Server 2026.3) and later.

**License**: Data Management or Tableau+.

**Permissions**: Users who are not server administrators or site administrators can call this method only if they have Connect, Write (save), and VizqlDataApiAccess (API Access) permissions for the data source that the work copy was created from (either explicitly or implicitly).

**Access Scope**: `tableau:datasources:update`

For more information, see [Versions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm), [Permissions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm), [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud), and access scopes for [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows,](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm) or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### URI

DELETE /api/api-version/tds/sites/site-luid/workcopy/workcopy-luid

#### URI Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use. These TDS Edit methods are available in API 3.30 and later. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-luid</span></td><td>The LUID of the site in the URI. This handler does not bind the path variable — the service uses the authenticated user's site LUID (<code>authUser.getSiteLuid()</code>).</td></tr><tr><td><span class="api-placeholder">workcopy-luid</span></td><td>The LUID of the work copy. Must be a UUID (8-4-4-4-12 hexadecimal digits), matching <code>[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}</code>.</td></tr></tbody></table>

#### Request Body

```
<tsRequest>
  <tdsElementList>
    <elementType>FieldDescription</elementType>
    <name>Sales</name>
  </tdsElementList>
  <tdsElementList>
    <elementType>TableDescription</elementType>
    <name>Orders</name>
  </tdsElementList>
</tsRequest>
```

```
{
  "tdsElementList": [
    {
      "elementType": "FieldDescription",
      "name": "Sales"
    },
    {
      "elementType": "TableDescription",
      "name": "Orders"
    }
  ]
}
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1"> <col></colgroup><tbody><tr><td><span class="api-placeholder">tdsElementList[]</span></td><td>Required. Elements to delete. Must contain at least one element. An empty or missing list is HTTP 400 with error code <code>400008</code>.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].elementType</span></td><td>Required for this method. Element type of the element to delete (<code>Column</code>, <code>FieldDescription</code>, or <code>TableDescription</code>). Any other value is forwarded and reported as a per-element failure.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].name</span></td><td>Required. Name of the element to delete.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column</span></td><td>Not applicable to this method. Delete uses <code>elementType</code> and <code>name</code> only; other content is ignored.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].description</span></td><td>Not applicable to this method. Delete uses <code>elementType</code> and <code>name</code> only; other content is ignored.</td></tr></tbody></table>

#### Response Code

200 OK

#### Response Body

On full success the response is an empty `tsResponse` — `tdsElementResult` is omitted entirely rather than returned as an empty list. When one or more elements fail, the HTTP status is the status of the first failure and the body carries `tdsElementResult` for the failed elements only; see the Attribute Values table below and the Errors table for the failure shape.

```
<tsResponse/>
```

```
{}
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1"> <col></colgroup><tbody><tr><td><span class="api-placeholder">tdsElementResult[]</span></td><td>Failed elements only. Omitted on full success, including omitted rather than returned as an empty array.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].elementType</span></td><td>Required. Element type of the failed element, copied from the request.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].name</span></td><td>Required. Name of the failed element, copied from the request.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].status</span></td><td>Required. Failure status for this element.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].status.code</span></td><td>Required (within <code>status</code>). The translated HTTP status for this element (200, 400, 401, 403, 404, 500, or 503). Not a Tableau 6-digit error sub-code.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].status.message</span></td><td>Optional. Error message from the TDS service.</td></tr></tbody></table>

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td>400008</td><td>Missing tdsElementList</td><td><code>tdsElementList</code> is missing or empty. The list is required and must contain at least one element.</td></tr><tr><td>400</td><td></td><td>Invalid work copy LUID</td><td>The work copy LUID in the URI is not a UUID (8-4-4-4-12 hexadecimal digits).</td></tr><tr><td>400</td><td></td><td>Per-element invalid argument</td><td>One or more elements were rejected as invalid. The body lists only the failed elements, and each <code>status.code</code> is the HTTP status 400.</td></tr><tr><td>400</td><td></td><td>Unmapped per-element gRPC status</td><td>The TDS service returned a status that maps to HTTP 400. The body lists only the failed elements.</td></tr><tr><td>401</td><td>401000 / 401002</td><td>Missing or invalid authentication</td><td>No authentication token provided, or token is expired or invalid.</td></tr><tr><td>401</td><td></td><td>Per-element unauthenticated</td><td>The TDS service rejected an element as unauthenticated. The body lists only the failed elements.</td></tr><tr><td>403</td><td>403004</td><td>Data Management Bundle not licensed</td><td>On Tableau Server the TDS Edit API requires a Data Management Bundle license. The call is rejected when that license is absent.</td></tr><tr><td>403</td><td>403004</td><td>Unable to resolve tenant</td><td>On Tableau Cloud the subscription could not be checked because the tenant id for the site could not be retrieved.</td></tr><tr><td>403</td><td>403004</td><td>No cloud entitlements</td><td>On Tableau Cloud no entitlements were found for the tenant. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>403</td><td>403004</td><td>Subscription not entitled</td><td>On Tableau Cloud the site edition is not Tableau+. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>403</td><td></td><td>Per-element permission denied</td><td>The TDS service rejected an element because permission was denied. The body lists only the failed elements.</td></tr><tr><td>404</td><td></td><td>Per-element not found</td><td>One or more elements were not found. The body lists only the failed elements. This is not error code 404065, which the read methods return for a missing named element.</td></tr><tr><td>405</td><td>405000</td><td>Method not allowed</td><td>The HTTP method is not supported for this resource.</td></tr><tr><td>429</td><td>429000</td><td>Rate limit exceeded</td><td>Too many requests sent in a given time period.</td></tr><tr><td>500</td><td></td><td>Per-element internal error</td><td>The TDS service failed while editing an element. The body lists only the failed elements.</td></tr><tr><td>503</td><td></td><td>Per-element unavailable</td><td>The TDS service was unavailable while editing an element. The body lists only the failed elements.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Download Data Source

Downloads a data source in `.tdsx` format.

#### URI

GET /api/api-version/sites/site-id/datasources/datasource-id/content

GET /api/api-version/sites/site-id/datasources/datasource-id/content?includeExtract=extract-value

#### Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-id</span></td><td>The ID of the site that contains the data source.</td></tr><tr><td><span class="api-placeholder">datasource-id</span></td><td>The ID of the data source to download.</td></tr><tr><td><span class="api-placeholder">extract-value</span></td><td>(Optional) The <span class="api-placeholder">extract-value</span> is a Boolean value (<code>False</code> or <code>True</code>). When the data source specified for download has an extract, if you add the parameter <code>?includeExtract=False</code>, the extract is not included when you download the data source. You can use this parameter to improve performance if you are downloading workbooks or data sources that have large extracts.</td></tr></tbody></table>

#### Request Body

None

#### Permissions

Users who are not server administrators or site administrators can download a data source only if they have ExportXml permission for the data source (either explicitly or implicitly).

#### Required scope for JWT authorization

Introduced in Tableau Cloud June 2022 (API 3.16) and Tableau Server 2022.3 (API 3.17).

```
tableau:datasources:download
```

For more information, see [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud) and access scopes for connected apps: [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm), or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### Response Code

200

#### Response Body

The data source content in `.tdsx` format (`Content-Type: application/octet-stream`).

The response will have the following content disposition header:

`Content-Disposition: name="tableau_datasource"; filename="datasource-filename"`

#### Version

Version 2.0 and later. For more information, see [REST API and Resource Versions](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm).

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>403</td><td>403028</td><td>Read forbidden</td><td>A non-administrator user attempted to download a data source, but the caller doesn't have <span class="api-command-ref">Read</span> permission.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID in the URI doesn't correspond to an existing site.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The data source ID in the URI doesn't correspond to an existing data source.</td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">GET</span>.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

#### Example

`curl "http://MY-SERVER/api/3.29/sites/9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d/datasources/1a2a3b4b-5c6c-7d8d-9e0e-1f2f3a4a5b6b/content" -X GET -H "X-Tableau-Auth:12ab34cd56ef78ab90cd12ef34ab56cd" > my-datasource.tdsx`

The response is a file that contains the data source.

## Download Data Source Encrypted Keychain

Gets an encrypted version of the embedded credentials from the data source. These credentials can only be migrated to the linked destination Tableau Cloud or Tableau Server.

Before you use this method, you must create public and private keys for resources with embedded credentials. For more information, see [Migrate Workbooks and Data Sources with Embedded Credentials](https://help.tableau.com/current/server/en-us/cmt-migration_embedded_credentials.htm).

**Version:** Available in API 3.23 (Tableau Cloud June 2024/ Tableau Server 2024.2) and later. _[Version Overview](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm)_

**License:** No additional license required.

**Permissions:** This method can only be called by Tableau Cloud and Tableau Server admins.   _[Permissions Overview](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm)_

**JWT Access Scope:** tableau:embedded\_credentials:download

- Scope added in API 3.27 (Tableau Cloud December 2025 / Server 2025.3).
- For more information, see [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud) and access scopes for connected apps: [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm), or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### URI

POST /api/api-version/sites/site-luid/datasources/datasource-luid/retrieveKeychain

#### URI Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-luid</span></td><td>The LUID for the site.</td></tr><tr><td><span class="api-placeholder">datasource-luid</span></td><td>The LUID of the data source to download the encrypted keychain from.</td></tr></tbody></table>

#### Request Body

```
<tsRequest>
  <destinationSiteUrlNamespace>site1</destinationSiteUrlNamespace>
  <destinationSiteLuid>d56023b5-8f8b-4241-aa74-8974ced85827</destinationSiteLuid>
  <destinationServerUrl>http://example.com</destinationServerUrl>
</tsRequest>
```

```
{
  "destinationSiteUrlNamespace": "site1",
  "destinationSiteLuid": "d56023b5-8f8b-4241-aa74-8974ced85827",
  "destinationServerUrl": "http://localhost"
}
```

#### Request Attributes

<table class="api-parameters-table">
                                <colgroup>
                                    <col class="api-parameters-table-col-1">
                                    <col>
                                </colgroup>
                                <tbody>
                                    <tr>
                                        <td><code>destinationSiteUrlNamespace</code>
                                        </td>
                                        <td>
                                            <p>
								(Required) The site name on Tableau Cloud.</p>
                                        </td>
                                    </tr>
                                    <tr>
                                        <td><code>destinationSiteLuid</code>
                                        </td>
                                        <td>(Required) &nbsp;The site ID on Tableau Cloud.</td>
                                    </tr>
                                    <tr>
                                        <td><code>destinationServerUrl</code>
                                        </td>
                                        <td>
                                            <p>(Required) The destination Tableau Cloud URL.</p>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>

#### cURL Request Example

```
curl --location "https://example.org/api/3.24/sites/7a2f773d-4a9f-496e-afc6-a60517cb1b86/datasources/1a2a3b4b-5c6c-7d8d-9e0e-1f2f3a4a5b6b/retrieveKeychain" -X POST --header "Content-Type: application/xml"  --header "X-Tableau-Auth: nbQAstTxTHuBlcMlXZ3QKg|LXn5aiYcffck999kgpOPrQft5JkvRsYg|7a2f773d-4a9f-496e-afc6-a60517cb1b86"  --data "<tsRequest> <destinationSiteUrlNamespace>site1</destinationSiteUrlNamespace><destinationSiteLuid>9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d</destinationSiteLuid><destinationServerUrl>http://example.com</destinationServerUrl></tsRequest>"
```

#### Response Code

200

#### Response Body

```
<tsResponse>
   <associatedUserLuidList/>
   <encryptedKeychainList>
     <encryptedKeychain>BADsJ5lBKho2Tdqqbo7txS8IyKgNw5FnJud0etCHJLhBUurgIRHk3g5AeMQg6KHBw+6nwNIDEd65MKi76DLd5aIMhQC5aLCR4NE7R2gp7JbxLo+nOMGnfDQm5XekJVpLQGfY53GIX52ED2iTfOQ0yRNbnPV4djT0z23rosG0gpmqXV/py5okFzVW4wx8RisnZdvv+SAlv222jVhksX1w5A6HB3Bs45BeWfpwrOnHwnNoWUGwHuu4iGlyE7m65RlATZN+fvDGOFN1zU2lXaSZyWqRKiWkD+oCS5wRNtJ6lGz7RnesKvH6QEL9sT8cXA1ZOEA531xNAv9rjazEP5BssIdA1GcJ5J7zar5xxC68qm3cz3MkndyqWXZrf0vWPgwysUHEpWn60oDG/8/xG6c0Eigh4gwE+dA+NF1L2q9VyhVr8+AzJ7vatf95LDwAuRT43G3Q+WApx9qBPXco15pKjwy00rHPgn4cRtu+unwh6d3gIh6AbK6X++U/vV/Ktpe31lSZmV8eHPeTNfdCrGOT9ozZhF5oKhsBZyFrVY7Wtf1YcXawh3bvtZxg9d8a2mKNXDeaF+uJrpI43aFa4KrJKdfvDpq2k0aJhL1QNxWSFBYw0tPJX/rhKAeOHHY2K44Wh5JNWwL+x1uYap93IK303sJ13hV0jXW7nXUhfIW7o5iUtbYWrpCvVwubZLf4U5Y=</encryptedKeychain>
   </encryptedKeychainList>
</tsResponse>
```

```
{
  "associatedUserLuidList": [],
  "encryptedKeychainList": {
    "encryptedKeychain": "BADsJ5lBKho2Tdqqbo7txS8IyKgNw5FnJud0etCHJLhBUurgIRHk3g5AeMQg6KHBw+6nwNIDEd65MKi76DLd5aIMhQC5aLCR4NE7R2gp7JbxLo+nOMGnfDQm5XekJVpLQGfY53GIX52ED2iTfOQ0yRNbnPV4djT0z23rosG0gpmqXV/py5okFzVW4wx8RisnZdvv+SAlv222jVhksX1w5A6HB3Bs45BeWfpwrOnHwnNoWUGwHuu4iGlyE7m65RlATZN+fvDGOFN1zU2lXaSZyWqRKiWkD+oCS5wRNtJ6lGz7RnesKvH6QEL9sT8cXA1ZOEA531xNAv9rjazEP5BssIdA1GcJ5J7zar5xxC68qm3cz3MkndyqWXZrf0vWPgwysUHEpWn60oDG/8/xG6c0Eigh4gwE+dA+NF1L2q9VyhVr8+AzJ7vatf95LDwAuRT43G3Q+WApx9qBPXco15pKjwy00rHPgn4cRtu+unwh6d3gIh6AbK6X++U/vV/Ktpe31lSZmV8eHPeTNfdCrGOT9ozZhF5oKhsBZyFrVY7Wtf1YcXawh3bvtZxg9d8a2mKNXDeaF+uJrpI43aFa4KrJKdfvDpq2k0aJhL1QNxWSFBYw0tPJX/rhKAeOHHY2K44Wh5JNWwL+x1uYap93IK303sJ13hV0jXW7nXUhfIW7o5iUtbYWrpCvVwubZLf4U5Y="
  }
}
```

#### Errors

<table class="api-error-table">
                        <colgroup>
                            <col class="api-error-table-col-1">
                            <col class="api-error-table-col-2">
                            <col class="api-error-table-col-3">
                            <col>
                        </colgroup>
                        <tbody>
                            <tr>
                                <th>HTTP status</th>
                                <th><code>error</code> Code</th>
                                <th>Condition</th>
                                <th>Details</th>
                            </tr>
                            <tr>
                                <td>400</td>
                                <td>400000</td>
                                <td>Bad Request</td>
                                <td>The content of the request body is missing or incomplete, or contains malformed XML.</td>
                            </tr>
                            <tr>
                                <td>401</td>
                                <td>401002</td>
                                <td>Unauthorized Access</td>
                                <td>
                                    <p>The authentication token provided in the request header was invalid or has expired.</p>
                                </td>
                            </tr>
                            <tr>
                                <td>403</td>
                                <td>403054</td>
                                <td>Unauthorized Access</td>
                                <td>A non-administrator user attempted to get data source revision information, but the caller doesn't have sufficient permissions.</td>
                            </tr>
                            <tr>
                                <td>404</td>
                                <td>404000</td>
                                <td>Site not found</td>
                                <td>The site ID in the URI doesn't correspond to an existing site.</td>
                            </tr>
                            <tr>
                                <td>404</td>
                                <td>404004
                    </td>
                                <td>Data source not found</td>
                                <td>The data source ID in the URI doesn't correspond to an existing data source.</td>
                            </tr>
                            <tr>
                                <td>405</td>
                                <td>405000</td>
                                <td>Invalid request method</td>
                                <td>Request type was not <span class="api-command-ref">POST</span>.</td>
                            </tr>
                        </tbody>
                    </table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Download Data Source Revision

Downloads a specific version of a data source prior to the current one in `.tdsx` format. To down load the current version of a data source use the [Download Data Source](#download_data_source) method.

**Note:** This method is available only if version history is enabled for the specified site. For more information, see [Maintain a History of Revisions](https://help.tableau.com/current/server/en-us/help.htm#revision_history_maintain.htm) in the Tableau Server Help.

#### URI

GET /api/api-version/sites/site-id/datasources/datasource-id/revisions/revision-number/content

#### Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-id</span></td><td>The ID of the site that contains the data source.</td></tr><tr><td><span class="api-placeholder">datasource-id</span></td><td>The ID of the data source to download.</td></tr><tr><td><span class="api-placeholder">revision-number</span></td><td>The revision number of the data source to download. To determine what versions are available, call <a href="#get_data_source_revisions">Get Data Source Revisions</a>.</td></tr></tbody></table>

#### Request Body

None

#### Permissions

Tableau Server users who are site administrators can download data source revisions on the site that they are administrators for. Users who are not server administrators or site administrators can get data source revisions if they have all of the following:

- A site role of ExplorerCanPublish.
- Read (view), Write (save), and Download (save as) permissions for the specified data source.
- Save (write) permissions for the project that contains the data source.

#### Access Scope

Scope added in API 3.27 (Tableau Cloud December 2025 / Server 2025.3).

```
tableau:content:read
```

For more information, see [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud) and access scopes for connected apps: [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm), or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### Response Code

200

#### Response Body

The data source content in `.tdsx` format (`Content-Type: application/octet-stream`).

The response will have the following content disposition header:

`Content-Disposition: name="tableau_datasource"; filename="datasource-filename"`

#### Version

Version 2.3 and later. For more information, see [REST API and Resource Versions](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm).

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>403</td><td>403028</td><td>Read forbidden</td><td>A non-administrator user attempted to download a data source, but the caller doesn't have required permissions.</td></tr><tr><td>403</td><td>403053</td><td>Version history not enabled</td><td>version history is not enabled for the specified site.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID in the URI doesn't correspond to an existing site.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The data source ID in the URI doesn't correspond to an existing data source.</td></tr><tr><td>404</td><td>404024</td><td>Data source revision not found</td><td>The revision number in the URI doesn't correspond to an existing data source revision.</td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">GET</span>.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Get Data Source Revisions

Returns a list of revision information (history) for the specified data source.

**Note:** This method is available only if version history is enabled for the specified site. For more information, see [Maintain a History of Revisions](https://help.tableau.com/current/server/en-us/help.htm#revision_history_maintain.htm) in the Tableau Server Help.

To get a specific version of the data source from revision history, use the [Download Data Source Revision](#download_data_source_revision) method.

#### URI

GET /api/api-version/sites/site-id/datasources/datasource-id/revisions

GET /api/api-version/sites/site-id/datasources/datasource-id/revisions?pageSize\=page-size&pageNumber\=page-number

#### Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-id</span></td><td>The ID of the site that contains the data source to get revisions for.</td></tr><tr><td><span class="api-placeholder">datasource-id</span></td><td>The ID of the data source to get revisions for.</td></tr><tr><td><span class="api-placeholder">page-size</span></td><td>(Optional) The number of items to return in one response. The minimum is 1. The maximum is 1000. The default is 100. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_paging.htm">Paginating Results</a>.</td></tr><tr><td><span class="api-placeholder">page-number</span></td><td>(Optional) The offset for paging. The default is 1. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_paging.htm">Paginating Results</a>.</td></tr></tbody></table>

#### Request Body

None

#### Permissions

Tableau Server users who are site administrators can get data source revisions on the site that they are administrators for. Users who are not server administrators or site administrators can get data source revisions if they have all of the following:

- A site role of ExplorerCanPublish.
- Read (view), Write (save), and Download (save as) permissions for the specified data source.
- Save (write) permissions for the project that contains the data source.

#### Access Scope

Scope added in API 3.27 (Tableau Cloud December 2025 / Server 2025.3).

```
tableau:content:read
```

For more information, see [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud) and access scopes for connected apps: [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm), or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### Response Code

200

#### Response Body

```
<tsResponse>
  <pagination pageNumber="pageNumber" pageSize="page-size"
    totalAvailable="total-available" />
  <revisions>
    <revision revisionNumber="1" publishedAt="date" deleted="false">
      <publisher id="publisher-id" name="publisher-name"/>
    </revision>
    <revision revisionNumber="2" publishedAt="date" deleted="false">
    </revision>
    <revision revisionNumber="3" publishedAt="date" deleted="false" current="true" sizeInBytes="size>
      <publisher id="publisher-id" name="publisher-name"/>
    </revision>
  </revisions>
</tsResponse>
```

If the revision element includes the attribute `deleted="true"`, the data source has been deleted and cannot be downloaded using the [Download Data Source Revision](#download_data_source_revision) method.

If a user has been deleted from the site, no `<publisher>` element is included in the `<revision>` element.

#### Version

Version 2.3 and later. For more information, see [REST API and Resource Versions](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm).

#### Errors

<table class="api-error-table">
                                <colgroup>
                                    <col class="api-error-table-col-1">
                                    <col class="api-error-table-col-2">
                                    <col class="api-error-table-col-3">
                                    <col>
                                </colgroup>
                                <tbody>
                                    <tr>
                                        <th>HTTP status</th>
                                        <th><code>error</code> Code</th>
                                        <th>Condition</th>
                                        <th>Details</th>
                                    </tr>
                                    <tr>
                                        <td>400</td>
                                        <td>400006</td>
                                        <td>Invalid page number</td>
                                        <td>
                                    The page number parameter is not an integer, is less than one, or is greater than the final page
                                    number for data sources at the requested page size.
                                </td>
                                    </tr>
                                    <tr>
                                        <td>400</td>
                                        <td>400007</td>
                                        <td>Invalid page size</td>
                                        <td>The page size parameter is not an integer, or is less than one.</td>
                                    </tr>
                                    <tr>
                                        <td>403</td>
                                        <td>403014</td>
                                        <td>Page size limit exceeded</td>
                                        <td>The specified page size is larger than the maximum page size.</td>
                                    </tr>
                                    <tr>
                                        <td>403</td>
                                        <td>403053</td>
                                        <td>Version history not enabled</td>
                                        <td>version history is not enabled for the specified site.</td>
                                    </tr>
                                    <tr>
                                        <td>403</td>
                                        <td>403054</td>
                                        <td>A non-administrator user attempted to get data source revision information, but the caller doesn't have sufficient permissions.</td>
                                    </tr>
                                    <tr>
                                        <td>404</td>
                                        <td>404000</td>
                                        <td>Site not found</td>
                                        <td>The site ID in the URI doesn't correspond to an existing site.</td>
                                    </tr>
                                    <tr>
                                        <td>404</td>
                                        <td></td>
                                        <td>Data source not found</td>
                                        <td>The data source ID in the URI doesn't correspond to an existing data source.</td>
                                    </tr>
                                    <tr>
                                        <td>405</td>
                                        <td>405000</td>
                                        <td>Invalid request method</td>
                                        <td>Request type was not <span class="api-command-ref">GET</span>.</td>
                                    </tr>
                                </tbody>
                            </table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Publish Data Source

Publishes a data source on the specified site, or appends data to an existing data source.

To make other changes to a published data source, call [Update Data Source](#update_data_source) or [Update Data Source Connection](#update_data_source_connection).

**Version**: Available in API 2.0 and later.

**License**: Available for Tableau Server and Tableau Cloud.

**Permissions**: You can publish a data source if you have implicit or explicit Publish permissions for the data source, or are a Tableau administrator.

Note: The `queryTaggingEnabled` attribute is returned only for administrator users.

**Access Scope**: `tableau:datasources:create`

For more information, see [Versions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm), [Permissions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm), [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud), and access scopes for [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows,](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm) or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

This method is used in two ways. You can call it to publish a data source in a single request. To do that, you include the content of the data source file in the body of the request. The maximum size of a file that can be published in a single request is 64 MB. If you want to avoid having the publishing process time out, you can use the _asJob_ parameter to make data source publication asynchronous.

Alternatively, you can publish a data source in multiple parts. To do that, you initiate a file upload by calling [Initiate File Upload](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref_publishing.htm#initiate_file_upload), send portions of the file to the server using [Append to File Upload](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref_publishing.htm#append_to_file_upload), and then commit the upload by calling Publish Data Source. In this case, Publish Data Source doesn't contain the file to publish.

**Extracts with multiple table options**  
Starting in v2021.4, you can publish multi table Hyper extract files created using the [Hyper API](https://help.tableau.com/current/api/hyper_api/en-us/docs/hyper_api_create_update.html). The data must include a single [fact table](https://en.wikipedia.org/wiki/Fact_table) containing the foreign keys that relate the tables to each other. The Hyper API infers the data object model, but does not perform any validation, such as referential integrity checking. If the Hyper API can’t infer the data object model of a Hyper extract, for instance, because there is more than one fact table, then attempting to publish the extract will fail. Prior to v2021.4, there was no way to append data to an extract with multiple tables using the REST API.

**Data Sources stored locally**  
When you publish a data source from your local computer to the server, you must make sure that the server has all the components that are required in order for other users to see and interact with the data source. For example, if the data source is based on an Excel spreadsheet, you typically publish a packaged data source (`.tdsx` file) that contains all the components for that data source.

**Replace data source**  
Starting in version 2025.1, you can use the replace parameter. You can include `overwrite`, `append`, and `replace` in a single request, but only one of these parameters can be set to true. If more than one is set to true, the request returns an HTTP 400 error.

**Working with Parquet files**  
\- When publishing a Parquet file to a data source through a live-to-Hyper connection, the files are converted to Hyper files. You may want to publish a copy of your original Parquet file to retain that data in its native format.  
\- A data source with a live-to-Hyper connection to data in a Hyper file converted from Parquet can only have a single connection.  
\- When incrementally updating that data from that connection, using the Update Hyper in Data Source method, the Parquet file is not converted to Hyper.

**Composed data sources and extended data sources**  
Starting in REST API version 3.29 (Cloud 262 and Server 2026.2), you can publish composed and extended data sources.  
  
When you publish a composed data source, you must include a `parentDataSourceUrls` element in addition to the `.tds` file so the composed data source is correctly linked to its parents. Include one entry for every published data source that is a direct parent of the composed data source. These correspond to the `datasource-url` tags serialized in the `.tds` file's data source tree. Include only the immediate parent data sources that the data source you are publishing depends on.  
  
When you publish an extended data source, include the `.tds` file as usual; no `parentDataSourceUrls` element is required.

For more information, see [Publishing Resources](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_publish.htm).

#### URI

POST /api/api-version/sites/site-luid/datasources

POST /api/api-version/sites/site-luid/datasources?overwrite=overwrite-flag&asJob=asJob-value

POST /api/api-version/sites/site-luid/datasources?append=append-flag

POST /api/api-version/sites/site-luid/datasources?uploadSessionId=upload-session-id&datasourceType=datasource-file-type&overwrite=overwrite-flag&append=append-flag&replace=replace-flag

#### URI Parameter Values

<table class="api-parameters-table">
                        <colgroup>
                            <col class="api-parameters-table-col-1-wide">
                            <col>
                        </colgroup>
                        <tbody>
                            <tr>
                                <td><span class="api-placeholder">api-version</span>
                                </td>
                                <td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">site-luid</span>
                                </td>
                                <td>The LUID of the site to publish to.</td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">overwrite-flag</span>
                                </td>
                                <td><span class="api-command-ref">true</span> to overwrite a data source that has the same name, or <span class="api-command-ref">false</span>
                                        to fail if the specified data source already exists. The default is <span class="api-command-ref">false</span>. If <span class="api-placeholder">overwrite-flag</span>
                                        is set to <span class="api-command-ref">true</span> but the data source doesn't already exist, the operation succeeds.
                                        <p>You can include both the  <span class="api-command-ref">overwrite</span> and <span class="api-command-ref">append</span> parameters in a request, but they cannot both be <span class="api-command-ref">true.</span></p></td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">replace-flag</span>
                                </td>
                                <td>(New in 2025.1) A boolean value (<strong>true </strong>or <strong>false</strong>). Set to <strong>true </strong>to replace the data in an existing data source. The default is <strong>false</strong>.</td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">asJob-value</span>
                                </td>
                                <td>A Boolean value that is used to publish data sources asynchronously. If you set this value to <i>false</i> (the default), the publishing process runs as a synchronous process. If a data source is very large, the process might time out before it finishes. If you set this value to <i>true</i>, the process runs asynchronously, and a job will start to perform the publishing process and return the job ID. You can check the status of the import job by calling <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref_jobs_tasks_and_schedules.htm#query_job">Query Job</a>.
									</td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">append-flag</span>
                                </td>
                                <td><span class="api-command-ref">true</span> to append the data being published to an existing data source that has the same name. The default
                                        is <span class="api-command-ref">false</span>. If <span class="api-placeholder">append-flag</span>
                                        is set to <span class="api-command-ref">true</span> but the data source doesn't already exist, the operation fails.
                                <p>
									In order to append data to a published data source on Tableau Server, both the source file and the published file must be
									an extract with the file extension <code>.hyper</code> or <code>.tde</code>. The schema of the source and the published extract must match.
								</p><p>If an extract was stored using the multiple tables option, you can't append data to it.</p><p>You can include both the  <span class="api-command-ref">overwrite</span> and <span class="api-command-ref">append</span> parameters in a request, but they cannot both be <span class="api-command-ref">true.</span></p></td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">upload-session-luid</span>
                                </td>
                                <td>If you are calling this method to commit a file that was uploaded in parts, this value contains the upload session LUID that was generated by a call to
                                        <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref_publishing.htm#initiate_file_upload"><span class="api-command-ref">Initiate File Upload</span></a>. If this value is not included, the server assumes
                                        that the body of the request contains the file to be published.
                                    </td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">datasource-file-type</span>
                                </td>
                                <td><span class="api-command-ref">hyper</span>, <span class="api-command-ref">tds</span>, <span class="api-command-ref">tdsx</span>, or <span class="api-command-ref">tde</span> the kind of file
                                        that you are uploading. This value is required if you are calling <span class="api-command-ref">Publish Data Source</span> in order to
                                        commit a file that was previously uploaded using <span class="api-command-ref">Append to File Upload</span>. The value is not used if you upload a file in the
                                        body of the request.
                                    </td>
                            </tr>
                        </tbody>
                    </table>

#### Request Body

The content type in the header of requests to publish a data source must use the mixed multipart content type with a boundary string definition, in the form of: `Content-Type: multipart/mixed; boundary=boundary-string`.

**Publishing a file in the request body**

```
--boundary-string
Content-Disposition: name="request_payload"
Content-Type: text/xml
<tsRequest>
	<datasource
	name="datasource-name"
	useRemoteQueryAgent="remote-query-agent-flag"
	description="datasource-description">
	<connectionCredentials
	name="connection-username"
	password="connection-password"
	embed="embed-flag"
	oAuth="oauth-flag" />
	<project
	id="project-id" />
	<parentDataSourceUrls>parent-datasource-url</parentDataSourceUrls>
	</datasource>
</tsRequest>
--boundary-string
Content-Disposition: name="tableau_datasource"; filename="SALES.TDSX"
Content-Type: application/octet-stream
content-of-datasource-file
--boundary-string--
```

**Committing a file previously uploaded**

```
--boundary-string
Content-Disposition: name="request_payload"
Content-Type: text/xml
<tsRequest>
	<datasource
	name="datasource-name" >
	<connectionCredentials
	name="connection-username"
	password="connection-password"
	embed="embed-flag"
	oAuth="oauth-flag" />
	<project
	id="project-id" />
	<parentDataSourceUrls>parent-datasource-url</parentDataSourceUrls>
	</datasource>
</tsRequest>
	--boundary-string--
```

**Publishing a file in the request body**

```
Content-Length: 16301
Content-Type: multipart/form-data; boundary=----------------------my_boundary_string
----------------------my_boundary_string
Content-Disposition: form-data; name="part1.json"
Content-Type: application/json
{
  "datasource": {
	"name": "datasource-name",
	"useRemoteQueryAgent": "remote-query-agent-flag",
	"description": "datasource-description",
	"connectionCredentials": {
	"name": "connection-username",
	"password": "connection-password",
	"embed": "embed-flag",
	"oAuth": "oauth-flag"
	},
  "project": {
	"id": "project-id"
	},
  "parentDataSourceUrls": [
  "parent-datasource-url"
   ]
   }
 }
 ----------------------my_boundary_string
Content-Disposition: form-data; name="datasource.tdsx"
Content-Type: application/octet-stream
content-of-datasource-file
----------------------my_boundary_string--
```

**Committing a file previously uploaded**

```
Content-Length: 16301
Content-Type: multipart/form-data; boundary=----------------------my_boundary_string
----------------------my_boundary_string
Content-Disposition: form-data; name="part1.json"
Content-Type: application/json
{
  "datasource": {
	"name": "datasource-name",
	"connectionCredentials": {
	"name": "connection-username",
	"password": "connection-password",
	"embed": "embed-flag",
	"oAuth": "oauth-flag"
	},
  "project": {
	"id": "project-id"
	},
  "parentDataSourceUrls": [
	"parent-datasource-url"
	]
  }
}
----------------------my_boundary_string--
```

#### Request Attributes

<table class="api-parameters-table">
                        <colgroup>
                            <col class="api-parameters-table-col-1-extra-wide">
                            <col>
                        </colgroup>
                        <tbody>
                            <tr>
                                <td><span class="api-placeholder">boundary-string</span>
                                </td>
                                <td>(Required) A string of characters that is guaranteed to be unique within the body of the request, and that is used to delimit sections of the request body. This value
                                        must be declared as a header that has this format:
                                        <p><code>Content-type: multipart/mixed; boundary=boundary-string</code></p></td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">datasource-name</span>
                                </td>
                                <td>(Required) The name to assign to the data source when it is saved on the server.</td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">remote-query-agent-flag</span>
                                </td>
                                <td>(Optional) When <code>true</code>, this flag will <a href="https://help.tableau.com/current/online/en-us/to_enable_bridge_live_connections.htm" target="_blank">allow your Tableau Cloud site to use Tableau Bridge clients</a>. Bridge allows you to maintain data sources with live connections to supported on-premises data sources.
							</td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">datasource-description</span>
                                </td>
                                <td>(Optional) A description of the data source.</td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">connection-username</span>
                                </td>
                                <td>(Optional) If the data source connection requires credentials, the <span class="api-command-ref">&lt;connectionCredentials&gt;</span> elements is included and this attribute specifies the connection username. If the element is included but is not required, the server ignores the element and its attributes.<p>If your auth type allows secrets to be passed as generic username and password variables, use this attribute for the appropriate secret, such as client id. (Example auth types include 2-legged OAuth, like Service Principal OAuth with Databricks and Client Credentials OAuth with Snowflake.)</p></td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">connection-password</span>
                                </td>
                                <td>(Optional) If the data source connection requires credentials, the <span class="api-command-ref">&lt;connectionCredentials&gt;</span> elements is included and this attribute specifies the connection password. If the element is included but is not required, the server ignores the element and its attributes.<p>If your auth type allows secrets to be passed as generic username and password variables, use this attribute for the appropriate secret, such as client secret. (Example auth types include 2-legged OAuth, like Service Principal OAuth with Databricks and Client Credentials OAuth with Snowflake.)</p></td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">embed-flag</span>
                                </td>
                                <td>(Optional) If the data source connection requires credentials, the <span class="api-command-ref">&lt;connectionCredentials&gt;</span> element is included. Setting this attribute to <span class="api-command-ref">true</span> instructs the server to save the credentials.</td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">oauth-flag</span>
                                </td>
                                <td>(Optional) If the data source connection is configured to use OAuth, set this to <code class="api-command-ref">true</code> to specify
									that the value of the <span class="api-command-ref">name</span> attribute in the
									<span class="api-command-ref">connectionCredentials</span> element is an OAuth username. In that case, no password is
									required and the value of the <span class="api-command-ref">embed</span> attribute specifies whether to embed the OAuth
									credential with the data source.<p>If your auth type allows secrets to be passed as generic username and password variables, set the <span class="api-command-ref">oAuth</span> attribute to <code>false</code>. (Example auth types include 2-legged OAuth, like Service Principal OAuth with Databricks and Client Credentials OAuth with Snowflake.)</p><p>For more information on OAuth, see the OAuth Connections section of the <a href="https://help.tableau.com/current/online/en-us/protected_auth.htm" target="_blank">Tableau Cloud</a> or <a href="https://help.tableau.com/current/server/en-us/protected_auth.htm" target="_blank">Tableau Server</a> Product Help.</p></td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">project-id</span>
                                </td>
                                <td>The LUID of the project to assign the data source to. If the project is not specified, the data source will be published to the default project.</td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">datasource-file-name</span>
                                </td>
                                <td>The file name (including extension) of the data source file to upload. This attribute is used in the request body only if the
                                        request also includes the content of the data source file; it is not used if you are committing a file uploaded using
                                        previous requests.
                                    </td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">	content-of-datasource-file</span>
                                </td>
                                <td>The content of the data source file, if the request includes the file. The maximum size of a file that can be uploaded in one call is 64&nbsp;MB.</td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">askDataEnablement</span>
                                </td>
                                <td>
									This attribute is not available in API 3.12 and later (Tableau Cloud September 2021 / Server 2021.3).
								</td>
                            </tr>
                            <tr>
                                <td><span class="api-placeholder">parentDataSourceUrls</span>
                                </td>
                                <td>The name (URL) of the immediately referenced published data source that the data source being published depends on. For a composed data source, you must include one entry for each top-level parent data source in the data model.
</td>
                            </tr>
                        </tbody>
                    </table>

#### cURL Example

`curl "http://MY_SERVER/api/3.4/sites/ff2a8360-3c2b-4b05-a793-7607c602e1fb/datasources" -X POST -H "X-Tableau-Auth:6fSulU7ET8yjpHteQj56MQ|LrkEdTHcmPkWFcD8wOEy29hlVXm8iPo4" -H "Content-Type: multipart/mixed;" -F "request_payload=@publish-datasource.xml" -F "tableau_datasource=@data-source.tds"`

**Content of publish-datasource.xml**:

```
<tsRequest>
  <datasource name="datasource1" description="This is a data source named datasource1." >
    <project id="522dc5c5-e1da-47b9-8e07-f02929ff5ceb" />
  </datasource>
</tsRequest>
```

#### Response Code

201

#### Response Body

```
<tsResponse>
  <datasource
	id="75b71d2f-e8d3-42af-b654-d953659326ee"
	name="Sales"
	contentUrl="mySite"
	description="Sales Data Source"
	useRemoteQueryAgent="True"
	webpageUrl="https://my_server/#/datasources/222"
	type="excel-direct"
	createdAt="2016-02-12T23:36:09Z"
	updatedAt="2020-12-16T15:33:03Z"
	isCertified="False"
	certificationNote="This is a certification note."
	encryptExtracts="True">
	  <project
		id="56c86f04-b834-4a08-a561-86497bb4b2df"
		name="Visualization"/>
	  <owner id="20148c74-7818-4eb8-b2a1-9f3f5f582613"/>
	  <tags/>
  </datasource>
</tsResponse>
```

```
{
  "datasource": {
	"id": "75b71d2f-e8d3-42af-b654-d953659326ee",
	"name": "Sales",
	"contentUrl": "mySite",
	"description": "Sales Data Source",
	"useRemoteQueryAgent": "True",
	"webpageUrl": "https://my_server/#/datasources/222",
	"type": "excel-direct",
	"createdAt": "2016-02-12T23:36:09Z",
	"updatedAt": "2020-12-16T15:33:03Z",
	"isCertified": "False",
	"certificationNote": "This is a certification note.",
	"encryptExtracts": "True",
	"project": {
	  "id": "56c86f04-b834-4a08-a561-86497bb4b2df",
	  "name": "Visualization"
	},
	"owner": {
	  "id": "20148c74-7818-4eb8-b2a1-9f3f5f582613"
	},
	"tags": []
  }
}
```

The `createdAt` and `updatedAt` attribute values are returned in UTC format (YYYY-MM-DDTHH:MM:SSZ).

#### Response Headers

`Location: /api/3.29/sites/site-id/datasources/id-from-server`

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td>400000</td><td>Bad request</td><td>The request message is missing or incomplete, or contains malformed XML. Make sure that the <span class="api-command-ref">Content-Length</span> value is set.</td></tr><tr><td>400</td><td>400000</td><td>Missing data source</td><td>There is no attachment in the request for the data source.</td></tr><tr><td>400</td><td>400008</td><td>Invalid <span class="api-command-ref">overwrite</span> value</td><td>The <span class="api-command-ref">overwrite</span> parameter must be set to <span class="api-command-ref">true</span> or <span class="api-command-ref">false</span>.</td></tr><tr><td>400</td><td>400008</td><td>Invalid <span class="api-command-ref">append</span> value</td><td>The <span class="api-command-ref">append</span> parameter must be set to <span class="api-command-ref">true</span> or <span class="api-command-ref">false</span>.</td></tr><tr><td>400</td><td>400008</td><td>Invalid <span class="api-command-ref">embed</span> value</td><td>The request body contains a <span class="api-command-ref">&lt;connectionCredentials&gt;</span> element and it has an <span class="api-command-ref">embed</span>&nbsp;attribute whose value is not <span class="api-command-ref">true</span>&nbsp;or&nbsp;<span class="api-command-ref">false</span>.</td></tr><tr><td>400</td><td>400010</td><td>Invalid data source filename</td><td>The name of the data source file did not end with the suffix <code>.hyper</code>, <code>.tds</code>, <code>.tdsx</code>, or <code>.tde</code>.</td></tr><tr><td>400</td><td>400010</td><td>Missing or invalid file type</td><td>The request included an <span class="api-command-ref">uploadSessionId</span>&nbsp;parameter but no file type, or the file type was something other than <span class="api-command-ref">hyper</span>, <span class="api-command-ref">tds</span>, <span class="api-command-ref">tdsx</span>, or <span class="api-command-ref">tde</span>.</td></tr><tr><td>400</td><td>400010</td><td>Unexpected attachments</td><td>The message had both a <span class="api-placeholder">uploadSessionId</span> parameter and an attachment, or the message contained more than one attachment.</td></tr><tr><td>400</td><td>400011</td><td>Publishing error</td><td>The data source could not be published for some other reason than those specified earlier.</td></tr><tr><td>400</td><td>400011</td><td>Bad Request</td><td>The request is invalid. This can occur if more than one of the conflict resolution parameters (<strong>overwrite</strong>, <strong>append</strong>, or <strong>replace</strong>) is set to <code>true</code>. Only one of these parameters can be true in a single request.</td></tr><tr><td>400</td><td>400019</td><td>Malformed request body</td><td>The request message is missing or incomplete, or contains malformed XML. Make sure that the <span class="api-command-ref">Content-Length</span> value is set.</td></tr><tr><td>400</td><td>400055</td><td>Incompatible <span class="api-command-ref">overwrite</span> and <span class="api-command-ref">append</span> values</td><td>The <span class="api-command-ref">overwrite</span> and <span class="api-command-ref">append</span> parameter cannot both be set to <span class="api-command-ref">true</span>.</td></tr><tr><td>400</td><td>400129</td><td>Invalid Ask Data enablement</td><td>The enablement setting in the request body is not valid for the current server configuration.</td></tr><tr><td>403</td><td>403007</td><td>Insufficient publishing permission</td><td>A non-administrator user attempted to publish a data source, but the caller doesn't have sufficient project permissions.</td></tr><tr><td>403</td><td>403007</td><td>Unlicensed publishing forbidden</td><td>A non-administrator user who is unlicensed attempted to publish a data source. This is disallowed for all projects (including the default project).</td></tr><tr><td>403</td><td>403007</td><td>Overwrite forbidden</td><td>A data source with the specified name already exists and the <span class="api-command-ref">overwrite</span> parameter was not set to <span class="api-command-ref">true</span>.</td></tr><tr><td>403</td><td>403007</td><td>Problem connecting to data source</td><td>There was a problem connecting to a data source.&nbsp;This can be due to missing or invalid connection credentials or because the referenced data source is not available on the server.</td></tr><tr><td>403</td><td>403008</td><td>Insufficient storage quota</td><td>The data source could not be published because there is not enough storage remaining on the server to accommodate its size.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID in the URI doesn't correspond to an existing site.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The <span class="api-command-ref">append</span> parameter is <span class="api-command-ref">true</span> but the data source name specified in the request body does not correspond to an existing data source.</td></tr><tr><td>404</td><td>404005</td><td>Project not found</td><td>The project ID in the request body doesn't correspond to an existing project on the site.</td></tr><tr><td>404</td><td>404015</td><td>File upload not found</td><td>The file upload session ID in the request body doesn't correspond to an existing file upload on the site.</td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">POST</span>.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Publish Work Copy

Publishes a work copy as a data source. Send the published data source `name` and an optional `description`. The response returns the new data source LUID. A blank name is rejected.

**Version**: Available in API 3.30 (Tableau Cloud October 2026 / Server 2026.3) and later.

**License**: Data Management or Tableau+.

**Permissions**: Users who are not server administrators or site administrators can call this method only if they have Connect, Write (save), and VizqlDataApiAccess (API Access) permissions for the data source that the work copy was created from (either explicitly or implicitly).

**Access Scope**: `tableau:datasources:create`

For more information, see [Versions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm), [Permissions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm), [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud), and access scopes for [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows,](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm) or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### URI

POST /api/api-version/tds/sites/site-luid/workcopy/workcopy-luid/publish

#### URI Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use. These TDS Edit methods are available in API 3.30 and later. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-luid</span></td><td>The LUID of the site in the URI. This handler does not bind the path variable — the service uses the authenticated user's site LUID (<code>authUser.getSiteLuid()</code>).</td></tr><tr><td><span class="api-placeholder">workcopy-luid</span></td><td>The LUID of the work copy. Must be a UUID (8-4-4-4-12 hexadecimal digits), matching <code>[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}</code>.</td></tr></tbody></table>

#### Request Body

```
<tsRequest>
  <datasource name="Quarterly Sales" description="Quarterly sales rollup." />
</tsRequest>
```

```
{
  "datasource": {
    "name": "Quarterly Sales",
    "description": "Quarterly sales rollup."
  }
}
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1"> <col></colgroup><tbody><tr><td><span class="api-placeholder">datasource</span></td><td>Required. Published data source name and optional description. Other data source fields are not read by this method.</td></tr><tr><td><span class="api-placeholder">datasource.name</span></td><td>Required. Name of the data source to publish. A null, empty, or whitespace-only value is HTTP 400 with error code <code>400008</code>.</td></tr><tr><td><span class="api-placeholder">datasource.description</span></td><td>Optional. Description of the published data source. May be null, empty, or whitespace.</td></tr></tbody></table>

#### Response Code

201 Created

#### Response Body

Returns the published data source's identifiers in `tdsWorkCopy`. The response includes `datasourceLuid` but not `workCopyLuid`.

```
<tsResponse>
  <tdsWorkCopy>
    <datasourceLuid>a1b2c3d4-e5f6-4321-8765-1234567890ab</datasourceLuid>
  </tdsWorkCopy>
</tsResponse>
```

```
{
  "tdsWorkCopy": {
    "datasourceLuid": "a1b2c3d4-e5f6-4321-8765-1234567890ab"
  }
}
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1"> <col></colgroup><tbody><tr><td><span class="api-placeholder">tdsWorkCopy</span></td><td>Required. Work copy and published data source identifiers.</td></tr><tr><td><span class="api-placeholder">tdsWorkCopy.workCopyLuid</span></td><td>Optional. LUID of the work copy. Not returned by this method; returned by Create Work Copy.</td></tr><tr><td><span class="api-placeholder">tdsWorkCopy.datasourceLuid</span></td><td>LUID of the newly published data source.</td></tr></tbody></table>

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td>400008</td><td>Datasource name missing</td><td>The published data source name is missing or blank.</td></tr><tr><td>400</td><td></td><td>Invalid work copy LUID</td><td>The work copy LUID in the URI is not a UUID (8-4-4-4-12 hexadecimal digits).</td></tr><tr><td>401</td><td>401000 / 401002</td><td>Missing or invalid authentication</td><td>No authentication token provided, or token is expired or invalid.</td></tr><tr><td>403</td><td>403004</td><td>Data Management Bundle not licensed</td><td>On Tableau Server the TDS Edit API requires a Data Management Bundle license. The call is rejected when that license is absent.</td></tr><tr><td>403</td><td>403004</td><td>Unable to resolve tenant</td><td>On Tableau Cloud the subscription could not be checked because the tenant id for the site could not be retrieved.</td></tr><tr><td>403</td><td>403004</td><td>No cloud entitlements</td><td>On Tableau Cloud no entitlements were found for the tenant. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>403</td><td>403004</td><td>Subscription not entitled</td><td>On Tableau Cloud the site edition is not Tableau+. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>404</td><td></td><td>Work copy not found or not visible to the caller</td><td>The work copy LUID in the URI doesn't correspond to an existing work copy, or the caller doesn't have permission to access it.</td></tr><tr><td>405</td><td>405000</td><td>Method not allowed</td><td>The HTTP method is not supported for this resource.</td></tr><tr><td>429</td><td>429000</td><td>Rate limit exceeded</td><td>Too many requests sent in a given time period.</td></tr><tr><td>500</td><td></td><td>Unknown error</td><td>There was an internal server error.</td></tr><tr><td>503</td><td></td><td>Service unavailable</td><td>Service unavailable.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Query Data Source

Returns information about the specified data source.

**Note**: After you create a resource, the server updates its search index. If you make a query immediately to see a new resource, the query results might not be up to date.

#### URI

GET /api/api-version/sites/site-id/datasources/datasource-id

#### Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-id</span></td><td>The site that contains the data source.</td></tr><tr><td><span class="api-placeholder">datasource-id</span></td><td>The ID of the data source to get.</td></tr></tbody></table>

#### Request Body

None

#### Permissions

Users who are not server administrators or site administrators can view a data source only if they have Connect permission for the data source (either explicitly or implicitly).

#### Required scope for JWT authorization

Introduced in Tableau Cloud June 2022 (API 3.16) and Tableau Server 2022.3 (API 3.17).

```
tableau:content:read
```

For more information, see [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud) and access scopes for connected apps: [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm), or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### Response Code

200

#### Response Body

```
<tsResponse>
  <datasource id="datasource-id"
	certificationNote="certification-note"
	name="datasource-name"
	description="data-source-description"
	type="datasource-type"
    contentUrl="datasource-content-url"
    createdAt="datetime-created"
    updatedAt="datetime-updated"
    encryptExtracts="encryptExtracts"
	hasExtracts="has-extracts-flag"
 	isCertified="is-certified-flag"
	useRemoteQueryAgent="use-remote-query-agent-flag"
	webpageUrl="web-page-url" >
      <project id="project-id" name="project-name" />
      <owner id="datasource-owner-id"  />
      <tags>
        <tag label="tag"/>
        ... additional tags ...
      </tags>
      <askData enablement="enablement-setting"/>
  </datasource>
</tsResponse>
```

The datetime-created and datetime-updated attribute values are returned in UTC format (YYYY-MM-DDTHH:MM:SSZ).

#### Version

Version 1.0 and later. For more information, see [REST API and Resource Versions](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm).

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>403</td><td>403004</td><td>Read forbidden</td><td>A non-administrator user attempted to query a data source, but the caller doesn't have <span class="api-command-ref">Connect</span> permission.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID in the URI doesn't correspond to an existing site.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The data source ID in the URI doesn't correspond to an existing data source.</td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">GET</span>.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

#### Example

`curl "http://MY-SERVER/api/3.29/sites/9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d/datasources/1a2a3b4b-5c6c-7d8d-9e0e-1f2f3a4a5b6b" -X GET -H "X-Tableau-Auth:12ab34cd56ef78ab90cd12ef34ab56cd"`

**Example response:**

```
<tsResponse version-and-namespace-settings>
  <datasource id="1a2a3b4b-5c6c-7d8d-9e0e-1f2f3a4a5b6b" name="Activity rates and healthy living"
    certificationNote="This is a note about the datasource certification."
	contentUrl="activity-dates-and-healthy-living"
	encryptExtracts="true"
	description="The Activity and Health data source."
	isCertified="true"
	type="excel-direct"
	createdAt="2011-03-30T22:32:35Z"
	updatedAt="2016-01-13T01:00:02Z">
	useRemoteQueryAgent="false"
	webpageUrl="https://MYSERVER/#/datasources/4414"
      <project id="1f2f3e4e5-d6d7-c8c9-b0b1-a2a3f4f5e6e" name="default"/>
      <owner id="9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d"/>
      <tags>
      </tags>
	  <askData enablement="Enabled"/>
  </datasource>
</tsResponse>
```

**Note:** This method returns connection information, including connection type. In some cases, the name of the connection type might not map directly to a name of a connection type that you're familiar with. In those cases, see [Mapping ConnectionType Names](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_connectiontype.htm) for more information.

## Query Data Sources

Returns a list of published data sources on the specified site, with optional parameters for specifying the paging of large results. To get a list of data sources embedded in a workbook, use the [Query Workbook Connections](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#query_workbook_connections) method.

**Note**: After you create a resource, the server updates its search index. If you make a query immediately to see a new resource, the query results might not be up to date.

**Version**: Available in API 1.0 and later.

**License**: No additional license required.

**Permissions**: Tableau Server users who are not server administrators or site administrators can view a data source only if they have Connect permissions for the data source (either explicitly or implicitly).

**Access Scope**: `tableau:content:read`

- For more information, see [Versions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm), [Permissions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm), [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud), and access scopes for [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows,](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm) or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### URI

GET /api/api-version/sites/site-id/datasources

GET /api/api-version/sites/site-id/datasources?pageSize\=page-size&pageNumber\=page-number

GET /api/api-version/sites/site-id/datasources?filter=filter-expression

GET /api/api-version/sites/site-id/datasources?sort=sort-expression

GET /api/api-version/sites/site-id/datasources?fields=field-expression

#### Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-id</span></td><td>The ID of the site that contains the data sources.</td></tr><tr><td><span class="api-placeholder">page-size</span></td><td>(Optional) The number of items to return in one response. The minimum is 1. The maximum is 1000. The default is 100. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_paging.htm">Paginating Results</a>.</td></tr><tr><td><span class="api-placeholder">page-number</span></td><td>(Optional) The offset for paging. The default is 1. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_paging.htm">Paginating Results</a>.</td></tr><tr><td><span class="api-placeholder">filter-expression</span></td><td>(Optional) An expression that lets you specify a subset of data sources to return. You can filter on predefined fields such as <code>name</code> and <code>updatedAt</code>. You can include multiple filter expressions. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_filtering_and_sorting.htm">Filtering and Sorting</a>.</td></tr><tr><td><span class="api-placeholder">sort-expression</span></td><td>(Optional) An expression that lets you specify the order in which user information is returned. If you do not specify a sort expression, the sort order of the information that's returned is undefined. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_filtering_and_sorting.htm">Filtering and Sorting</a>.</td></tr><tr><td><span class="api-placeholder">field-expression</span></td><td>(Optional) An expression that lets you specify the set of available fields to return. You can qualify the return values based upon predefined keywords such as <code>_all_</code> or <code>_default_</code>, and you can specify individual fields for the data sources or other supported resources. You can include multiple field expressions in a request. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_fields.htm">Using Fields in the Rest API</a>.</td></tr></tbody></table>

**Note**: The filter and sort parameters can be combined with each other and with paging parameters and fields parameters using an ampersand (**`&`**).

#### Request Body

None

#### Response Code

200

#### Response Body

```
<tsResponse>
  <pagination pageNumber="pageNumber" pageSize="page-size"
    totalAvailable="total-available" />
  <datasources>
    <datasource id="datasource1-id"
      description="data-source-description"
      name="datasource-name"
      size="datasource-size"
      type="datasource-type"
      contentUrl="datasource-content-url"
      createdAt="datetime-created"
      updatedAt="datetime-updated"
      encryptExtracts="encrypt-extracts-flag"
      hasExtracts="has-extracts-flag"
      isCertified="is-certified-flag"
      useRemoteQueryAgent="use-remote-query-agent-flag"
      webpageUrl="datasource-webpage-url"  >
	    <project id="project-id" name="project-name" />
        <owner id="datasource-owner-id" />
        <tags>
          <tag label="tag"/>
          <!-- potential additional tags -->
        </tags>
    </datasource>
    <!-- potential additional data sources -->
  </datasources>
</tsResponse>
```

```
{
  "pagination": {
    "pageNumber": "pageNumber",
    "pageSize": "page-size",
    "totalAvailable": "total-available"
  },
  "datasources": {
    "datasource": [
	 {
      "id": "datasource1-id",
      "description": "data-source-description",
      "name": "datasource-name",
      "size": "datasource-size",
      "type": "datasource-type",
      "contentUrl": "datasource-content-url",
      "createdAt": "datetime-created",
      "updatedAt": "datetime-updated",
      "encryptExtracts": "encrypt-extracts-flag",
      "hasExtracts": "has-extracts-flag",
      "isCertified": "is-certified-flag",
      "useRemoteQueryAgent": "use-remote-query-agent-flag",
      "webpageUrl": "datasource-webpage-url",
      "project": {
        "id": "project-id",
        "name": "project-name"
      },
      "owner": {
        "id": "datasource-owner-id"
      },
      "tags": [
		{
          "label": "tag"
        }
		]
      }
	]
  }
}
```

#### cURL Example

```
curl "http://MY-SERVER/api/3.29/sites/9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d/datasources" -X GET -H "X-Tableau-Auth:12ab34cd56ef78ab90cd12ef34ab56cd"
```

**Example response:**

```
<tsResponse version-and-name-space-settings>
  <pagination pageNumber="1" pageSize="100" totalAvailable="2"/>
  <datasources>
    <datasource id="1a2a3b4b-5c6c-7d8d-9e0e-1f2f3a4a5b6b"
      name="Sample - Coffee Chain (Access)"
      size="1"
      type="googledrive"
      contentUrl="coffee-chain"
      description="The Sample - Coffee Chain data source."
      type="msaccess"
      createdAt="2011-03-30T22:32:35Z"
      updatedAt="2016-01-13T01:00:02Z"
      encryptExtracts="false"
      isCertified="false"
      useRemoteQueryAgent="false"
      webpageUrl="https://my-server.com/#/site/my-site/datasources/1275708" >
        <project id="1f2f3e4e-5d6d-7c8c-9b0b-1a2a3f4f5e6e" name="Default"/>
        <owner id="9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d"/>
        <tags>
	  	  <tag label="test"/>
        </tags>
    </datasource>
  </datasources>
</tsResponse>
```

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td>400006</td><td>Invalid page number</td><td>The page number parameter is not an integer, is less than one, or is greater than the final page number for data sources at the requested page size.</td></tr><tr><td>400</td><td>400007</td><td>Invalid page size</td><td>The page size parameter is not an integer, or is less than one.</td></tr><tr><td>403</td><td>403014</td><td>Page size limit exceeded</td><td>The specified page size is larger than the maximum page size.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID in the URI doesn't correspond to an existing site.</td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">GET</span>.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Query Data Source Connections

Returns a list of data connections for the specified data source.

#### URI

GET /api/api-version/sites/site-id/datasources/datasource-id/connections

#### Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-extra-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-id</span></td><td>The ID of the site that contains the data source.</td></tr><tr><td><span class="api-placeholder">datasource-id</span></td><td>The ID of the data source to return connection information about.</td></tr></tbody></table>

#### Request Body

None

#### Permissions

Users who are not server administrators or site administrators can query a data source only if they have Read (view) permission for the data source (either explicitly or implicitly). `queryTaggingEnabled` is returned only for administrator users.

#### Required scope for JWT authorization

Introduced in Tableau Cloud June 2022 (API 3.16) and Tableau Server 2022.3 (API 3.17).

```
tableau:content:read
```

For more information, see [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud) and access scopes for connected apps: [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm), or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### Response Code

200

#### Response Body

```
<tsResponse>
  <connections>
    <connection id="connection-id" type="connection-type"
      serverAddress="server-address" serverPort="port"
      userName="connection-user-name"
      queryTaggingEnabled="query-tagging-enabled"
      authenticationType="authentication-type"
      useOAuthManagedKeychain="using-OAuth-managed-keychain-or-not /> />
	< ... additional connections ... >
  </connections>
</tsResponse>
```

#### Version

Version 2.3 and later. For more information, see [REST API and Resource Versions](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm).

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>403</td><td>403021</td><td>Read forbidden</td><td>A user who is not a server administrator user attempted to query the data source connections, but the caller doesn't have <span class="api-command-ref">Read</span> permission.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID in the URI doesn't correspond to an existing site.</td></tr><tr><td>404</td><td>404011</td><td>Data source not found</td><td>The data source ID in the URI doesn't correspond to an existing data source.</td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">GET</span>.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

#### Example

`curl "http://MY-SERVER/api/3.29/sites/9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d/datasources/1a1b1c1d-2e2f-2a2b-3c3d-3e3f4a4b4c4d/connections" -X GET -H "X-Tableau-Auth:12ab34cd56ef78ab90cd12ef34ab56cd"`

**Example response:**

```
<tsResponse version-and-namespace-settings>
  <connections>
    <connection id="12ab34cd-56ef-78ab-90cd-12ef34ab56cd" type="dataengine" />
    <connection id="374371c0-ffe9-4e16-b48e-6b868e3026ca" type="dataengine" />
    <connection id="08a7b6b5-b4ba-be3a-4d2d-1e9e59a8a7b6" type="dataengine" />
  </connections>
</tsResponse>
```

**Note:** This method returns connection information, including connection type. In some cases, the name of the connection type might not map directly to a name of a connection type that you're familiar with. In those cases, see [Mapping ConnectionType Names](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_connectiontype.htm) for more information.

## Read Data Source Elements

Reads columns, field descriptions, or table descriptions from a published data source. Set `elementType` to the kind of element, and optionally set `name` to read one element.

A missing named element returns HTTP 404. When a read record fails inside a successful response, the failure is on that element's `error` field and the HTTP status stays 200.

**Version**: Available in API 3.30 (Tableau Cloud October 2026 / Server 2026.3) and later.

**License**: Data Management or Tableau+.

**Permissions**: Users who are not server administrators or site administrators can call this method only if they have Connect, Write (save), and VizqlDataApiAccess (API Access) permissions for the data source (either explicitly or implicitly).

**Access Scope**: `tableau:content:read`

For more information, see [Versions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm), [Permissions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm), [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud), and access scopes for [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows,](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm) or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### URI

GET /api/api-version/tds/sites/site-luid/datasource/datasource-luid

#### URI Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use. These TDS Edit methods are available in API 3.30 and later. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-luid</span></td><td>The LUID of the site in the URI. This handler does not bind the path variable — the service uses the authenticated user's site LUID (<code>authUser.getSiteLuid()</code>).</td></tr><tr><td><span class="api-placeholder">datasource-luid</span></td><td>The LUID of the data source. Must be a UUID (8-4-4-4-12 hexadecimal digits), matching <code>[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}</code>.</td></tr><tr><td><code>elementType</code></td><td>Required. The kind of element to return. Allowed values are <code>Column</code>, <code>FieldDescription</code>, and <code>TableDescription</code>.</td></tr><tr><td><code>name</code></td><td>Optional. The name of a single element to read. When omitted, the call lists elements of the requested <code>elementType</code>. When this value is non-empty and the TDS service returns gRPC <code>NOT_FOUND</code>, the API responds 404 with error code <code>404065</code>.</td></tr></tbody></table>

#### Response Code

200 OK

#### Response Body

Returns the elements read from the data source or work copy in `tdsElementList`. Each entry carries either a `column` payload (when `elementType` is `Column`) or a `description` string (when `elementType` is `FieldDescription` or `TableDescription`). If an individual read record fails, that entry carries an `error` object instead and the overall HTTP status stays 200.

```
<tsResponse>
  <tdsElementList>
    <elementType>Column</elementType>
    <name>Sales</name>
    <column>
      <caption>Sales</caption>
      <role>MEASURE</role>
      <type>REAL</type>
    </column>
  </tdsElementList>
  <tdsElementList>
    <elementType>FieldDescription</elementType>
    <name>Sales</name>
    <description>Total sales amount.</description>
  </tdsElementList>
  <tdsElementList>
    <name>Orders</name>
    <error>
      <code>5</code>
      <message>NOT_FOUND</message>
    </error>
  </tdsElementList>
</tsResponse>
```

```
{
  "tdsElementList": [
    {
      "elementType": "Column",
      "name": "Sales",
      "column": {
        "caption": "Sales",
        "role": "MEASURE",
        "type": "REAL"
      }
    },
    {
      "elementType": "FieldDescription",
      "name": "Sales",
      "description": "Total sales amount."
    },
    {
      "name": "Orders",
      "error": {
        "code": 5,
        "message": "NOT_FOUND"
      }
    }
  ]
}
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1"> <col></colgroup><tbody><tr><td><span class="api-placeholder">tdsElementList[]</span></td><td>Required. Elements read from the data source or work copy. Empty when the TDS service returns no records.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].elementType</span></td><td>Optional. Element type. Not set by the read converter for this operation.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].name</span></td><td>Required. Name of the element, set from the gRPC read result or from the failure record when the record failed.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column</span></td><td>Optional. Present when the read result is a column. Mutually exclusive with <code>description</code>.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column.caption</span></td><td>Optional. Column display caption from the TDS service.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column.role</span></td><td>Optional. Column role, <code>FieldRole.name()</code> from the TDS service.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column.type</span></td><td>Optional. Column field type, <code>FieldType.name()</code> from the TDS service.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].description</span></td><td>Optional. Description text. Present when the read result is a field description or a table description. Mutually exclusive with <code>column</code>.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].error</span></td><td>Optional. Present only when this read record failed. The HTTP status of the read stays 200.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].error.code</span></td><td>Required (within <code>error</code>). The raw gRPC status code for the failed record — not a translated HTTP code and not a Tableau 6-digit error code.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].error.message</span></td><td>Optional. Error message from the TDS service.</td></tr></tbody></table>

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td></td><td>Invalid data source LUID</td><td>The data source LUID in the URI is not a UUID (8-4-4-4-12 hexadecimal digits).</td></tr><tr><td>400</td><td></td><td>Invalid elementType</td><td><code>elementType</code> must be <code>Column</code>, <code>FieldDescription</code>, or <code>TableDescription</code>.</td></tr><tr><td>401</td><td>401000 / 401002</td><td>Missing or invalid authentication</td><td>No authentication token provided, or token is expired or invalid.</td></tr><tr><td>403</td><td>403004</td><td>Data Management Bundle not licensed</td><td>On Tableau Server the TDS Edit API requires a Data Management Bundle license. The call is rejected when that license is absent.</td></tr><tr><td>403</td><td>403004</td><td>Unable to resolve tenant</td><td>On Tableau Cloud the subscription could not be checked because the tenant id for the site could not be retrieved.</td></tr><tr><td>403</td><td>403004</td><td>No cloud entitlements</td><td>On Tableau Cloud no entitlements were found for the tenant. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>403</td><td>403004</td><td>Subscription not entitled</td><td>On Tableau Cloud the site edition is not Tableau+. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>404</td><td>404065</td><td>TDS element not found</td><td>No element with the requested name exists. Returned only when the <code>name</code> query parameter is non-empty. A missing data source or work copy is not given this code.</td></tr><tr><td>405</td><td>405000</td><td>Method not allowed</td><td>The HTTP method is not supported for this resource.</td></tr><tr><td>429</td><td>429000</td><td>Rate limit exceeded</td><td>Too many requests sent in a given time period.</td></tr><tr><td>500</td><td></td><td>Unknown error</td><td>There was an internal server error.</td></tr><tr><td>503</td><td></td><td>Service unavailable</td><td>Service unavailable.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Read Work Copy Elements

Reads columns, field descriptions, or table descriptions from a work copy. Set `elementType` to the kind of element, and optionally set `name` to read one element.

A missing named element returns HTTP 404. When a read record fails inside a successful response, the failure is on that element's `error` field and the HTTP status stays 200.

**Version**: Available in API 3.30 (Tableau Cloud October 2026 / Server 2026.3) and later.

**License**: Data Management or Tableau+.

**Permissions**: Users who are not server administrators or site administrators can call this method only if they have Connect, Write (save), and VizqlDataApiAccess (API Access) permissions for the data source that the work copy was created from (either explicitly or implicitly).

**Access Scope**: `tableau:content:read`

For more information, see [Versions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm), [Permissions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm), [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud), and access scopes for [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows,](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm) or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### URI

GET /api/api-version/tds/sites/site-luid/workcopy/workcopy-luid

#### URI Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use. These TDS Edit methods are available in API 3.30 and later. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-luid</span></td><td>The LUID of the site in the URI. This handler does not bind the path variable — the service uses the authenticated user's site LUID (<code>authUser.getSiteLuid()</code>).</td></tr><tr><td><span class="api-placeholder">workcopy-luid</span></td><td>The LUID of the work copy. Must be a UUID (8-4-4-4-12 hexadecimal digits), matching <code>[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}</code>.</td></tr><tr><td><code>elementType</code></td><td>Required. The kind of element to return. Allowed values are <code>Column</code>, <code>FieldDescription</code>, and <code>TableDescription</code>.</td></tr><tr><td><code>name</code></td><td>Optional. The name of a single element to read. When omitted, the call lists elements of the requested <code>elementType</code>. When this value is non-empty and the TDS service returns gRPC <code>NOT_FOUND</code>, the API responds 404 with error code <code>404065</code>.</td></tr></tbody></table>

#### Response Code

200 OK

#### Response Body

Returns the elements read from the work copy in `tdsElementList`. Each entry carries either a `column` payload (when `elementType` is `Column`) or a `description` string (when `elementType` is `FieldDescription` or `TableDescription`). If an individual read record fails, that entry carries an `error` object instead and the overall HTTP status stays 200.

```
<tsResponse>
  <tdsElementList>
    <elementType>FieldDescription</elementType>
    <name>Sales</name>
    <description>Total sales amount, updated on the work copy.</description>
  </tdsElementList>
  <tdsElementList>
    <elementType>TableDescription</elementType>
    <name>Orders</name>
    <description>Order line items.</description>
  </tdsElementList>
  <tdsElementList>
    <name>Region</name>
    <error>
      <code>5</code>
      <message>NOT_FOUND</message>
    </error>
  </tdsElementList>
</tsResponse>
```

```
{
  "tdsElementList": [
    {
      "elementType": "FieldDescription",
      "name": "Sales",
      "description": "Total sales amount, updated on the work copy."
    },
    {
      "elementType": "TableDescription",
      "name": "Orders",
      "description": "Order line items."
    },
    {
      "name": "Region",
      "error": {
        "code": 5,
        "message": "NOT_FOUND"
      }
    }
  ]
}
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1"> <col></colgroup><tbody><tr><td><span class="api-placeholder">tdsElementList[]</span></td><td>Required. Elements read from the data source or work copy. Empty when the TDS service returns no records.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].elementType</span></td><td>Optional. Element type. Not set by the read converter for this operation.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].name</span></td><td>Required. Name of the element, set from the gRPC read result or from the failure record when the record failed.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column</span></td><td>Optional. Present when the read result is a column. Mutually exclusive with <code>description</code>.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column.caption</span></td><td>Optional. Column display caption from the TDS service.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column.role</span></td><td>Optional. Column role, <code>FieldRole.name()</code> from the TDS service.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column.type</span></td><td>Optional. Column field type, <code>FieldType.name()</code> from the TDS service.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].description</span></td><td>Optional. Description text. Present when the read result is a field description or a table description. Mutually exclusive with <code>column</code>.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].error</span></td><td>Optional. Present only when this read record failed. The HTTP status of the read stays 200.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].error.code</span></td><td>Required (within <code>error</code>). The raw gRPC status code for the failed record — not a translated HTTP code and not a Tableau 6-digit error code.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].error.message</span></td><td>Optional. Error message from the TDS service.</td></tr></tbody></table>

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td></td><td>Invalid work copy LUID</td><td>The work copy LUID in the URI is not a UUID (8-4-4-4-12 hexadecimal digits).</td></tr><tr><td>400</td><td></td><td>Invalid elementType</td><td><code>elementType</code> must be <code>Column</code>, <code>FieldDescription</code>, or <code>TableDescription</code>.</td></tr><tr><td>401</td><td>401000 / 401002</td><td>Missing or invalid authentication</td><td>No authentication token provided, or token is expired or invalid.</td></tr><tr><td>403</td><td>403004</td><td>Data Management Bundle not licensed</td><td>On Tableau Server the TDS Edit API requires a Data Management Bundle license. The call is rejected when that license is absent.</td></tr><tr><td>403</td><td>403004</td><td>Unable to resolve tenant</td><td>On Tableau Cloud the subscription could not be checked because the tenant id for the site could not be retrieved.</td></tr><tr><td>403</td><td>403004</td><td>No cloud entitlements</td><td>On Tableau Cloud no entitlements were found for the tenant. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>403</td><td>403004</td><td>Subscription not entitled</td><td>On Tableau Cloud the site edition is not Tableau+. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>404</td><td>404065</td><td>TDS element not found</td><td>No element with the requested name exists. Returned only when the <code>name</code> query parameter is non-empty. A missing data source or work copy is not given this code.</td></tr><tr><td>405</td><td>405000</td><td>Method not allowed</td><td>The HTTP method is not supported for this resource.</td></tr><tr><td>429</td><td>429000</td><td>Rate limit exceeded</td><td>Too many requests sent in a given time period.</td></tr><tr><td>500</td><td></td><td>Unknown error</td><td>There was an internal server error.</td></tr><tr><td>503</td><td></td><td>Service unavailable</td><td>Service unavailable.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Remove Data Source Revision

Removes a specific version of a data source from the specified site.

The content is removed, and the specified revision can no longer be downloaded using [Download Data Source Revision](#download_data_source_revision). If you call [Get Data Source Revisions](#get_data_source_revisions), the revision that's been removed is listed with the attribute `IsDeleted="true"`.

**Note:** Calling this method permanently removes the specified data source revision.

#### URI

DELETE /api/api-version/sites/site-id/datasources/datasource-id/revisions/revision-number

#### Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-id</span></td><td>The ID of the site that contains the group.</td></tr><tr><td><span class="api-placeholder">datasource-id</span></td><td>The ID of the data source to remove the revision for.</td></tr><tr><td><span class="api-placeholder">revision-number</span></td><td>The revision number of the data source to remove. To determine what versions are available, call <a href="#get_data_source_revisions">Get Data Source Revisions</a>.</td></tr></tbody></table>

#### Request Body

None

#### Permissions

Tableau Server users who are site administrators can remove data source revisions on the site that they are administrators for. Users who are not server administrators or site administrators can remove data source revisions if they have all of the following:

- A site role of ExplorerCanPublish.
- Read (view), Write (save), and Download (save as) permissions for the specified data source.
- Save (write) permissions for the project that contains the data source.

#### Access Scope

Scope added in API 3.27 (Tableau Cloud December 2025 / Server 2025.3).

```
tableau:datasources:delete
```

For more information, see [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud) and access scopes for connected apps: [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm), or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### Response Code

204

#### Response Body

None

#### Version

Version 2.3 and later. For more information, see [REST API and Resource Versions](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm).

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>403</td><td>403004</td><td>Deletion forbidden</td><td>A non-administrator user attempted to remove a data source revision, but the caller doesn't have required permissions.</td></tr><tr><td>403</td><td>403053</td><td>Version history not enabled</td><td>version history is not enabled for the specified site.</td></tr><tr><td>403</td><td>403055</td><td>Cannot delete head revision</td><td>The head (first) version cannot be deleted. To remove the data source, call <a href="#delete_data_source">Delete Data Source</a>.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID in the URI doesn't correspond to an existing site.</td></tr><tr><td>404</td><td>404006</td><td>Data source not found</td><td>The data source ID in the URI doesn't correspond to an existing data source.</td></tr><tr><td>404</td><td>404024</td><td>Data source revision not found</td><td>The revision number in the URI doesn't correspond to an existing data source revision.</td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">DELETE</span>.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Update Data in Hyper Connection

Incrementally updates data (insert, update, upsert, replace and delete) in a published data source from a live-to-Hyper connection, where the data source has multiple connections.

A live-to-Hyper connection has a Hyper or Parquet formatted file/database as the origin of its data.

For all connections to Parquet files, and for any data sources with a single connection generally, you can use the [Update Data in Hyper Data Source](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#ref_update_data_in_hyper_data_source) method without specifying the `connection-id`.

A request for this method must include an `upload-session-id` for a Hyper file payload containing an upload of the most current data from the data source for your published live-to-Hyper data. Use [Initiate File Upload](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#initiate_file_upload) and [Append to File Upload](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#append_to_file_upload) methods to form the payload and acquire upload-session-id.

For details and examples, see [Update Data in Published Live-to-Hyper Data Sources](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_how_to_update_data_to_hyper.htm).

**Note:** While Hyper Update REST API methods make incremental changes much more efficient, multiple simultaneous update requests and large changes in large datasets can overwhelm Tableau server background processes. To mitigate this issue, Hyper Update requests are limited by the server configuration setting `api.server.update_uploaded_file.max_size_in_mb`. Starting in Tableau Server 2022.1 / Tableau Cloud March 2022, the default for this setting is 100MB. In previous versions, the limit was set to 10MB. Where heavy incremental update traffic is expected, we recommend you use a chunking strategy to limit the size of each update, and fine tune `max_size_in_mb` value to optimize performance for your exact conditions.

#### URI

PATCH /api/api-version/sites/site-id/datasources/datasource-id/connections/connection-id/data?uploadSessionId=upload-session-id

#### Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-id</span></td><td>The ID of the site that contains the data source.</td></tr><tr><td><span class="api-placeholder">datasource-id</span></td><td>The ID of the data source to update.</td></tr><tr><td><span class="api-placeholder">connection-id</span></td><td>The ID of the connection. To determine what connections are available for a data source, call Query Data Source Connections.</td></tr><tr><td><span class="api-placeholder">upload-session-id</span></td><td>The upload session ID. A user-generated identifier that is unique to a request. If the server receives more than one request with the same ID within 24 hours, all subsequent requests will be treated as duplicates and ignored by the server. This can be used to guarantee idempotency of requests.</td></tr></tbody></table>

#### Request Body

This method supports only JSON content-type for the request body.

```
{"actions": [
	{"action": action-type",
		"source-schema": "source-schema-name",
		"source-table": "source-table-name",
		"target-schema": "target-schema-name",
		"target-table": "target-table-name",
		"condition": {conditional-declaration"}
		. . . more action definition . . .}
	}
	{. . . more actions . . .}
]}
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">actions-type</span></td><td>(Required) The definition of the operation(s) to perform on the data in the target hyper file.</td></tr><tr><td><span class="api-placeholder">source-schema-name</span></td><td>(Optional) The name of the source database schema for the data to be updated. A value is not required unless there are multiple schemas in the database.</td></tr><tr><td><span class="api-placeholder">source-table-name</span></td><td>(Required) The name of the source database table containing the data to be updated.</td></tr><tr><td><span class="api-placeholder">target-schema-name</span></td><td>(Optional) The name of the target hyper file schema of the data to be updated from the source database. A value is not required unless there are multiple schemas in the database.</td></tr><tr><td><span class="api-placeholder">target-table-name</span></td><td>(Required) The name of the table containing the data to be updated in the target hyper file.</td></tr><tr><td><span class="api-placeholder">condition</span></td><td>(Required for <code>insert</code>, <code>upsert</code>, and <code>delete</code>)A declaration that defines a comparison operation between source and target data or between source or target data and a user provided constant. For details and examples, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_how_to_update_data_to_hyper.htm">Update Data in Published Live-to-Hyper Data Sources</a>.</td></tr></tbody></table>

An `action` is an operation to be performed on specified target data. Multiple different actions can be defined as a batch in a request. The supported actions are:

- `insert` - Inserts rows from a named source-table in your data source into a named target-table in your published Hyper. A simplified example is:
    
    ```
    {"action": "insert", "source-table": "added_users", "target-table": "current_users"}
    ```
- `update` – Updates existing tuples from a named `source-table` in your data source into a named `target-table` in your published Hyper. The tuples to be updated are defined in a condition declaration. A simplified example is:
    
    ```
    {"action": "update",
    	"target-table": "my_data",
    	"source-table": "uploaded_table",
    	"condition": {"op": "eq", "target-col": "row_id",
    	"source-col": "update_row_id"}
    }
    ```
- `upsert` - Updates a tuple inside the `target-table`, if such a tuple exists. If no such tuple exists, a new tuple will be inserted. The tuples to be updated are defined in a condition declaration. A simplified example is:
    
    ```
    {"action": "upsert",
    	"target-table": "my_data",
    	"source-table": "uploaded_table",
    	"condition": {"op": "gt", "target-col": "row_id",
    	"source-col": "update_row_id"}
    }
    ```
- `replace` – Deletes all tuples from a `target-table` and inserts all data from a `source-table` with a matching schema. A simplified example is:
    
    ```
    {"action": "replace", "source-table": "added_users",
    "target-table": "current_users"}
    ```
- `delete` – Deletes tuples from a target-table. The tuples to be deleted are defined in a condition declaration. A simplified example is:
    
    ```
    {"action": "delete",
    	"target-table": "my_extract_table",
    	"source-table": "deleted_row_id_table",
    	"condition": {"op": "gt", "target-col": "id",
    	"source-col": "deleted_id"}
    }
    ```

For more information, see [Update Data in Published Live-to-Hyper Data Sources](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_how_to_update_data_to_hyper.htm).

#### Permissions

The user calling this method must be the data source owner and must have the overwrite permission on it.

#### Request Header

In addition to the typical authentication token, the following fields must be specified as part of the request header:

- `content-type: application/json` - This endpoint accepts JSON only.
- `RequestID` - A user-generated identifier that uniquely identifies a request. If the server receives more than one request with the same id within 24 hours, all subsequent requests will be treated as duplicates and ignored by the server. This can be used to guarantee idempotency of requests, which prevents executing the same job more than once could be caused by network anomalies or client crashes.

#### Access Scope

Scope added in API 3.27 (Tableau Cloud December 2025 / Server 2025.3).

```
tableau:hyper_data:update
```

For more information, see [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud) and access scopes for connected apps: [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm), or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### Response Code

200

#### Response Body

The response body returns the job-id, which specifies the ID of the async job that will carry out the data operations described in the action batch. This returned "job-id" can be used to [query the status of the update job](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref_jobs_tasks_and_schedules.htm#query_job) or to [cancel a scheduled job](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref_jobs_tasks_and_schedules.htm#cancel_job).

```
(job-id: "scheduled-job-luid"}
```

#### Version

Version 2o21.2 and later. For more information, see [REST API and Resource Versions](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm).

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td>400000</td><td>Bad request</td><td>The content of the request body is missing or incomplete, or contains malformed JSON.</td></tr><tr><td>400</td><td>400008</td><td>Invalid parameter value</td><td>A parameter in the request body is missing or invalid.</td></tr><tr><td>403</td><td>403062</td><td>Update data source multiple connections forbidden</td><td>A connection ID is required because the data source has multiple connections. Consider using <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#update_data_in_hyper_connection">Update Data in Hyper Connection</a> to specify the connection. <i>(This error does not apply to that Connection method)</i></td></tr><tr><td>403</td><td>403032</td><td>Update forbidden</td><td>A non-administrator user tried to update a data source, but the caller doesn't have <span class="api-command-ref">Write</span> permission.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID in the URI doesn't correspond to an existing site.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The data source LUID in the request body doesn't correspond to an existing data source.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The data source ID in the URI doesn't correspond to an existing data source.</td></tr><tr><td>404</td><td>404008</td><td>Operation not supported</td><td>The operation requested is not supported, the source data for the connection must be a Hyper file/database.</td></tr><tr><td>404</td><td>404020</td><td>Connection not found</td><td>No resource was found for the specified connection and data source. <i>(This error does not apply to Update Data in Hyper Data Source)</i></td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">PATCH</span>.</td></tr><tr><td>409</td><td>409015</td><td>Data source name conflict</td><td>The data source name in the request already belongs to the specified site. For the purpose of uniqueness checks, data source names are case-insensitive.</td></tr><tr><td>409</td><td>409094</td><td>Data update job already exists</td><td>A data update job for the datasource is already queued or in progress.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Update Data in Hyper Data Source

Incrementally updates data (insert, update, upsert, replace and delete) in a published data source from a live-to-Hyper connection, where the data source has a single connection.

A live-to-Hyper connection has a Hyper or Parquet formatted file/database as the origin of its data.

For data sources with multiple connections, you can specify which to update using the [Update Data in Hyper Data Source](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#ref_update_data_in_hyper_data_connection) method.

A request for this method must include an `upload-session-id` for a Hyper file payload containing an upload of the most current data from the data source for your published live-to-Hyper data. Use [Initiate File Upload](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#initiate_file_upload) and [Append to File Upload](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#append_to_file_upload) methods to form the payload and acquire upload-session-id.

For details and examples, see [Update Data in Published Live-to-Hyper Data Sources](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_how_to_update_data_to_hyper.htm).

**Note:** While Hyper Update REST API methods make incremental changes much more efficient, multiple simultaneous update requests and large changes in large datasets can overwhelm Tableau server background processes. To mitigate this issue, Hyper Update requests are limited by the server configuration setting `api.server.update_uploaded_file.max_size_in_mb`. Starting in Tableau Server 2022.1 / Tableau Cloud March 2022, the default for this setting is 100MB. In previous versions, the limit was set to 10MB. Where heavy incremental update traffic is expected, we recommend you use a chunking strategy to limit the size of each update, and fine tune `max_size_in_mb` value to optimize performance for your exact conditions.

**Working with Parquet files**  
\- When publishing a Parquet file to a data source through a live-to-Hyper connection, the files are converted to Hyper files. You may want to publish a copy of your original Parquet file to retain that data in its native format.  
\- A data source with a live-to-Hyper connection to data in a Hyper file converted from Parquet can only have a single connection.  
\- When incrementally updating that data from that connection, using the Update Hyper in Data Source method, the Parquet file is not converted to Hyper.

#### URI

PATCH /api/api-version/sites/site-id/datasources/datasource-id/data?uploadSessionId=upload-session-id

#### Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-id</span></td><td>The ID of the site that contains the data source.</td></tr><tr><td><span class="api-placeholder">datasource-id</span></td><td>The ID of the data source to update.</td></tr><tr><td><span class="api-placeholder">upload-session-id</span></td><td>The upload session ID. A user-generated identifier that is unique to a request. If the server receives more than one request with the same ID within 24 hours, all subsequent requests will be treated as duplicates and ignored by the server. This can be used to guarantee idempotency of requests.</td></tr></tbody></table>

#### Request Body

This method supports only JSON content-type for the request body.

```
{"actions": [
	{"action": action-type",
		"source-schema": "source-schema-name",
		"source-table": "source-table-name",
		"target-schema": "target-schema-name",
		"target-table": "target-table-name",
		"condition": {conditional-declaration"}
		. . . more action definition . . .}
	}
	{. . . more actions . . .}
]}
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">actions-type</span></td><td>(Required) The definition of the operation(s) to perform on the data in the target hyper file.</td></tr><tr><td><span class="api-placeholder">source-schema-name</span></td><td>(Optional) The name of the source database schema for the data to be updated. A value is not required unless there are multiple schemas in the database.</td></tr><tr><td><span class="api-placeholder">source-table-name</span></td><td>(Required) The name of the source database table containing the data to be updated.</td></tr><tr><td><span class="api-placeholder">target-schema-name</span></td><td>(Optional) The name of the target hyper file schema of the data to be updated from the source database. A value is not required unless there are multiple schemas in the database.</td></tr><tr><td><span class="api-placeholder">target-table-name</span></td><td>(Required) The name of the table containing the data to be updated in the target hyper file.</td></tr><tr><td><span class="api-placeholder">condition</span></td><td>(Required for <code>insert</code>, <code>upsert</code>, and <code>delete</code>)A declaration that defines a comparison operation between source and target data or between source or target data and a user provided constant. For details and examples, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_how_to_update_data_to_hyper.htm">Update Data in Published Live-to-Hyper Data Sources</a>.</td></tr></tbody></table>

An `action` is an operation to be performed on specified target data. Multiple different actions can be defined as a batch in a request. The supported actions are:

- `insert` - Inserts rows from a named source-table in your data source into a named target-table in your published Hyper. A simplified example is:
    
    ```
    {"action": "insert", "source-table": "added_users", "target-table": "current_users"}
    ```
- `update` – Updates existing tuples from a named `source-table` in your data source into a named `target-table` in your published Hyper. The tuples to be updated are defined in a condition declaration. A simplified example is:
    
    ```
    {"action": "update",
    	"target-table": "my_data",
    	"source-table": "uploaded_table",
    	"condition": {"op": "eq", "target-col": "row_id",
    	"source-col": "update_row_id"}
    }
    ```
- `upsert` - Updates a tuple inside the `target-table`, if such a tuple exists. If no such tuple exists, a new tuple will be inserted. The tuples to be updated are defined in a condition declaration. A simplified example is:
    
    ```
    {"action": "upsert",
    	"target-table": "my_data",
    	"source-table": "uploaded_table",
    	"condition": {"op": "gt", "target-col": "row_id",
    	"source-col": "update_row_id"}
    }
    ```
- `replace` – Deletes all tuples from a `target-table` and inserts all data from a `source-table` with a matching schema. A simplified example is:
    
    ```
    {"action": "replace", "source-table": "added_users",
    "target-table": "current_users"}
    ```
- `delete` – Deletes tuples from a target-table. The tuples to be deleted are defined in a condition declaration. A simplified example is:
    
    ```
    {"action": "delete",
    	"target-table": "my_extract_table",
    	"source-table": "deleted_row_id_table",
    	"condition": {"op": "gt", "target-col": "id",
    	"source-col": "deleted_id"}
    }
    ```

For more information, see [Update Data in Published Live-to-Hyper Data Sources](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_how_to_update_data_to_hyper.htm).

#### Permissions

The user calling this method must be the data source owner and must have the overwrite permission on it.

#### Request Header

In addition to the typical authentication token, the following fields must be specified as part of the request header:

- `content-type: application/json` - This endpoint accepts JSON only.
- `RequestID` - A user-generated identifier that uniquely identifies a request. If the server receives more than one request with the same id within 24 hours, all subsequent requests will be treated as duplicates and ignored by the server. This can be used to guarantee idempotency of requests, which prevents executing the same job more than once could be caused by network anomalies or client crashes.

#### Access Scope

Scope added in API 3.27 (Tableau Cloud December 2025 / Server 2025.3).

```
tableau:hyper_data:update
```

For more information, see [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud) and access scopes for connected apps: [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm), or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### Response Code

200

#### Response Body

The response body returns the job-id, which specifies the ID of the async job that will carry out the data operations described in the action batch. This returned "job-id" can be used to [query the status of the update job](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref_jobs_tasks_and_schedules.htm#query_job) or to [cancel a scheduled job](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref_jobs_tasks_and_schedules.htm#cancel_job).

```
(job-id: "scheduled-job-luid"}
```

#### Version

Version 2o21.2 and later. For more information, see [REST API and Resource Versions](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm).

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td>400000</td><td>Bad request</td><td>The content of the request body is missing or incomplete, or contains malformed JSON.</td></tr><tr><td>400</td><td>400008</td><td>Invalid parameter value</td><td>A parameter in the request body is missing or invalid.</td></tr><tr><td>403</td><td>403062</td><td>Update data source multiple connections forbidden</td><td>A connection ID is required because the data source has multiple connections. Consider using <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#update_data_in_hyper_connection">Update Data in Hyper Connection</a> to specify the connection. <i>(This error does not apply to that Connection method)</i></td></tr><tr><td>403</td><td>403032</td><td>Update forbidden</td><td>A non-administrator user tried to update a data source, but the caller doesn't have <span class="api-command-ref">Write</span> permission.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID in the URI doesn't correspond to an existing site.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The data source LUID in the request body doesn't correspond to an existing data source.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The data source ID in the URI doesn't correspond to an existing data source.</td></tr><tr><td>404</td><td>404008</td><td>Operation not supported</td><td>The operation requested is not supported, the source data for the connection must be a Hyper file/database.</td></tr><tr><td>404</td><td>404020</td><td>Connection not found</td><td>No resource was found for the specified connection and data source. <i>(This error does not apply to Update Data in Hyper Data Source)</i></td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">PATCH</span>.</td></tr><tr><td>409</td><td>409015</td><td>Data source name conflict</td><td>The data source name in the request already belongs to the specified site. For the purpose of uniqueness checks, data source names are case-insensitive.</td></tr><tr><td>409</td><td>409094</td><td>Data update job already exists</td><td>A data update job for the datasource is already queued or in progress.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Update Data Source

Updates the owner, project or certification status of the specified data source.

**Version**: Available in API 2.0 and later.

**License**: No additional license required.

**Permissions**: You can update data source details if you are a Tableau administrator (Creator). Specific properties can be updated by other users depending on the type of update action and the permissions granted to the user.

- Users who are not server administrators can move a data source from one project to another if they own the data source or the current (source) project, or are a project leader for the current project, and they have Write permission for the destination project.
- Users can change certification status and the certification note if they are server administrators, site administrators, or project leaders for the current project.
- Users can modify the name of the data source if: they have server administrator, site administrator (Creator) or Creator permissions and access to the data source with the overwrite capability.

**Access Scope**: `tableau:datasources:update`

- For more information, see [Versions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm), [Permissions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm), [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud), and access scopes for [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows,](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm) or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### URI

PUT /api/api-version/sites/site-id/datasources/datasource-id

**Note:** Starting in 2021.2, you can also modify (insert, update, upsert, replace, and delete) data in a published data source that is a live-to-Hyper connection. To do this, use the [Update Data in Hyper Data Source](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#update_data_in_hyper_data_source) method, or for data sources with multiple connections, use the [Update Data in Hyper Connection](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref.htm#update_data_in_hyper_connection) method. For more information, see [UpdateData in Published Live-to-Hyper Data Sources](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_how_to_update_data_to_hyper.htm).

#### Path Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-luid</span></td><td>The LUID of the site that contains the data source.</td></tr><tr><td><span class="api-placeholder">datasource-luid</span></td><td>The LUID of the data source to update.</td></tr></tbody></table>

#### Request Body

```
<tsRequest>
  <datasource name="Sales"
    isCertified="true"
    certificationNote="This is a certification note."
    encryptExtracts="false">
      <project id="56c86f04-b834-4a08-a561-86497bb4b2df"/>
      <owner id="20148c74-7818-4eb8-b2a1-9f3f5f582613"/>
      <askData enablement="true [REMOVED IN API 3.12]"/>
  </datasource>
</tsRequest>
```

```
{
  "datasource": {
    "name": "Sales",
    "isCertified": "true",
    "certificationNote": "This is a certification note.",
    "encryptExtracts": "false",
    "project": {
    "id": "56c86f04-b834-4a08-a561-86497bb4b2df"
    },
	"owner": {
      "id": "20148c74-7818-4eb8-b2a1-9f3f5f582613"
	  },
	 "askData": {
	   "enablement": "true [REMOVED IN API 3.12]"
	 }
  }
}
```

#### Request Attributes

<table class="api-parameters-table">
                                <colgroup>
                                    <col class="api-parameters-table-col-1-wide">
                                    <col>
                                </colgroup>
                                <tbody>
                                    <tr>
                                        <td><code>datasource name</code>
                                        </td>
                                        <td>(Optional) The new name of a the data source.
							</td>
                                    </tr>
                                    <tr>
                                        <td><code>project</code>
                                        </td>
                                        <td>(Optional) The LUID of a project to add the data source to.
							</td>
                                    </tr>
                                    <tr>
                                        <td><code>owner</code>
                                        </td>
                                        <td>(Optional) The LUID of a user to assign the data source to as owner.
							</td>
                                    </tr>
                                    <tr>
                                        <td><code>datasource certification-status</code>
                                        </td>
                                        <td>(Optional) A Boolean value that indicates whether the data source is certified. To learn more about data source certification, see <a href="https://help.tableau.com/current/pro/desktop/en-us/datasource_recommended.html">Use Certified and Recommended Data Sources and Tables</a>.
							</td>
                                    </tr>
                                    <tr>
                                        <td><code>datasource certification-note</code>
                                        </td>
                                        <td>(Optional) A note that provides more information on the certification of the data source, if applicable.
							</td>
                                    </tr>
                                    <tr>
                                        <td><code>datasource encryptExtracts</code>
                                        </td>
                                        <td>(Optional) <b>true</b> to encrypt the extracts or <b>false</b> to not encrypt extracts. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_ref_extract_and_encryption.htm" class="xref">Extract and Encryption Methods</a>.</td>
                                    </tr>
                                    <tr>
                                        <td><code>askDataEnablement</code>
                                        </td>
                                        <td>
                                            <p class="note">
									This attribute is removed in API 3.12 and later (Tableau Cloud September 2021 / Server 2021.3).
								</p>
                                            <p>
									(Optional) Determines if a data source allows use of Ask Data. The value can be <code>Enabled</code>, <code>Disabled</code>,
									or <code>SiteDefault</code>.
								</p>
                                            <p>
									If <code>enablement</code> is not specified, Ask Data availability for the data source is unchanged during this update.
									If the <code>askData</code> element is included, it must contain an <code>enablement</code> attribute. Setting the value of
									<code>enablement</code> to <code>SiteDefault</code> for a data source will cause its enablement to follow the site's settings
									for <span class="api-command-ref">Availability of Ask Data</span>. A value of <code>Enabled</code> or <code>Disabled</code> will
									override a site's settings for the data source unless the setting <span class="api-command-ref">Always disable Ask Data</span>
									is selected. In that case, Ask Data will not be available for the data source regardless of the value of <code>enablement</code>.
								</p>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>

Any combination of the attributes inside the <datasource> element is valid. Only the attributes and child elements that are included result in updates to the data source. If no attributes or nested elements are included, no update is made.

If the <project> element is included, the id attribute must be included, and any other attributes of the <project> element are ignored.

If the <owner> element is included, the id attribute must be included, and any other attributes of the owner are ignored.

#### cURL Example

```
curl --location --request GET "https://MY_SERVER/api/3.16/sites/a946d998-2ead-4894-bb50-1054a91dcab3/datasources" \ --header "X-Tableau-Auth: b09KVmT7QxuLVLv1En7iMg"oxKwSGTYT0WKRes5xk3dgI4gIkG3TM8W"a946d998-2ead-4894-bb50-1054a91dcvv8" \ --header "Content-Type: application/xml" \ --data-raw "<tsRequest> <datasource name='Sales'/> </tsRequest>"
```

#### Response Code

200

#### Response Body

```
<tsResponse>
  <datasource name="Sales" id="75b71d2f-e8d3-42af-b654-d953659326ee"
    contentUrl="mySite" type="excel-direct"
    createdAt="2016-02-12T23:36:09Z" updatedAt="2020-12-16T15:33:03Z"
    isCertified="false"
    certificationNote="This is a certification note."
    encryptExtracts="false">
      <project id="56c86f04-b834-4a08-a561-86497bb4b2df" />
      <owner id="20148c74-7818-4eb8-b2a1-9f3f5f582613" />
      <job id="65348c74-7818-4eb8-b2a1-9f3f5f588870" />
      <askData enablement="true [REMOVED IN API 3.12]" />
  </datasource>
</tsResponse>
```

```
{
  "datasource": {
    "name": "Sales",
    "id": "75b71d2f-e8d3-42af-b654-d953659326ee",
    "contentUrl": "mySite",
	"type": "excel-direct",
	"createdAt": "2016-02-12T23:36:09Z",
	"updatedAt": "2020-12-16T15:33:03Z",
	"isCertified": "false",
	"certificationNote": "This is a certification note.",
	"encryptExtracts": "false",
	"project": {
	"id": "56c86f04-b834-4a08-a561-86497bb4b2df"
    },
    "owner": {
      "id": "20148c74-7818-4eb8-b2a1-9f3f5f582613"
    },
    "job": {
      "id": "65348c74-7818-4eb8-b2a1-9f3f5f588870"
    },
    "askData": {
	  "enablement": "true [REMOVED IN API 3.12]"
    }
  }
}
```

The `createdAt` and `updatedAt` attribute values are returned in UTC format (YYYY-MM-DDTHH:MM:SSZ).

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td>400000</td><td>Bad request</td><td>The content of the request body is missing or incomplete, or contains malformed XML.</td></tr><tr><td>400</td><td>400008</td><td>Invalid parameter value</td><td>A user attempted to rename a datasource to a name containing only spaces, or to a name with more 255 characters.</td></tr><tr><td>400</td><td>400129</td><td>Invalid Ask Data enablement</td><td>The requested enablement setting in the request body does not correspond to the site configuration.</td></tr><tr><td>403</td><td>403027</td><td>Owner update forbidden</td><td>A non-administrator user tried to change the owner for the data source.</td></tr><tr><td>403</td><td>403030</td><td>Project update forbidden</td><td>A non-administrator user tried to change the project for the data source, but the caller doesn't have <span class="api-command-ref">Write</span> permission for the project.</td></tr><tr><td>403</td><td>403032</td><td>Update forbidden</td><td>A non-administrator user tried to update a data source, but the caller doesn't have <span class="api-command-ref">Write</span> permission.</td></tr><tr><td>403</td><td>403141</td><td>Update forbidden</td><td>A user attempted to update a data source that they do not have permissions to update.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID in the URI doesn't correspond to an existing site.</td></tr><tr><td>404</td><td>404002</td><td>Owner not found</td><td>The owner ID in the request body doesn't correspond to an existing owner.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The data source ID in the URI doesn't correspond to an existing data source.</td></tr><tr><td>404</td><td>404005</td><td>Project not found</td><td>The project ID in the request body doesn't correspond to an existing project.</td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">PUT</span> or <span class="api-command-ref">PATCH</span>.</td></tr><tr><td>409</td><td>409015</td><td>Data source name conflict</td><td>The data source name in the request already belongs to the specified site. For the purpose of uniqueness checks, data source names are case-insensitive.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Update Data Source Connection

Updates the server address, port, authentication type, username, or password for the specified data source connection.

If the data source contains multiple connections, all the connections are updated. To update specific connections in a data source containing multiple connections, see [Update Data Source Connections](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#update_workbook_connections).

**Version**: Available in API 2.3 and later.

**License**: No additional license required.

**Permissions**: Users who are server administrators or site administrators can change the connection for a data source or enable [query tagging](https://help.tableau.com/current/pro/desktop/en-us/performance_tips.htm). Users who are not server administrators can only update a data source. If they have Write (save) permission for the data source and if they have write permission for the project.

**Access Scope**: `tableau:datasources:update`

- Access scope introduced in API 3.16 (Tableau Cloud June 2022 / Server 2022.3)

For more information, see [Versions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm), [Permissions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm), [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud), and access scopes for [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows,](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm) or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### URI

PUT /api/api-version/sites/site-id/datasources/datasource-id/connections/connection-id

#### Path Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-luid</span></td><td>The LUID of the site that contains the data source.</td></tr><tr><td><span class="api-placeholder">datasource-luid</span></td><td>The LUID of the data source to update.</td></tr><tr><td><span class="api-placeholder">connection-luid</span></td><td>The LUID of the connection to update. To determine what connections are available for a data source, call <a href="#query_data_source_connections">Query Data Source Connections</a>.</td></tr></tbody></table>

#### Request Body

```
<tsRequest>
  <connection
	serverAddress="newAddress"
	serverPort="newPort"
	authenticationType="new Auth Type"
	userName="Jane Doe"
	password="xxxxxx"
	embedPassword="false"
	queryTaggingEnabled="false" />
</tsRequest>
```

```
{
  "connection": {
	"serverAddress": "newAddress",
	"serverPort": "newPort",
	"userName": "Jane Doe",
	"authenticationType": "new Auth Type",
	"password": "xxxxxx",
	"embedPassword": "false",
	"queryTaggingEnabled": "false"
  }
}
```

#### Request Attributes

<table class="api-parameters-table">
                                <colgroup>
                                    <col class="api-parameters-table-col-1-extra-wide">
                                    <col>
                                </colgroup>
                                <tbody>
                                    <tr>
                                        <td><span class="api-placeholder">connection serverAddress</span>
                                        </td>
                                        <td> The new server for the connection.</td>
                                    </tr>
                                    <tr>
                                        <td><span class="api-placeholder">connection serverPort</span>
                                        </td>
                                        <td> The new port for the connection</td>
                                    </tr>
                                    <tr>
                                        <td><span class="api-placeholder">connection authenticationType</span>
                                        </td>
                                        <td>Added in version 3.27.
                                <p>*The new authentication type for the connection.</p><p>Standard values:</p><ul><li><p><code>auth-user-pass</code>:&nbsp;username and password</p></li><li><p><code>oauth</code></p></li><li><p><code>auth-keypair</code>:&nbsp;keypair authentication</p></li></ul><p>Connector-specific values:</p><ul><li><p><code>sqlserver</code>:&nbsp;SQL&nbsp;Server username and password</p></li><li><p><code>Azure AD Password</code></p></li><li><p><code>AD Service Principal</code></p></li><li><p><code>username-password</code>:&nbsp;Several connectors use this value. For example, SAP&nbsp;HANA, SAP Sybase ASE, SAP NetWeaver Business Warehouse (BW), Denodo, and Salesforce.</p></li></ul><p>If you are unsure of the value for authenticationType for the target connection, there are two ways to determine the value. First, if you have a data source or workbook that is currently using the target authentication type, you can query for it using the REST API methods <a href="https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_data_sources.htm#query_data_sources" target="_blank">Query Datasource Connections</a> or <a href="https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#query_workbook_connections" target="_blank">Query Workbook Connections</a>, which returns the authentication type string in the response. </p><p>Alternatively,  you can inspect the <code>&lt;connection&gt;</code> element in the XML of a workbook or data source which is available locally. Look for the value of the <code>authentication</code> attribute of the connection. </p></td>
                                    </tr>
                                    <tr>
                                        <td><span class="api-placeholder">connection userName</span>
                                        </td>
                                        <td>The new username for the connection.</td>
                                    </tr>
                                    <tr>
                                        <td><span class="api-placeholder">connection password</span>
                                        </td>
                                        <td>The new password for the connection.</td>
                                    </tr>
                                    <tr>
                                        <td><span class="api-placeholder">embedPassword</span>
                                        </td>
                                        <td><code>True</code> to embed the password; otherwise, <code>False</code>.</td>
                                    </tr>
                                    <tr>
                                        <td><span class="api-placeholder">queryTaggingEnabled</span>
                                        </td>
                                        <td>
                                            <blockquote><p>[!WARNING]</p><p>Starting with API 3.23 (Tableau Cloud June 2024 / Server 2024.2), the <code>queryTaggingEnabled</code> attribute is deprecated,
									will no longer be supported, and may be retired in future releases.<br><br>Instead, for Tableau Server, use TSM to enable query tagging for all content on a server by
									setting <a href="https://help.tableau.com/current/server/en-us/cli_configuration-set_tsm.htm#native_apiUserInfoInGeneratedSQLEnabled" target="_blank"><code>native_api.UserInfoInGeneratedSQLEnabled</code></a> to <code>true</code>.</p></blockquote>
                                            <p>For API 3.22 (Tableau Cloud February 2024 / Server 2024.1) and earlier: If <code>true</code>, query tagging is enabled. If <code>false</code>, query tagging is disabled. The default is <code>false</code>.</p>
                                            <p>For more information on query tagging, see 	<a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_how_to_query_tagging.htm" target="_blank" class="xref">Understand Workbook Impact on Your Database Using Query Tagging</a>.</p>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>

Any combination of the attributes inside the <connection> element is valid. If no attributes are included, no update is made.

#### cURL Request Example

```
curl --location --request PUT "/api/api-version/sites/site-id/datasources/datasource-id/connections/connection-id" \ --header "Content-Type: application/json" \ --header "X-Tableau-Auth: ZOjZ-2-xRfmShEJLk3LCKQ|KVZTJA7K1YeNuuJwXSKUKSatWRn9Vbpe|11e4e373-9777-44d1-ac04-5363d6e8092e" \ --data "{   'connection': { 	'serverAddress': 'newAddress', 	'serverPort': 'newPort', 	'userName': 'Jane Doe', 'authenticationType': 'new Auth Type',	'password': 'xxxxxx', 	'embedPassword': 'false', 	'queryTaggingEnabled': 'false'   }"
```

#### Response Code

200

#### Response Body

```
<tsResponse>
  <connection id="12ab34cd-56ef-78ab-90cd-12ef34ab56cd"
	serverAddress="database.example.com"
	serverPort="12345"
	authenticationType="new Auth Type"
	userName="jajohnson"
	queryTaggingEnabled="false" />
</tsResponse>
```

```
{
  "connection": {
	"id": "12ab34cd-56ef-78ab-90cd-12ef34ab56cd",
	"serverAddress": "database.example.com",
	"serverPort": "12345",
	"authenticationType": "new Auth Type",
	"userName": "jajohnson",
	"queryTaggingEnabled": "false"
  }
}
```

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td>400000</td><td>Bad request</td><td>The content of the request body is missing or incomplete, or contains malformed XML.</td></tr><tr><td>403</td><td>403023</td><td>Update forbidden</td><td>A non-administrator user tried to update a data source, but the caller doesn't have <span class="api-command-ref">Write</span> permission.</td></tr><tr><td>403</td><td>403027</td><td>Owner update forbidden</td><td>A non-administrator user tried to change connection information, but the caller doesn't have <span class="api-command-ref">Write</span> permission.</td></tr><tr><td>403</td><td>403062</td><td>Unsupported operation</td><td>The data source contains multiple connections, but the URI did not include <code>/connections/<span class="api-placeholder">connection-id</span></code> to indicate which connection should be updated.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID in the URI doesn't correspond to an existing site.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The data source ID in the URI doesn't correspond to an existing data source.</td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">PUT</span>.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Update Data Source Connections

Updates the server address, port, authentication type, username, or password for one or more connections in a data source. To update all connections in a given data source with the same connection information, see [Update Data Source Connection](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_data_sources.htm#update_data_source_connection).

**Version**: Available in API 3.27 and later.

**License**: No additional license required.

**Permissions**: Users who are server administrators or site administrators can change the connection for a data source or enable [query tagging](https://help.tableau.com/current/pro/desktop/en-us/performance_tips.htm). Users who are not server administrators can only update a data source. If they have Write (save) permission for the data source and if they have write permission for the project.

**Access Scope**: `tableau:datasources:update`

- Access scope introduced in API 3.16 (Tableau Cloud June 2022 / Server 2022.3)

For more information, see [Versions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm), [Permissions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm), [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud), and access scopes for [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows,](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm) or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### URI

PUT /api/api-version/sites/site-id/datasources/datasource-id/connections/

#### Path Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-luid</span></td><td>The LUID of the site that contains the data source.</td></tr><tr><td><span class="api-placeholder">datasource-luid</span></td><td>The LUID of the data source to update.</td></tr></tbody></table>

#### Request Body

```
<tsRequest>
  <connectionLuids>
<connectionLuid>Luid1</connectionLuid>
<connectionLuid>Luid2</connectionLuid>
  </connectionLuids>
  <connection
    serverAddress="newAddress"
    serverPort="newPort"
    authenticationType="new Auth Type"
    userName="Jane Doe"
    password="xxxxxx"
    embedPassword="false"
    queryTaggingEnabled="false" />
  </tsRequest>
```

```
{
  "connectionLuids": [
    "Luid1",
    "Luid2"
  ],
  "connection": {
    "serverAddress": "newAddress",
    "serverPort": "newPort",
    "authenticationType": "new Auth Type",
    "userName": "Jane Doe",
    "password": "xxxxxx",
    "embedPassword": "false",
    "queryTaggingEnabled": "false"
  }
}
```

#### Request Attributes

<table class="api-parameters-table">
                                <colgroup>
                                    <col class="api-parameters-table-col-1-extra-wide">
                                    <col>
                                </colgroup>
                                <tbody>
                                    <tr>
                                        <td><span class="api-placeholder">connectionLuids</span>
                                        </td>
                                        <td>An array of connection LUIDs in the data source that you are updating.</td>
                                    </tr>
                                    <tr>
                                        <td><span class="api-placeholder">connection serverAddress</span>
                                        </td>
                                        <td> The new server for the connection.</td>
                                    </tr>
                                    <tr>
                                        <td><span class="api-placeholder">connection serverPort</span>
                                        </td>
                                        <td> The new port for the connection</td>
                                    </tr>
                                    <tr>
                                        <td><span class="api-placeholder">connection authenticationType</span>
                                        </td>
                                        <td>
                                            <p>*The new authentication type for the connection.</p>
                                            <p>Standard values:</p>
                                            <ul>
                                                <li>
                                                    <p><code>auth-user-pass</code>:&nbsp;username and password</p>
                                                </li>
                                                <li>
                                                    <p><code>oauth</code>
                                                    </p>
                                                </li>
                                                <li>
                                                    <p><code>auth-keypair</code>:&nbsp;keypair authentication</p>
                                                </li>
                                            </ul>
                                            <p>Connector-specific values:</p>
                                            <ul>
                                                <li>
                                                    <p><code>sqlserver</code>:&nbsp;SQL&nbsp;Server username and password</p>
                                                </li>
                                                <li>
                                                    <p><code>Azure AD Password</code>
                                                    </p>
                                                </li>
                                                <li>
                                                    <p><code>AD Service Principal</code>
                                                    </p>
                                                </li>
                                                <li>
                                                    <p><code>username-password</code>:&nbsp;Several connectors use this value. For example, SAP&nbsp;HANA, SAP Sybase ASE, SAP NetWeaver Business Warehouse (BW), Denodo, and Salesforce.</p>
                                                </li>
                                            </ul>
                                            <p>If you are unsure of the value for authenticationType for the target connection, there are two ways to determine the value. First, if you have a data source or workbook that is currently using the target authentication type, you can query for it using the REST API methods <a href="https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_data_sources.htm#query_data_sources" target="_blank">Query Datasource Connections</a> or <a href="https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#query_workbook_connections" target="_blank">Query Workbook Connections</a>, which returns the authentication type string in the response. </p>
                                            <p>Alternatively,  you can inspect the <code>&lt;connection&gt;</code> element in the XML of a workbook or data source which is available locally. Look for the value of the <code>authentication</code> attribute of the connection. </p>
                                        </td>
                                    </tr>
                                    <tr>
                                        <td><span class="api-placeholder">connection userName</span>
                                        </td>
                                        <td>The new username for the connection.</td>
                                    </tr>
                                    <tr>
                                        <td><span class="api-placeholder">connection password</span>
                                        </td>
                                        <td>The new password for the connection.</td>
                                    </tr>
                                    <tr>
                                        <td><span class="api-placeholder">embedPassword</span>
                                        </td>
                                        <td><code>True</code> to embed the password; otherwise, <code>False</code>.</td>
                                    </tr>
                                    <tr>
                                        <td><span class="api-placeholder">queryTaggingEnabled</span>
                                        </td>
                                        <td>
                                            <blockquote><p>[!WARNING]</p><p>Starting with API 3.23 (Tableau Cloud June 2024 / Server 2024.2), the <code>queryTaggingEnabled</code> attribute is deprecated,
									will no longer be supported, and may be retired in future releases.<br><br>Instead, for Tableau Server, use TSM to enable query tagging for all content on a server by
								setting <a href="https://help.tableau.com/current/server/en-us/cli_configuration-set_tsm.htm#native_apiUserInfoInGeneratedSQLEnabled" target="_blank"><code>native_api.UserInfoInGeneratedSQLEnabled</code></a> to <code>true</code>.</p></blockquote>
                                            <p>For API 3.22 (Tableau Cloud February 2024 / Server 2024.1) and earlier: If <code>true</code>, query tagging is enabled. If <code>false</code>, query tagging is disabled. The default is <code>false</code>.</p>
                                            <p>For more information on query tagging, see 	<a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_how_to_query_tagging.htm" target="_blank" class="xref">Understand Workbook Impact on Your Database Using Query Tagging</a>.</p>
                                        </td>
                                    </tr>
                                </tbody>
                            </table>

Any combination of the attributes inside the <connection> element is valid. If no attributes are included, no update is made.

#### cURL Request Example

```
curl --location --request PUT "/api/api-version/sites/site-id/datasources/datasource-id/connections/" \ --header "Content-Type: application/xml" \ --header "X-Tableau-Auth;" \ --data "{   'connectionLuids': [     'Luid1',     'Luid2'   ],   'connection': {     'serverAddress': 'newAddress',     'serverPort': 'newPort',     'authenticationType': 'new Auth Type',     'userName': 'Jane Doe',     'password': 'xxxxxx',     'embedPassword': 'false',     'queryTaggingEnabled': 'false'   } }"
```

#### Response Code

200

#### Response Body

```
<tsResponse>
  <connection id="12ab34cd-56ef-78ab-90cd-12ef34ab56cd"
	serverAddress="database.example.com"
	serverPort="12345"
	authenticationType="new Auth Type"
	userName="jajohnson"
	queryTaggingEnabled="false" />
</tsResponse>
```

```
{
  "connection": {
	"id": "12ab34cd-56ef-78ab-90cd-12ef34ab56cd",
	"serverAddress": "database.example.com",
	"serverPort": "12345",
	"authenticationType": "new Auth Type",
	"userName": "jajohnson",
	"queryTaggingEnabled": "false"
  }
}
```

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td>400000</td><td>Bad request</td><td>The content of the request body is missing or incomplete, or contains malformed XML.</td></tr><tr><td>403</td><td>403023</td><td>Update forbidden</td><td>A non-administrator user tried to update a data source, but the caller doesn't have <span class="api-command-ref">Write</span> permission.</td></tr><tr><td>403</td><td>403027</td><td>Owner update forbidden</td><td>A non-administrator user tried to change connection information, but the caller doesn't have <span class="api-command-ref">Write</span> permission.</td></tr><tr><td>403</td><td>403062</td><td>Unsupported operation</td><td>The data source contains multiple connections, but the URI did not include <code>/connections/<span class="api-placeholder">connection-id</span></code> to indicate which connection should be updated.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID in the URI doesn't correspond to an existing site.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The data source ID in the URI doesn't correspond to an existing data source.</td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">PUT</span>.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Update Data Source Now

Runs an extract refresh on the specified data source.

**Note:** This method will fail and result in an error if your Server Administrator has disabled the **RunNow** setting for the site. For more information, see [Tableau Server Settings](https://help.tableau.com/current/server/en-us/maintenance_set.htm).

**Version**: Available in API 2.8 and later.

**License**: No additional license required.

**Permissions**: Users who are not server administrators or site administrators can only refresh extracts for data sources if they own the data source, or if they are the project leader for the project.

**Access Scope**: `tableau:tasks:run`

- For more information, see [Versions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm), [Permissions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm), [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud), and access scopes for [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows,](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm) or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

This method runs an extract refresh for the specified data source, with no need to associate that extract refresh with a scheduled task. This method is the equivalent of selecting a data source using the Tableau Server UI, and then selecting **Refresh Extracts** from the menu (also known as a "manual refresh"), however, the REST method always runs a full refresh even if the refresh type is set to incremental. Similar to a manual refresh, if the extract is a `.tde` file, it will be converted to a `.hyper` file as a result of the refresh. To learn more about extract upgrades to the `.hyper` file format, see [Extract Upgrade to .hyper Format](https://help.tableau.com/current/server/en-us/extracting_upgrade.htm).

#### URI

POST /api/api-version/sites/site-id/datasources/datasource-id/refresh

#### Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-id</span></td><td>The ID of the site that contains the data source.</td></tr><tr><td><span class="api-placeholder">datasource-id</span></td><td>The ID of the data source to refresh.</td></tr></tbody></table>

#### Request Body

As of version 3.28, you can specify an incremental refresh on extracts by updating the request body as follows:

```
<tsRequest>
 <extractRefresh incremental="true">
 </extractRefresh>
</tsRequest>
```

{
 "extractRefresh": {
   "@incremental": "true"
 }
}

#### Response Code

202

#### Response Body

```
<tsResponse>
  <job id="job-id" mode="Asynchronous" type="RefreshExtract" createdAt="date-time">
    <extractRefreshJob>
      <datasource id="datasource-id" name="datasource-name" incremental="true" />
    </extractRefreshJob>
</tsResponse>
```

```
{
  "job": {
    "id": "job-id",
    "mode": "Asynchronous",
    "type": "RefreshExtract",
    "createdAt": "date-time",
    "extractRefreshJob": {
      "datasource": {
        "id": "datasource-id",
        "name": "datasource-name",
		"incremental"="true"
      }
    }
  }
}
```

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td>400000</td><td>Bad Request</td><td>The content of the request body is missing or incomplete, or contains malformed XML.</td></tr><tr><td>401</td><td>401000</td><td>Unauthorized Access</td><td>The authentication token provided in the request header was invalid or has expired.</td></tr><tr><td>403</td><td>403032</td><td>Update Forbidden</td><td>A non-administrator user attempted to update a data source, but the caller doesn't have sufficient permissions.</td></tr><tr><td>404</td><td>404000</td><td>Site not found</td><td>The site ID in the URI is unknown.</td></tr><tr><td>404</td><td>404004</td><td>Data source not found</td><td>The data source ID in the URI is unknown.</td></tr><tr><td>405</td><td>405000</td><td>Invalid request method</td><td>Request type was not <span class="api-command-ref">POST</span>.</td></tr><tr><td>409</td><td>409093</td><td>Operation already in Queue</td><td>The extract refresh job is already in the queue.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

#### cURL Example

```
curl "http://MY-SERVER/api/3.29/sites/1edc53ac-e247-4870-9fd3-6fad0ce5f84d/datasources/89a82d78-664f-45a1-8256-d4d2961a070b/refresh" -X POST -H "X-Tableau-Auth:12ab34cd56ef78ab90cd12ef34ab56cd" –d @empty-tsrequest.xml"
```

**Content of empty-tsrequest.xml:**

```
<tsRequest>
</tsRequest>
```

**Example response:**

```
<tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-2.8.xsd">
  <job id="20cf4ddc-6d73-4733-89ec-8d336669bd56" mode="Asynchronous" type="RefreshExtract" createdAt="2017-12-06T22:58:52Z">
    <extractRefreshJob>
      <datasource id="89a82d78-664f-45a1-8256-d4d2961a070b" name="World Indicators Extract" />
    </extractRefreshJob>
  </job>
</tsResponse>
```

## Update Work Copy Elements

Updates columns, field descriptions, or table descriptions on a work copy. Returns HTTP 200 when every element is updated. The success body omits the elements that succeeded.

A column update may set at most one of `caption`, `type`, or `role`. An unknown `type` or `role` is HTTP 400 with error code `400008`. Setting more than one of those fields is HTTP 400 with no numeric sub-code. If any element fails, the HTTP status is the status of the first failure and the body lists only the failed elements.

**Version**: Available in API 3.30 (Tableau Cloud October 2026 / Server 2026.3) and later.

**License**: Data Management or Tableau+.

**Permissions**: Users who are not server administrators or site administrators can call this method only if they have Connect, Write (save), and VizqlDataApiAccess (API Access) permissions for the data source that the work copy was created from (either explicitly or implicitly).

**Access Scope**: `tableau:datasources:update`

For more information, see [Versions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm), [Permissions](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm), [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud), and access scopes for [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows,](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm) or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### URI

PUT /api/api-version/tds/sites/site-luid/workcopy/workcopy-luid

#### URI Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use. These TDS Edit methods are available in API 3.30 and later. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-luid</span></td><td>The LUID of the site in the URI. This handler does not bind the path variable — the service uses the authenticated user's site LUID (<code>authUser.getSiteLuid()</code>).</td></tr><tr><td><span class="api-placeholder">workcopy-luid</span></td><td>The LUID of the work copy. Must be a UUID (8-4-4-4-12 hexadecimal digits), matching <code>[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}</code>.</td></tr></tbody></table>

#### Request Body

```
<tsRequest>
  <tdsElementList>
    <elementType>Column</elementType>
    <name>Sales</name>
    <column>
      <caption>Total Sales</caption>
    </column>
  </tdsElementList>
  <tdsElementList>
    <elementType>FieldDescription</elementType>
    <name>Sales</name>
    <description>Total sales amount, revised.</description>
  </tdsElementList>
</tsRequest>
```

```
{
  "tdsElementList": [
    {
      "elementType": "Column",
      "name": "Sales",
      "column": {
        "caption": "Total Sales"
      }
    },
    {
      "elementType": "FieldDescription",
      "name": "Sales",
      "description": "Total sales amount, revised."
    }
  ]
}
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1"> <col></colgroup><tbody><tr><td><span class="api-placeholder">tdsElementList[]</span></td><td>Required. Elements to update. Must contain at least one element. An empty or missing list is HTTP 400 with error code <code>400008</code>.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].elementType</span></td><td>Optional. Element type sent to the TDS service. For this operation, use <code>Column</code>, <code>FieldDescription</code>, or <code>TableDescription</code>. Any other value is forwarded and reported as a per-element failure.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].name</span></td><td>Required. Element name.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column</span></td><td>Used when <code>elementType</code> is <code>Column</code>. At most one of <code>caption</code>, <code>type</code>, and <code>role</code> may be set — setting more than one is HTTP 400 with no numeric sub-code. A column with none of them set is a no-op update.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column.caption</span></td><td>Optional. The caption to set.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column.role</span></td><td>Optional. An accepted <code>FieldRole</code> constant other than <code>FIELD_ROLE_UNKNOWN</code> or <code>UNRECOGNIZED</code> — either of those is rejected as HTTP 400 with error code <code>400008</code>.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].column.type</span></td><td>Optional. An accepted <code>FieldType</code> constant other than <code>FIELD_TYPE_UNKNOWN</code> or <code>UNRECOGNIZED</code> — either of those is rejected as HTTP 400 with error code <code>400008</code>.</td></tr><tr><td><span class="api-placeholder">tdsElementList[].description</span></td><td>Used when <code>elementType</code> is <code>FieldDescription</code> or <code>TableDescription</code>. Description text to set. When <code>description</code> is null, the field is left unset so the TDS service can report a per-element failure instead of HTTP 500.</td></tr></tbody></table>

#### Response Code

200 OK

#### Response Body

On full success the response is an empty `tsResponse` — `tdsElementResult` is omitted entirely rather than returned as an empty list. When one or more elements fail, the HTTP status is the status of the first failure and the body carries `tdsElementResult` for the failed elements only; see the Attribute Values table below and the Errors table for the failure shape.

```
<tsResponse/>
```

```
{}
```

#### Attribute Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1"> <col></colgroup><tbody><tr><td><span class="api-placeholder">tdsElementResult[]</span></td><td>Failed elements only. Omitted on full success, including omitted rather than returned as an empty array.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].elementType</span></td><td>Required. Element type of the failed element, copied from the request.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].name</span></td><td>Required. Name of the failed element, copied from the request.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].status</span></td><td>Required. Failure status for this element.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].status.code</span></td><td>Required (within <code>status</code>). The translated HTTP status for this element (200, 400, 401, 403, 404, 409, 500, or 503). Not a Tableau 6-digit error sub-code.</td></tr><tr><td><span class="api-placeholder">tdsElementResult[].status.message</span></td><td>Optional. Error message from the TDS service.</td></tr></tbody></table>

#### Errors

<table class="api-error-table"><colgroup><col class="api-error-table-col-1"> <col class="api-error-table-col-2"> <col class="api-error-table-col-3"> <col></colgroup><tbody><tr><th>HTTP status</th><th><code>error</code> Code</th><th>Condition</th><th>Details</th></tr><tr><td>400</td><td>400008</td><td>Missing tdsElementList</td><td><code>tdsElementList</code> is missing or empty. The list is required and must contain at least one element.</td></tr><tr><td>400</td><td>400008</td><td>Invalid column type or role</td><td><code>type</code> or <code>role</code> is not an accepted field type or role. <code>FIELD_TYPE_UNKNOWN</code>, <code>FIELD_ROLE_UNKNOWN</code>, and <code>UNRECOGNIZED</code> are rejected. The accepted names are not in the staged sources.</td></tr><tr><td>400</td><td></td><td>Column update sets more than one field</td><td>A column update may set at most one of <code>caption</code>, <code>type</code>, or <code>role</code>.</td></tr><tr><td>400</td><td></td><td>Invalid work copy LUID</td><td>The work copy LUID in the URI is not a UUID (8-4-4-4-12 hexadecimal digits).</td></tr><tr><td>400</td><td></td><td>Per-element invalid argument</td><td>One or more elements were rejected as invalid. The body lists only the failed elements, and each <code>status.code</code> is the HTTP status 400.</td></tr><tr><td>400</td><td></td><td>Unmapped per-element gRPC status</td><td>The TDS service returned a status that maps to HTTP 400. The body lists only the failed elements.</td></tr><tr><td>401</td><td>401000 / 401002</td><td>Missing or invalid authentication</td><td>No authentication token provided, or token is expired or invalid.</td></tr><tr><td>401</td><td></td><td>Per-element unauthenticated</td><td>The TDS service rejected an element as unauthenticated. The body lists only the failed elements.</td></tr><tr><td>403</td><td>403004</td><td>Data Management Bundle not licensed</td><td>On Tableau Server the TDS Edit API requires a Data Management Bundle license. The call is rejected when that license is absent.</td></tr><tr><td>403</td><td>403004</td><td>Unable to resolve tenant</td><td>On Tableau Cloud the subscription could not be checked because the tenant id for the site could not be retrieved.</td></tr><tr><td>403</td><td>403004</td><td>No cloud entitlements</td><td>On Tableau Cloud no entitlements were found for the tenant. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>403</td><td>403004</td><td>Subscription not entitled</td><td>On Tableau Cloud the site edition is not Tableau+. The TDS Edit API requires a Tableau+ subscription.</td></tr><tr><td>403</td><td></td><td>Per-element permission denied</td><td>The TDS service rejected an element because permission was denied. The body lists only the failed elements.</td></tr><tr><td>404</td><td></td><td>Per-element not found</td><td>One or more elements were not found. The body lists only the failed elements. This is not error code 404065, which the read methods return for a missing named element.</td></tr><tr><td>405</td><td>405000</td><td>Method not allowed</td><td>The HTTP method is not supported for this resource.</td></tr><tr><td>409</td><td></td><td>Per-element already exists</td><td>One or more elements already exist. The body lists only the failed elements.</td></tr><tr><td>429</td><td>429000</td><td>Rate limit exceeded</td><td>Too many requests sent in a given time period.</td></tr><tr><td>500</td><td></td><td>Per-element internal error</td><td>The TDS service failed while editing an element. The body lists only the failed elements.</td></tr><tr><td>503</td><td></td><td>Per-element unavailable</td><td>The TDS service was unavailable while editing an element. The body lists only the failed elements.</td></tr></tbody></table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).

## Upload Data Source Encrypted Keychain

Uploads the encrypted version of the embedded credentials. This method will only work if the credentials are encrypted with the latest public key used to link the source Tableau Server with the destination Tableau Cloud or Tableau Server site.

Before you use this method, you must create public and private keys for resources with embedded credentials. For more information, see [Migrate Workbooks and Data Sources with Embedded Credentials](https://help.tableau.com/current/server/en-us/cmt-migration_embedded_credentials.htm).

**Version:** Available in API 3.23 (Tableau Cloud June 2024/ Tableau Server 2024.2) and later. _[Version Overview](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_versions.htm)_

**License:** No additional license required.

**Permissions:** This method can only be called by Tableau Cloud and Tableau Server admins.   _[Permissions Overview](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_permissions.htm)_

**JWT Access Scope:** tableau:embedded\_credentials:upload

- Scope added in API 3.27 (Tableau Cloud December 2025 / Server 2025.3).
- For more information, see [Access scopes for UATs](https://help.tableau.com/current/api/cloud-manager/en-us/docs/unified_access_tokens.html#scopes) (Cloud) and access scopes for connected apps: [Cloud](https://help.tableau.com/current/online/en-us/connected_apps_scopes.htm), [Server-Windows](https://help.tableau.com/current/server/en-us/connected_apps_scopes.htm), or [Server-Linux](https://help.tableau.com/current/server-linux/en-us/connected_apps_scopes.htm).

#### URI

PUT /api/api-version/sites/site-luid/datasources/datasource-luid/applykeychain

#### URI Parameter Values

<table class="api-parameters-table"><colgroup><col class="api-parameters-table-col-1-wide"> <col></colgroup><tbody><tr><td><span class="api-placeholder">api-version</span></td><td>The version of the API to use, such as <code><span class="mc-variable Variables.REST-API-Version variable">3.29</span></code>. For more information, see <a href="https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_versions.htm" class="xref">REST API and Resource Versions</a>.</td></tr><tr><td><span class="api-placeholder">site-luid</span></td><td>The LUID for the site.</td></tr><tr><td><span class="api-placeholder">datasource-luid</span></td><td>The LUID of the data source to download the encrypted keychain from.</td></tr></tbody></table>

#### Request Body

```

<tsRequest>
  <associatedUserLuidMapping/>
  <encryptedKeychainList>
    <encryptedKeychain>BADsJ5lBKho2Tdqqbo7txS8IyGlBu9LiRyb8etCHJLhBUurgIRHk3g5AeMQg6KHBw+6nwNIDEd65MKi76DLd5aIMhQC5aLCR4NE7R2gp7JbxLo+nOMGnfDQm5XekJVpLQGfY53GIX52ED2iTfOQ0yRNbnPV4djT0z23rosG0gpmqXV/GlBu9LiRyb8wx8RisnZdvv+SAlv222jVhksX1w5A6HB3Bs45BeWfpwrOnHwnNoWUGwHuu4iGlyE7m65RlATZN+fvDGOFN1zU2lXaSZyWqRKiWkD+oGlBu9LiRyb8Gz7RnesKvH6QEL9sT8cXA1ZOEA531xNAv9rjazEP5BssIdA1GcJ5J7zar5xxC68qm3cz3MkndyqWXZrf0vWPgwysUHEpWn60oDG/8/xG6c0Eigh4gwE+dA+NF1GlBu9LiRyb8+AzJ7vatf95LDwAuRT43G3Q+WApx9qBPXco15pKjwy00rHPgn4cRtu+unwh6d3gIh6AbK6X++U/vV/Ktpe31lSZmV8eHPeTNfdCrGOT9ozZhF5oKGlBu9LiRyb8tf1YcXawh3bvtZxg9d8a2mKNXDeaF+uJrpI43aFa4KrJKdfvDpq2k0aJhL1QNxWSFBYw0tPJX/rhKAeOHHY2K44Wh5JNWwL+x1uYap93IK303sJ1GlBu9LiRyb8UhfIW7o5iUtbYWrpCvVwubZLf4U5Y=</encryptedKeychain>
  </encryptedKeychainList>
</tsRequest>
```

```
{
"associatedUserLuidMapping": [],
"encryptedKeychainList": {
  "encryptedKeychain": "BADsJ5lBKho2Tdqqbo7txS8IyGlBu9LiRyb8etCHJLhBUurgIRHk3g5AeMQg6KHBw+6nwNIDEd65MKi76DLd5aIMhQC5aLCR4NE7R2gp7JbxLo+nOMGnfDQm5XekJVpLQGfY53GIX52ED2iTfOQ0yRNbnPV4djT0z23rosG0gpmqXV/GlBu9LiRyb8wx8RisnZdvv+SAlv222jVhksX1w5A6HB3Bs45BeWfpwrOnHwnNoWUGwHuu4iGlyE7m65RlATZN+fvDGOFN1zU2lXaSZyWqRKiWkD+oGlBu9LiRyb8Gz7RnesKvH6QEL9sT8cXA1ZOEA531xNAv9rjazEP5BssIdA1GcJ5J7zar5xxC68qm3cz3MkndyqWXZrf0vWPgwysUHEpWn60oDG/8/xG6c0Eigh4gwE+dA+NF1GlBu9LiRyb8+AzJ7vatf95LDwAuRT43G3Q+WApx9qBPXco15pKjwy00rHPgn4cRtu+unwh6d3gIh6AbK6X++U/vV/Ktpe31lSZmV8eHPeTNfdCrGOT9ozZhF5oKGlBu9LiRyb8tf1YcXawh3bvtZxg9d8a2mKNXDeaF+uJrpI43aFa4KrJKdfvDpq2k0aJhL1QNxWSFBYw0tPJX/rhKAeOHHY2K44Wh5JNWwL+x1uYap93IK303sJ1GlBu9LiRyb8UhfIW7o5iUtbYWrpCvVwubZLf4U5Y="
 }
}
```

#### Request Attributes

<table class="api-parameters-table">
                            <colgroup>
                                <col class="api-parameters-table-col-1">
                                <col>
                            </colgroup>
                            <tbody>
                                <tr>
                                    <td><code>associatedUserLuidMapping</code>
                                    </td>
                                    <td>
                                        <p>
								(Required) The user IDs from the source site mapped to destination site user IDs.</p>
                                    </td>
                                </tr>
                                <tr>
                                    <td><code>encryptedKeychainList</code>
                                    </td>
                                    <td>(Required) List of encrypted keychains from the source Tableau Server.</td>
                                </tr>
                                <tr>
                                    <td><code>encryptedKeychain</code>
                                    </td>
                                    <td>
                                        <p>(Required) Encrypted keychain from the source Tableau Server.</p>
                                    </td>
                                </tr>
                            </tbody>
                        </table>

#### cURL Request Example

```
curl --location "https://example.org/api/3.24/sites/7a2f773d-4a9f-496e-afc6-a60517cb1b86/datasources/1a2a3b4b-5c6c-7d8d-9e0e-1f2f3a4a5b6b/applykeychain" -X PUT --header "Content-Type: application/xml"  --header "X-Tableau-Auth: nbQAstTxTHuBlcMlXZ3QKg|LXn5aiYcffck999kgpOPrQft5JkvRsYg|7a2f773d-4a9f-496e-afc6-a60517cb1b86"  --data "&lt;tsRequest&gt;   &lt;destinationSiteUrlNamespace&gt;site1&lt;/destinationSiteUrlNamespace&gt;    &lt;destinationSiteLuid&gt;9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d&lt;/destinationSiteLuid&gt;   &lt;destinationServerUrl&gt;http://example.com&lt;/destinationServerUrl&gt;  &lt;/tsRequest&gt;"
```

#### Response Code

200

#### Response Body

None

#### Errors

<table class="api-error-table">
                        <colgroup>
                            <col class="api-error-table-col-1">
                            <col class="api-error-table-col-2">
                            <col class="api-error-table-col-3">
                            <col>
                        </colgroup>
                        <tbody>
                            <tr>
                                <th>HTTP status</th>
                                <th><code>error</code> Code</th>
                                <th>Condition</th>
                                <th>Details</th>
                            </tr>
                            <tr>
                                <td>400</td>
                                <td>400000</td>
                                <td>Bad Request</td>
                                <td>The content of the request body is missing or incomplete, or contains malformed XML.</td>
                            </tr>
                            <tr>
                                <td>401</td>
                                <td>401002</td>
                                <td>Unauthorized Access</td>
                                <td>
                                    <p>The authentication token provided in the request header was invalid or has expired.</p>
                                </td>
                            </tr>
                            <tr>
                                <td>403</td>
                                <td>403054</td>
                                <td>Unauthorized Access</td>
                                <td>A non-administrator user attempted to get data source revision information, but the caller doesn't have sufficient permissions.</td>
                            </tr>
                            <tr>
                                <td>404</td>
                                <td>404000</td>
                                <td>Site not found</td>
                                <td>The site ID in the URI doesn't correspond to an existing site.</td>
                            </tr>
                            <tr>
                                <td>404</td>
                                <td>404004
                    </td>
                                <td>Data source not found</td>
                                <td>The data source ID in the URI doesn't correspond to an existing data source.</td>
                            </tr>
                            <tr>
                                <td>405</td>
                                <td>405000</td>
                                <td>Invalid request method</td>
                                <td>Request type was not <span class="api-command-ref">PUT</span>.</td>
                            </tr>
                        </tbody>
                    </table>

For more information, see [Handling Errors](https://help.tableau.com/v0.0/api/rest_api/en-us/REST/rest_api_concepts_errors.htm).