> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bijection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tableau

> Resources, examples, configuration and evidence for Tableau.

Use the `@bijection/connectors/tableau` entrypoint to declare Tableau resources.

## Availability

This page describes the pinned source package. Published availability is unestablished for this artifact. [Source build and package availability](https://docs.bijection.com/client/sdk-distribution.md).

## Resources and modes

| Resource | Mode | Description |
| - | - | - |
| Published data sources | `pull` | Published data sources and their upstream tables |
| Workbooks | `pull` | Workbooks, their sheets and upstream data sources |

Declare a resource in application code, then bind deployment-specific settings and credentials. See [typed resources](https://docs.bijection.com/integrations/resources.md), [connections](https://docs.bijection.com/integrations/connections.md) and [source inspection](https://docs.bijection.com/integrations/cli.md).

## Published data sources

### pull: Published data sources and their upstream tables

The following example matches configuration `standard`.

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { tableau } from "@bijection/connectors/tableau";
export const datasources = tableau.datasources.pull();
```

> **Inferred record types**
>
> ```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "createdAt": string | null;
>   "extractLastRefreshTime": string | null;
>   "hasExtracts": boolean | null;
>   "id": string;
>   "luid": string;
>   "name": string | null;
>   "projectName": string | null;
>   "updatedAt": string | null;
>   "upstreamTables": { id: string; fullName: string | null; name: string | null; schema: string | null; luid: string; connectionType: string | null; }[];
> }
> ```

#### Configuration: standard

Case: `tableau/datasources/pull/standard`.

Connection and resource configuration are declared by this exact case.

Credential kind: `tableau`. Keep credential material in the private credential inventory.

| Setting | Type | Required | Owner |
| - | - | - | - |
| `baseUrl` | string | Yes | Shared connection |

> **Complete configuration contract**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "setup": [],
>   "resource": {
>     "access": {},
>     "defaults": {},
>     "connector": "tableau",
>     "output": {
>       "kind": "single",
>       "collection": "records"
>     },
>     "credential_kind": "tableau",
>     "connection_fields": [
>       "baseUrl"
>     ],
>     "address": {
>       "kind": "setup",
>       "field": "baseUrl"
>     }
>   },
>   "connection_setup": {
>     "type": "object",
>     "value": {
>       "baseUrl": {
>         "fieldType": {
>           "type": "string"
>         },
>         "optional": false
>       }
>     }
>   },
>   "execution": null
> }
> ```

Native admission analysis is available for this exact declaration.

**Collection: records**

| Contract | Meaning |
| - | - |
| Initial | Enumeration of observed records |
| Changes | Repeated observations of current records |
| Deletions | Deletion detection unsupported |
| Resume | Opaque cursor |
| Gap | Explicit repair required after a gap |
| Retention | Unspecified |

> **Complete native profile**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "movement": {
>     "exchanges": {
>       "records": {
>         "200": {
>           "placement": "retained_bytes",
>           "interpretation": "json",
>           "projectsBeforeRetention": false,
>           "retainedBodyLimitBytes": "524288",
>           "fileLimitBytes": null
>         }
>       }
>     },
>     "nativeInputLimitBytes": null,
>     "steps": [
>       {
>         "id": "acquire.1",
>         "inputs": [],
>         "action": {
>           "operation": "acquire",
>           "subject": "exchange records",
>           "limitBytes": null
>         }
>       },
>       {
>         "id": "retain.1",
>         "inputs": [
>           "acquire.1"
>         ],
>         "action": {
>           "operation": "retain",
>           "subject": "acquisition evidence",
>           "reason": "recovery",
>           "release": "acquisition_custody"
>         }
>       },
>       {
>         "id": "interpret.1",
>         "inputs": [
>           "retain.1"
>         ],
>         "action": {
>           "operation": "interpret",
>           "subject": "acquired input",
>           "produces": "records"
>         }
>       },
>       {
>         "id": "materialize.1",
>         "inputs": [
>           "interpret.1"
>         ],
>         "action": {
>           "operation": "materialize",
>           "subject": "source rows",
>           "reason": "serving",
>           "release": "replacement"
>         }
>       },
>       {
>         "id": "publish.1",
>         "inputs": [
>           "materialize.1"
>         ],
>         "action": {
>           "operation": "publish",
>           "subject": "source rows",
>           "visibility": "with_acquisition"
>         }
>       }
>     ]
>   },
>   "initial": "enumeration",
>   "changes": "observations",
>   "deletions": "unsupported",
>   "resume": "opaque_cursor",
>   "retentionMs": null,
>   "gap": "explicit_repair",
>   "limits": {
>     "http_response_bytes": "524288"
>   },
>   "restrictions": [],
>   "commands": {}
> }
> ```

> **Commands, occurrences and artifacts**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "records": {
>     "records": {
>       "protocol": "record_observation",
>       "coverage": "records",
>       "consistency": "observations",
>       "atomicity": "record",
>       "history": "observations",
>       "recordRefresh": false,
>       "reconciliation": false,
>       "notifications": false,
>       "snapshotMaxRows": null,
>       "profile": {
>         "movement": {
>           "exchanges": {
>             "records": {
>               "200": {
>                 "placement": "retained_bytes",
>                 "interpretation": "json",
>                 "projectsBeforeRetention": false,
>                 "retainedBodyLimitBytes": "524288",
>                 "fileLimitBytes": null
>               }
>             }
>           },
>           "nativeInputLimitBytes": null,
>           "steps": [
>             {
>               "id": "acquire.1",
>               "inputs": [],
>               "action": {
>                 "operation": "acquire",
>                 "subject": "exchange records",
>                 "limitBytes": null
>               }
>             },
>             {
>               "id": "retain.1",
>               "inputs": [
>                 "acquire.1"
>               ],
>               "action": {
>                 "operation": "retain",
>                 "subject": "acquisition evidence",
>                 "reason": "recovery",
>                 "release": "acquisition_custody"
>               }
>             },
>             {
>               "id": "interpret.1",
>               "inputs": [
>                 "retain.1"
>               ],
>               "action": {
>                 "operation": "interpret",
>                 "subject": "acquired input",
>                 "produces": "records"
>               }
>             },
>             {
>               "id": "materialize.1",
>               "inputs": [
>                 "interpret.1"
>               ],
>               "action": {
>                 "operation": "materialize",
>                 "subject": "source rows",
>                 "reason": "serving",
>                 "release": "replacement"
>               }
>             },
>             {
>               "id": "publish.1",
>               "inputs": [
>                 "materialize.1"
>               ],
>               "action": {
>                 "operation": "publish",
>                 "subject": "source rows",
>                 "visibility": "with_acquisition"
>               }
>             }
>           ]
>         },
>         "initial": "enumeration",
>         "changes": "observations",
>         "deletions": "unsupported",
>         "resume": "opaque_cursor",
>         "retentionMs": null,
>         "gap": "explicit_repair",
>         "limits": {
>           "http_response_bytes": "524288"
>         },
>         "restrictions": [],
>         "commands": {}
>       }
>     }
>   },
>   "occurrences": null,
>   "artifacts": {
>     "raw_archive": false,
>     "native_file_transfer_limit_bytes": null,
>     "external_versions": false,
>     "files": {}
>   },
>   "commands": {}
> }
> ```

**Recorded checks**

| Requirement | Scope | Evidence | Result |
| - | - | - | - |
| page-publication-recovery | \{"kind":"collection","name":"records"} | No check exercises this packaged Tableau declaration against Tableau; it is declared from documentation and has not run or been qualified. | Execution result unavailable |
| stated-cursor-empty-page-advances | \{"kind":"collection","name":"records"} | No check exercises this packaged Tableau declaration against Tableau; it is declared from documentation and has not run or been qualified. | Execution result unavailable |
| stated-cursor-repeat-refused | \{"kind":"collection","name":"records"} | No check exercises this packaged Tableau declaration against Tableau; it is declared from documentation and has not run or been qualified. | Execution result unavailable |
| identity-account | \{"kind":"connection"} | No check exercises this packaged Tableau declaration against Tableau; it is declared from documentation and has not run or been qualified. | Execution result unavailable |

Hosted qualification: **unestablished for this catalog configuration**. Installed connections report their own identity, authority and current status.

## Workbooks

### pull: Workbooks, their sheets and upstream data sources

The following example matches configuration `standard`.

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { tableau } from "@bijection/connectors/tableau";
export const workbooks = tableau.workbooks.pull();
```

> **Inferred record types**
>
> ```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "createdAt": string;
>   "id": string;
>   "luid": string;
>   "name": string | null;
>   "projectName": string | null;
>   "sheets": { id: string; name: string | null; luid: string; }[];
>   "updatedAt": string;
>   "upstreamDatasources": ({ id: string; name: string | null; luid: string; } | null)[];
> }
> ```

#### Configuration: standard

Case: `tableau/workbooks/pull/standard`.

Connection and resource configuration are declared by this exact case.

Credential kind: `tableau`. Keep credential material in the private credential inventory.

| Setting | Type | Required | Owner |
| - | - | - | - |
| `baseUrl` | string | Yes | Shared connection |

> **Complete configuration contract**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "setup": [],
>   "resource": {
>     "access": {},
>     "defaults": {},
>     "connector": "tableau",
>     "output": {
>       "kind": "single",
>       "collection": "records"
>     },
>     "credential_kind": "tableau",
>     "connection_fields": [
>       "baseUrl"
>     ],
>     "address": {
>       "kind": "setup",
>       "field": "baseUrl"
>     }
>   },
>   "connection_setup": {
>     "type": "object",
>     "value": {
>       "baseUrl": {
>         "fieldType": {
>           "type": "string"
>         },
>         "optional": false
>       }
>     }
>   },
>   "execution": null
> }
> ```

Native admission analysis is available for this exact declaration.

**Collection: records**

| Contract | Meaning |
| - | - |
| Initial | Enumeration of observed records |
| Changes | Repeated observations of current records |
| Deletions | Deletion detection unsupported |
| Resume | Opaque cursor |
| Gap | Explicit repair required after a gap |
| Retention | Unspecified |

> **Complete native profile**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "movement": {
>     "exchanges": {
>       "records": {
>         "200": {
>           "placement": "retained_bytes",
>           "interpretation": "json",
>           "projectsBeforeRetention": false,
>           "retainedBodyLimitBytes": "524288",
>           "fileLimitBytes": null
>         }
>       }
>     },
>     "nativeInputLimitBytes": null,
>     "steps": [
>       {
>         "id": "acquire.1",
>         "inputs": [],
>         "action": {
>           "operation": "acquire",
>           "subject": "exchange records",
>           "limitBytes": null
>         }
>       },
>       {
>         "id": "retain.1",
>         "inputs": [
>           "acquire.1"
>         ],
>         "action": {
>           "operation": "retain",
>           "subject": "acquisition evidence",
>           "reason": "recovery",
>           "release": "acquisition_custody"
>         }
>       },
>       {
>         "id": "interpret.1",
>         "inputs": [
>           "retain.1"
>         ],
>         "action": {
>           "operation": "interpret",
>           "subject": "acquired input",
>           "produces": "records"
>         }
>       },
>       {
>         "id": "materialize.1",
>         "inputs": [
>           "interpret.1"
>         ],
>         "action": {
>           "operation": "materialize",
>           "subject": "source rows",
>           "reason": "serving",
>           "release": "replacement"
>         }
>       },
>       {
>         "id": "publish.1",
>         "inputs": [
>           "materialize.1"
>         ],
>         "action": {
>           "operation": "publish",
>           "subject": "source rows",
>           "visibility": "with_acquisition"
>         }
>       }
>     ]
>   },
>   "initial": "enumeration",
>   "changes": "observations",
>   "deletions": "unsupported",
>   "resume": "opaque_cursor",
>   "retentionMs": null,
>   "gap": "explicit_repair",
>   "limits": {
>     "http_response_bytes": "524288"
>   },
>   "restrictions": [],
>   "commands": {}
> }
> ```

> **Commands, occurrences and artifacts**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "records": {
>     "records": {
>       "protocol": "record_observation",
>       "coverage": "records",
>       "consistency": "observations",
>       "atomicity": "record",
>       "history": "observations",
>       "recordRefresh": false,
>       "reconciliation": false,
>       "notifications": false,
>       "snapshotMaxRows": null,
>       "profile": {
>         "movement": {
>           "exchanges": {
>             "records": {
>               "200": {
>                 "placement": "retained_bytes",
>                 "interpretation": "json",
>                 "projectsBeforeRetention": false,
>                 "retainedBodyLimitBytes": "524288",
>                 "fileLimitBytes": null
>               }
>             }
>           },
>           "nativeInputLimitBytes": null,
>           "steps": [
>             {
>               "id": "acquire.1",
>               "inputs": [],
>               "action": {
>                 "operation": "acquire",
>                 "subject": "exchange records",
>                 "limitBytes": null
>               }
>             },
>             {
>               "id": "retain.1",
>               "inputs": [
>                 "acquire.1"
>               ],
>               "action": {
>                 "operation": "retain",
>                 "subject": "acquisition evidence",
>                 "reason": "recovery",
>                 "release": "acquisition_custody"
>               }
>             },
>             {
>               "id": "interpret.1",
>               "inputs": [
>                 "retain.1"
>               ],
>               "action": {
>                 "operation": "interpret",
>                 "subject": "acquired input",
>                 "produces": "records"
>               }
>             },
>             {
>               "id": "materialize.1",
>               "inputs": [
>                 "interpret.1"
>               ],
>               "action": {
>                 "operation": "materialize",
>                 "subject": "source rows",
>                 "reason": "serving",
>                 "release": "replacement"
>               }
>             },
>             {
>               "id": "publish.1",
>               "inputs": [
>                 "materialize.1"
>               ],
>               "action": {
>                 "operation": "publish",
>                 "subject": "source rows",
>                 "visibility": "with_acquisition"
>               }
>             }
>           ]
>         },
>         "initial": "enumeration",
>         "changes": "observations",
>         "deletions": "unsupported",
>         "resume": "opaque_cursor",
>         "retentionMs": null,
>         "gap": "explicit_repair",
>         "limits": {
>           "http_response_bytes": "524288"
>         },
>         "restrictions": [],
>         "commands": {}
>       }
>     }
>   },
>   "occurrences": null,
>   "artifacts": {
>     "raw_archive": false,
>     "native_file_transfer_limit_bytes": null,
>     "external_versions": false,
>     "files": {}
>   },
>   "commands": {}
> }
> ```

**Recorded checks**

| Requirement | Scope | Evidence | Result |
| - | - | - | - |
| page-publication-recovery | \{"kind":"collection","name":"records"} | No check exercises this packaged Tableau declaration against Tableau; it is declared from documentation and has not run or been qualified. | Execution result unavailable |
| stated-cursor-empty-page-advances | \{"kind":"collection","name":"records"} | No check exercises this packaged Tableau declaration against Tableau; it is declared from documentation and has not run or been qualified. | Execution result unavailable |
| stated-cursor-repeat-refused | \{"kind":"collection","name":"records"} | No check exercises this packaged Tableau declaration against Tableau; it is declared from documentation and has not run or been qualified. | Execution result unavailable |
| identity-account | \{"kind":"connection"} | No check exercises this packaged Tableau declaration against Tableau; it is declared from documentation and has not run or been qualified. | Execution result unavailable |

Hosted qualification: **unestablished for this catalog configuration**. Installed connections report their own identity, authority and current status.

## Provider guidance

Compiled declaration examples and configuration details are published in the [connector reference](https://docs.bijection.com/integrations/connectors/index).

Read-only content inventory over the captured Metadata API
(`POST <baseUrl>/api/metadata/graphql`). The connection setup `baseUrl` is the
Tableau Server or Tableau Cloud origin (Cloud includes the pod).

The Metadata API uses the REST API credentials token in `X-Tableau-Auth`.
`tableau.credential("TABLEAU_SESSION")` names a `session_login` envelope: the
engine signs in with a personal access token, presents the `credentials.token`
it answers as `X-Tableau-Auth`, and signs in again after the declared lifetime or
once after a rejected request. Nothing in the recipe holds the token or writes the
header. Store the token's name as `username` and its secret as `password`, and
declare the sign-in for the site's `contentUrl` (Tableau Cloud requires one; omit
it for Tableau Server's default site):

```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
{
  "kind": "session_login",
  "login": {
    "endpoint": "https://prod-useast-a.online.tableau.com/api/3.24/auth/signin",
    "token": { "kind": "field", "name": "credentials.token" },
    "lifetime_seconds": 7200,
    "body": {
      "credentials": {
        "personalAccessTokenName": { "$secret": "username" },
        "personalAccessTokenSecret": { "$secret": "password" },
        "site": { "contentUrl": "acme" }
      }
    }
  },
  "username": "<token name>",
  "password": "<token secret>",
  "bearer_header": "x-tableau-auth",
  "allowed_resource_origins": ["https://prod-useast-a.online.tableau.com"]
}
```

A token is valid only for the site it signed in to. Tableau Server's token lasts
240 minutes by default, so a two-hour declared lifetime renews well inside it; the
reference states no Tableau Cloud lifetime, and a session that ends sooner is
recovered by signing in again after the rejected request. Signing in again with
the same personal access token ends its earlier session, so one token should back
exactly one credential. Connected-app JWT sign-in is not supported: the JWT must
be freshly signed for every sign-in, which the envelope does not do. Identity is `tableauSites[0].luid`; the reference does not say that
`tableauSites` lists only the signed-in site.

`datasources.pull` walks `publishedDatasourcesConnection(first: 100, after:)` and
`workbooks.pull` walks `workbooksConnection(first: 100, after:)`, following
`pageInfo.endCursor` while `hasNextPage` holds. Data sources carry
`upstreamTables` (`id`, `luid`, `name`, `fullName`, `schema`, `connectionType`);
workbooks carry `sheets` and `upstreamDatasources` (`id`, `luid`, `name`). Interface
fields (`fields`, `database`) are not selected. Workbook `updatedAt` is non-null
and is the opaque version; data source `updatedAt` is nullable, so data sources
carry no version. No coverage is claimed. Results are scoped to what the token's
user may see.

Nothing is withdrawn: removed content just disappears from the connection and the
API offers no tombstone.

`NODE_LIMIT_EXCEEDED` and `TIME_LIMIT_EXCEEDED` are documented warnings that return
partial results; the captured response contract admits only `data` (and
`extensions`), so a page that carries `errors` is refused rather than published
partially. `RATE_EXCEEDED` (Metadata API throttling, configurable on Tableau
Server) has no documented HTTP status or retry header, so no backoff is declared.

No write is declared; the Metadata API is read-only.

The schema is a reviewed projection transcribed from the published reference, not
retrieved by introspection. Regenerate with
`BIJECTION_GRAPHQL_EXECUTABLE=/path/to/bijection-graphql node dev/graphql-codegen.mjs tableau`
(`--check` compares). Nothing here has run against Tableau or been qualified.

## Provider references

Provider references and prerequisites are maintained in the connector guidance above. No separate provider-documentation review date is recorded.

## Source and evidence

[Canonical connector source](https://github.com/bijectionhq/component-support/blob/b632604330ce9cbcfe17a5a680ef4fbe80f6f672/packages/connectors/src/connectors/tableau/README.md), [native analysis](https://github.com/bijectionhq/component-support/blob/b632604330ce9cbcfe17a5a680ef4fbe80f6f672/packages/connectors/contract-analysis.json) and [check receipts](https://github.com/bijectionhq/component-support/blob/b632604330ce9cbcfe17a5a680ef4fbe80f6f672/packages/connectors/evidence.json).

Connector artifact: `905888ea276a2a28e36981a79e8142b2547ea451c3e63162cb6915ad4a7d1305`.

The resource declaration examples above are compiled and compared with exact catalog declarations. Recorded checks apply only to their source, declaration and runtime identities. Configure a connection and inspect its status to establish deployment-specific readiness.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.