From a726c46e0629634fa1da4e9fbfcc88e4d84c597c Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Mon, 9 Nov 2026 13:51:21 -0800 Subject: [PATCH 01/12] Document filter special characters, wildcard searches and cieq The filter docs only said ampersands and commas are unsupported, with no workaround, and did not say which fields support wildcard searches or the cieq and has operators. Document the asterisk workaround for values containing & or , (with a client-side exact-match check), the REST API's like operator and the fields it applies to, and add the missing CaseInsensitiveEquals and Has operators to the operator lists. Closes #1200 Co-Authored-By: Claude Code --- docs/api-ref.md | 4 ++- docs/filter-sort.md | 73 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index 104213764..ab8f09b92 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -3006,7 +3006,7 @@ Name | Description :--- | :--- `Field` | Defined in the `RequestOptions.Field` class. `Operator` | Defined in the `RequestOptions.Operator` class -`Value` | The value to compare with the specified field and operator. +`Value` | The value to compare with the specified field and operator. Values cannot contain `&` or `,`; see [Special characters in filter values](filter-sort#special-characters-in-filter-values). @@ -6163,6 +6163,8 @@ Operator | Description `LessThan` | Sets the operator to less than (same as `lt` in the REST API). `TSC.RequestOptions.Operator.LessThan` `LessThanOrEqual` | Sets the operator to less than or equal (same as `lte` in the REST API). `TSC.RequestOptions.Operator.LessThanOrEqual` `In` | Sets the operator to in (same as `in` in the REST API). `TSC.RequestOptions.Operator.In` +`Has` | Sets the operator to has (same as `has` in the REST API). `TSC.RequestOptions.Operator.Has` +`CaseInsensitiveEquals` | Sets the operator to case-insensitive equals (same as `cieq` in the REST API). `TSC.RequestOptions.Operator.CaseInsensitiveEquals`

diff --git a/docs/filter-sort.md b/docs/filter-sort.md index feaf12102..51d3cd33b 100644 --- a/docs/filter-sort.md +++ b/docs/filter-sort.md @@ -35,7 +35,7 @@ API help](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_conc To filter on a field, you need to specify the field name, an operator criteria and a value criteria. -**Note**: Ampersands and commas in filters are not supported by the REST API as they are used as delimiters. +**Note**: Ampersands and commas in filter values are not supported by the REST API as they are used as delimiters. See [Special characters in filter values](#special-characters-in-filter-values) for a workaround. ### Operator criteria @@ -50,10 +50,74 @@ The operator can be any of the following: * LessThanOrEqual * In * Has +* CaseInsensitiveEquals + +Not every operator is supported on every field. In particular, the REST API supports +`Has` (substring search) only for jobs, and `CaseInsensitiveEquals` only on user name, +group name, and group set name. See the per-endpoint field tables in the [REST +API help](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_filtering_and_sorting.htm). ### Value criteria -The value that you want to filter on. This can be any valid string. +The value that you want to filter on. This can be any valid string. Field names, operator +names, and values are case-sensitive; use `CaseInsensitiveEquals` where the field supports it. + +Pass values as plain strings. For REST API version 3.7 and later, TSC URL-encodes the +query string for you, so do not percent-encode values yourself. + +### Special characters in filter values + +The REST API does not accept ampersand (`&`) or comma (`,`) characters in a filter +expression, because it uses them to separate expressions. This is true even if the +characters are URL-encoded, and putting a backslash in front of a comma does not escape it. +A filter value that contains either character fails with a `400065: Bad Request` error: + +```py +# Fails: the workbook name contains a comma and an ampersand +workbooks = server.workbooks.filter(name="T(L-F,SZ&V-MY) - PC") +``` + +To find an item whose name contains these characters, replace each one with an asterisk +(`*`). The asterisk acts as a wildcard, so the following filter finds the workbook named +`T(L-F,SZ&V-MY) - PC`: + +```py +for workbook in server.workbooks.filter(name="T(L-F*SZ*V-MY) - PC"): + print(workbook.name, workbook.id) +``` + +Because a wildcard matches any character, the filter can return more than one item. In the +example above, the same filter also returns a workbook named `T(L-F^SZ|V-MY) - PC`. Check +the results on the client side if you need an exact match: + +```py +wb_name = "T(L-F,SZ&V-MY) - PC" +pattern = wb_name.replace(",", "*").replace("&", "*") +matches = [wb for wb in server.workbooks.filter(name=pattern) if wb.name == wb_name] +``` + +Wildcard matching with `Equals` is not described in the REST API documentation (see +[Wildcard searches](#wildcard-searches)), so test it against your server before you rely on it. + +### Wildcard searches + +The REST API supports wildcard searches (starts with, ends with, and contains) starting in +Tableau Cloud May 2023 and Tableau Server 2022.1.14. The REST API documents these searches +through its `like` operator, and only on selected name fields: user name, user +friendlyName, group name, and group set name. Other fields support exact matches only. + +For example, to search for the string `marketing-example`, the REST API documentation +gives the following filter expressions: + +| Search | REST API filter expression | +| --- | --- | +| Starts with | `name:like:mark*` | +| Ends with | `name:like:*-ample` | +| Contains | `name:like:mark*ex*` | + +TSC does not define a `RequestOptions.Operator` value for `like`, and there are no +`contains`, `startswith`, or `endswith` operators. A Django style filter such as +`name__like="mark*"` raises a `ValueError`. ### Filtering example - RequestOptions @@ -219,3 +283,8 @@ print(len(flows)) | LessThanOrEqual | lte | | In | in | | Has | has | +| CaseInsensitiveEquals | cieq | + +For example, `server.users.filter(name__cieq="jsmith")` matches a user named `JSmith`. +See [Special characters in filter values](#special-characters-in-filter-values) and +[Wildcard searches](#wildcard-searches) for limits on filter values. From 670c0e15592a2669705a5cdcac8bda91cfd0fbbb Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Mon, 9 Nov 2026 13:54:18 -0800 Subject: [PATCH 02/12] Update the filter and sort endpoint and field list The list named four endpoints and seven fields, far fewer than the library supports. Describe the endpoints by what they accept and point at RequestOptions.Field for the full set of fields. Co-Authored-By: Claude Code --- docs/filter-sort.md | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/docs/filter-sort.md b/docs/filter-sort.md index 51d3cd33b..9d3d30fca 100644 --- a/docs/filter-sort.md +++ b/docs/filter-sort.md @@ -10,23 +10,13 @@ then pass the object to your endpoint as a parameter. ## Available endpoints and fields -You can use the TSC library to filter and sort the following endpoints: +You can use the TSC library to filter and sort the results of any endpoint whose `get` +method accepts a `RequestOptions` object, and the endpoints that support the `.filter()` and +`.order_by()` shorthand: custom views, data sources, flow runs, flows, groups, group sets, +jobs, linked tasks, metrics, projects, users, views, virtual connections, and workbooks. -* Users -* Datasources -* Workbooks -* Views - -For the above endpoints, you can filter or sort on the following -fields: - -* CreatedAt -* LastLogin -* Name -* OwnerName -* SiteRole -* Tags -* UpdatedAt +The fields you can filter or sort on are the members of `RequestOptions.Field`, for example +`CreatedAt`, `LastLogin`, `Name`, `OwnerName`, `SiteRole`, `Tags`, and `UpdatedAt`. **Important**: Not all of the fields are available for all endpoints. For more information, see the [REST API help](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_filtering_and_sorting.htm). From aa8a0b1dff702eb0bbbcac2729fbd5801d9192b2 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Mon, 9 Nov 2026 14:00:56 -0800 Subject: [PATCH 03/12] Record observed wildcard behaviour of Equals filters on Tableau Cloud Checked against a Tableau Cloud site (REST API 3.30): an Equals filter treats * as a wildcard at the start, end and middle of a workbook name, which makes the documented workaround for values containing & or , work, while like, cieq and has are rejected with a 400 on workbook names. Document this and remove the untested-workaround caveat. Related to #1200 Co-Authored-By: Claude Code --- docs/filter-sort.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/filter-sort.md b/docs/filter-sort.md index 9d3d30fca..6d93967de 100644 --- a/docs/filter-sort.md +++ b/docs/filter-sort.md @@ -86,8 +86,7 @@ pattern = wb_name.replace(",", "*").replace("&", "*") matches = [wb for wb in server.workbooks.filter(name=pattern) if wb.name == wb_name] ``` -Wildcard matching with `Equals` is not described in the REST API documentation (see -[Wildcard searches](#wildcard-searches)), so test it against your server before you rely on it. +This works because `Equals` treats `*` as a wildcard (see [Wildcard searches](#wildcard-searches)). ### Wildcard searches @@ -96,6 +95,13 @@ Tableau Cloud May 2023 and Tableau Server 2022.1.14. The REST API documents thes through its `like` operator, and only on selected name fields: user name, user friendlyName, group name, and group set name. Other fields support exact matches only. +In practice, Tableau Cloud also treats `*` as a wildcard in the value of an `Equals` filter on +other name fields. For example, `server.workbooks.filter(name="EPI*")` returns workbooks whose +names start with `EPI`, `name="*360"` returns names that end with `360`, and `name="*IC *"` +returns names that contain `IC `. This is not described in the REST API documentation, so +confirm it on your Tableau Server version before you rely on it. The `like` operator is +rejected on workbook names (`400 Bad Request`), as are `CaseInsensitiveEquals` and `Has`. + For example, to search for the string `marketing-example`, the REST API documentation gives the following filter expressions: From 094935bfef1888806f77c32cace47de1a5862928 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Mon, 9 Nov 2026 14:15:35 -0800 Subject: [PATCH 04/12] Correct the filter docs: ampersands work, only commas need a workaround Tested against Tableau Cloud: TSC percent-encodes the query string, so an ampersand in a filter value is accepted. A comma is rejected even when encoded or preceded by a backslash. The earlier text said both characters failed. Co-Authored-By: Claude Code --- docs/filter-sort.md | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/docs/filter-sort.md b/docs/filter-sort.md index 6d93967de..1961d82c4 100644 --- a/docs/filter-sort.md +++ b/docs/filter-sort.md @@ -25,7 +25,7 @@ API help](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_conc To filter on a field, you need to specify the field name, an operator criteria and a value criteria. -**Note**: Ampersands and commas in filter values are not supported by the REST API as they are used as delimiters. See [Special characters in filter values](#special-characters-in-filter-values) for a workaround. +**Note**: Commas in filter values are not supported by the REST API, because it uses them to separate filter expressions. See [Special characters in filter values](#special-characters-in-filter-values) for a workaround. ### Operator criteria @@ -57,32 +57,35 @@ query string for you, so do not percent-encode values yourself. ### Special characters in filter values -The REST API does not accept ampersand (`&`) or comma (`,`) characters in a filter -expression, because it uses them to separate expressions. This is true even if the -characters are URL-encoded, and putting a backslash in front of a comma does not escape it. -A filter value that contains either character fails with a `400065: Bad Request` error: +The REST API does not accept a comma (`,`) in a filter value, because it uses commas to +separate expressions. This is true even if the comma is URL-encoded, and putting a backslash +in front of it does not escape it. A filter value that contains a comma fails with a +`400065: Bad Request` error: ```py -# Fails: the workbook name contains a comma and an ampersand -workbooks = server.workbooks.filter(name="T(L-F,SZ&V-MY) - PC") +# Fails: the workbook name contains a comma +workbooks = server.workbooks.filter(name="Calculations, Groups & Sets") ``` -To find an item whose name contains these characters, replace each one with an asterisk -(`*`). The asterisk acts as a wildcard, so the following filter finds the workbook named -`T(L-F,SZ&V-MY) - PC`: +An ampersand (`&`) works when you use TSC, because TSC URL-encodes the query string. If you +build the request yourself, encode the ampersand as `%26`: a literal `&` ends the `filter` +parameter and the server sees a truncated filter. + +To find an item whose name contains a comma, replace the comma with an asterisk (`*`). The +asterisk acts as a wildcard, so the following filter finds the workbook named +`Calculations, Groups & Sets`: ```py -for workbook in server.workbooks.filter(name="T(L-F*SZ*V-MY) - PC"): +for workbook in server.workbooks.filter(name="Calculations* Groups & Sets"): print(workbook.name, workbook.id) ``` -Because a wildcard matches any character, the filter can return more than one item. In the -example above, the same filter also returns a workbook named `T(L-F^SZ|V-MY) - PC`. Check +Because a wildcard matches any character, the filter can return more than one item. Check the results on the client side if you need an exact match: ```py -wb_name = "T(L-F,SZ&V-MY) - PC" -pattern = wb_name.replace(",", "*").replace("&", "*") +wb_name = "Calculations, Groups & Sets" +pattern = wb_name.replace(",", "*") matches = [wb for wb in server.workbooks.filter(name=pattern) if wb.name == wb_name] ``` From 3bcfb679b0c03ebc355dd9b18d37e7b7dd9384e7 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Mon, 9 Nov 2026 14:40:43 -0800 Subject: [PATCH 05/12] Explain that view filters use different value rules Readers of the special-character and wildcard sections could apply them to vf() export filters, where a comma separates alternatives, a backslash escapes it, and asterisks are literal. Co-Authored-By: Claude Code --- docs/filter-sort.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/filter-sort.md b/docs/filter-sort.md index 1961d82c4..5a4435b8f 100644 --- a/docs/filter-sort.md +++ b/docs/filter-sort.md @@ -118,6 +118,21 @@ TSC does not define a `RequestOptions.Operator` value for `like`, and there are `contains`, `startswith`, or `endswith` operators. A Django style filter such as `name__like="mark*"` raises a `ValueError`. +### View filters follow different rules + +The rules above apply to the `filter` query parameter that `RequestOptions.filter` and the +Django style filters build. View filters that you set with `vf()` on export options such as +`CSVRequestOptions` or `PDFRequestOptions` are sent as `vf_=` parameters, and +the server reads their values differently: + +- A comma separates alternatives, so `vf("Region", "East,West")` matches `East` or `West`. + To match a literal comma, escape it with a backslash: `vf("Name", "Rock\\, Paper")`. +- `*` and `%` are literal characters, not wildcards. +- Ampersands and other characters are passed through as data. + +For the server-side rules, see [Filter query views](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_filtering_and_sorting.htm#Filter-query-views) +in the REST API documentation. + ### Filtering example - RequestOptions The following code displays only the workbooks where the name equals Superstore: From 965c23103805376c9b938bcd62002db9ffd4064d Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Mon, 9 Nov 2026 15:10:59 -0800 Subject: [PATCH 06/12] Correct the case-sensitivity note for filter values Equals on workbook, data source, project and user names, and on workbook content URLs, ignores case. Equals on a group name is case-sensitive on Tableau Server. Refs #1200 Co-Authored-By: Claude Code --- docs/filter-sort.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/filter-sort.md b/docs/filter-sort.md index 5a4435b8f..eef8cc49a 100644 --- a/docs/filter-sort.md +++ b/docs/filter-sort.md @@ -49,8 +49,11 @@ API help](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_conc ### Value criteria -The value that you want to filter on. This can be any valid string. Field names, operator -names, and values are case-sensitive; use `CaseInsensitiveEquals` where the field supports it. +The value that you want to filter on. This can be any valid string. Field names and operator +names are case-sensitive. Whether a value is case-sensitive depends on the field. In testing, +`Equals` on the name of a workbook, data source, project, or user, and on a workbook's content +URL, ignored case. `Equals` on a group name was case-sensitive on Tableau Server. Where the +field supports it, use `CaseInsensitiveEquals` to ignore case regardless. Pass values as plain strings. For REST API version 3.7 and later, TSC URL-encodes the query string for you, so do not percent-encode values yourself. From a9c2a4228fb5c7f82d26bb4237f8d0bb22bd5fe8 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Mon, 9 Nov 2026 17:15:29 -0800 Subject: [PATCH 07/12] Use generic names in the filter examples Co-Authored-By: Claude Code --- docs/filter-sort.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/filter-sort.md b/docs/filter-sort.md index eef8cc49a..e4be9a158 100644 --- a/docs/filter-sort.md +++ b/docs/filter-sort.md @@ -67,7 +67,7 @@ in front of it does not escape it. A filter value that contains a comma fails wi ```py # Fails: the workbook name contains a comma -workbooks = server.workbooks.filter(name="Calculations, Groups & Sets") +workbooks = server.workbooks.filter(name="Sales, Q1 & Q2") ``` An ampersand (`&`) works when you use TSC, because TSC URL-encodes the query string. If you @@ -76,10 +76,10 @@ parameter and the server sees a truncated filter. To find an item whose name contains a comma, replace the comma with an asterisk (`*`). The asterisk acts as a wildcard, so the following filter finds the workbook named -`Calculations, Groups & Sets`: +`Sales, Q1 & Q2`: ```py -for workbook in server.workbooks.filter(name="Calculations* Groups & Sets"): +for workbook in server.workbooks.filter(name="Sales* Q1 & Q2"): print(workbook.name, workbook.id) ``` @@ -87,7 +87,7 @@ Because a wildcard matches any character, the filter can return more than one it the results on the client side if you need an exact match: ```py -wb_name = "Calculations, Groups & Sets" +wb_name = "Sales, Q1 & Q2" pattern = wb_name.replace(",", "*") matches = [wb for wb in server.workbooks.filter(name=pattern) if wb.name == wb_name] ``` @@ -102,9 +102,9 @@ through its `like` operator, and only on selected name fields: user name, user friendlyName, group name, and group set name. Other fields support exact matches only. In practice, Tableau Cloud also treats `*` as a wildcard in the value of an `Equals` filter on -other name fields. For example, `server.workbooks.filter(name="EPI*")` returns workbooks whose -names start with `EPI`, `name="*360"` returns names that end with `360`, and `name="*IC *"` -returns names that contain `IC `. This is not described in the REST API documentation, so +other name fields. For example, `server.workbooks.filter(name="Sales*")` returns workbooks whose +names start with `Sales`, `name="*2026"` returns names that end with `2026`, and `name="*Q1 *"` +returns names that contain `Q1 `. This is not described in the REST API documentation, so confirm it on your Tableau Server version before you rely on it. The `like` operator is rejected on workbook names (`400 Bad Request`), as are `CaseInsensitiveEquals` and `Has`. From 808cf6871f6b8e86cdae69f88ecaae9df0b60e63 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Mon, 9 Nov 2026 21:45:36 -0800 Subject: [PATCH 08/12] Add an In operator example and note that vf encodes ampersands Co-Authored-By: Claude Code --- docs/filter-sort.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/filter-sort.md b/docs/filter-sort.md index e4be9a158..a7b830212 100644 --- a/docs/filter-sort.md +++ b/docs/filter-sort.md @@ -131,7 +131,8 @@ the server reads their values differently: - A comma separates alternatives, so `vf("Region", "East,West")` matches `East` or `West`. To match a literal comma, escape it with a backslash: `vf("Name", "Rock\\, Paper")`. - `*` and `%` are literal characters, not wildcards. -- Ampersands and other characters are passed through as data. +- Ampersands and other characters are passed through as data. TSC URL-encodes the value, so + `vf("Client", "Smith & Sons")` sends the ampersand intact. For the server-side rules, see [Filter query views](https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_filtering_and_sorting.htm#Filter-query-views) in the REST API documentation. @@ -150,6 +151,24 @@ matching_workbooks, pagination_item = server.workbooks.get(req_option) print(matching_workbooks[0].owner_id) ``` +### Matching one of several values + +The `In` operator matches items whose field equals any value in a list: + +```py +req_option = TSC.RequestOptions() +req_option.filter.add(TSC.Filter(TSC.RequestOptions.Field.Name, + TSC.RequestOptions.Operator.In, + ['Superstore', 'Sales Dashboard'])) +matching_workbooks, pagination_item = server.workbooks.get(req_option) +``` + +Names that contain spaces or ampersands work in a list. The server separates the entries with +commas, so a value that contains a comma cannot be used in a list. See +[Special characters in filter values](#special-characters-in-filter-values). + +The Django style equivalent is `server.workbooks.filter(name__in=['Superstore', 'Sales Dashboard'])`. + ## Sorting To sort on a field, you need to specify the field name and the direction criteria for the sort order. From 62fe0d5ced2199914951573ab07e60d6603cde47 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Mon, 9 Nov 2026 21:46:10 -0800 Subject: [PATCH 09/12] Correct the In list comma note: the value splits silently Co-Authored-By: Claude Code --- docs/filter-sort.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/filter-sort.md b/docs/filter-sort.md index a7b830212..02f344dc2 100644 --- a/docs/filter-sort.md +++ b/docs/filter-sort.md @@ -164,7 +164,8 @@ matching_workbooks, pagination_item = server.workbooks.get(req_option) ``` Names that contain spaces or ampersands work in a list. The server separates the entries with -commas, so a value that contains a comma cannot be used in a list. See +commas, so a value that contains a comma is split into separate entries and does not match +the item it names. The request does not fail. See [Special characters in filter values](#special-characters-in-filter-values). The Django style equivalent is `server.workbooks.filter(name__in=['Superstore', 'Sales Dashboard'])`. From d92a780ba516f5c72c75ba68d29b8700cc225680 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Mon, 9 Nov 2026 22:03:28 -0800 Subject: [PATCH 10/12] Qualify & encoding by REST API version and fix Value row Values can contain &, but only from REST API 3.7 when TSC encodes the query string. The Value row said & is not allowed. Co-Authored-By: Claude Code --- docs/api-ref.md | 2 +- docs/filter-sort.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/api-ref.md b/docs/api-ref.md index ab8f09b92..6f0ff4529 100644 --- a/docs/api-ref.md +++ b/docs/api-ref.md @@ -3006,7 +3006,7 @@ Name | Description :--- | :--- `Field` | Defined in the `RequestOptions.Field` class. `Operator` | Defined in the `RequestOptions.Operator` class -`Value` | The value to compare with the specified field and operator. Values cannot contain `&` or `,`; see [Special characters in filter values](filter-sort#special-characters-in-filter-values). +`Value` | The value to compare with the specified field and operator. Values cannot contain `,`; see [Special characters in filter values](filter-sort#special-characters-in-filter-values). diff --git a/docs/filter-sort.md b/docs/filter-sort.md index 02f344dc2..e3f9b89a1 100644 --- a/docs/filter-sort.md +++ b/docs/filter-sort.md @@ -70,9 +70,9 @@ in front of it does not escape it. A filter value that contains a comma fails wi workbooks = server.workbooks.filter(name="Sales, Q1 & Q2") ``` -An ampersand (`&`) works when you use TSC, because TSC URL-encodes the query string. If you -build the request yourself, encode the ampersand as `%26`: a literal `&` ends the `filter` -parameter and the server sees a truncated filter. +From REST API 3.7, an ampersand (`&`) works when you use TSC, because TSC URL-encodes the query +string. On earlier versions, or if you build the request yourself, encode the ampersand as `%26`: +a literal `&` ends the `filter` parameter and the server sees a truncated filter. To find an item whose name contains a comma, replace the comma with an asterisk (`*`). The asterisk acts as a wildcard, so the following filter finds the workbook named From 9f0549aa4cf6fe4f8c5a61a8e2380d70433748d2 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Mon, 9 Nov 2026 22:10:51 -0800 Subject: [PATCH 11/12] Scope the Equals wildcard note to what was tested Prefix, suffix and middle * matched on workbook names (Tableau Cloud) and project names (REST API 3.31), ignoring letter case. Co-Authored-By: Claude Code --- docs/filter-sort.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/filter-sort.md b/docs/filter-sort.md index e3f9b89a1..b3a862e37 100644 --- a/docs/filter-sort.md +++ b/docs/filter-sort.md @@ -101,12 +101,15 @@ Tableau Cloud May 2023 and Tableau Server 2022.1.14. The REST API documents thes through its `like` operator, and only on selected name fields: user name, user friendlyName, group name, and group set name. Other fields support exact matches only. -In practice, Tableau Cloud also treats `*` as a wildcard in the value of an `Equals` filter on -other name fields. For example, `server.workbooks.filter(name="Sales*")` returns workbooks whose -names start with `Sales`, `name="*2026"` returns names that end with `2026`, and `name="*Q1 *"` -returns names that contain `Q1 `. This is not described in the REST API documentation, so -confirm it on your Tableau Server version before you rely on it. The `like` operator is -rejected on workbook names (`400 Bad Request`), as are `CaseInsensitiveEquals` and `Has`. +In practice, `*` also acts as a wildcard in the value of an `Equals` filter on other name +fields, at the start, end, or middle of the value. In testing this worked for workbook names on +Tableau Cloud and for project names on a Tableau Server that supports REST API 3.31. For example, +`server.workbooks.filter(name="Sales*")` returns workbooks whose names start with `Sales`, +`name="*2026"` returns names that end with `2026`, and `name="*Q1 *"` returns names that contain +`Q1 `. The match ignores letter case where `Equals` does. This is not described in the REST API +documentation, so confirm it on your Tableau Server version and field before you rely on it. The +`like` operator is rejected on workbook names (`400 Bad Request`), as are `CaseInsensitiveEquals` +and `Has`. For example, to search for the string `marketing-example`, the REST API documentation gives the following filter expressions: From d1f4a04600df6e6a27922930975adb6fc7527c55 Mon Sep 17 00:00:00 2001 From: Jac Fitzgerald Date: Mon, 9 Nov 2026 22:11:39 -0800 Subject: [PATCH 12/12] Say the wildcard behavior is not documented per version Co-Authored-By: Claude Code --- docs/filter-sort.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/filter-sort.md b/docs/filter-sort.md index b3a862e37..919c72a55 100644 --- a/docs/filter-sort.md +++ b/docs/filter-sort.md @@ -106,8 +106,9 @@ fields, at the start, end, or middle of the value. In testing this worked for wo Tableau Cloud and for project names on a Tableau Server that supports REST API 3.31. For example, `server.workbooks.filter(name="Sales*")` returns workbooks whose names start with `Sales`, `name="*2026"` returns names that end with `2026`, and `name="*Q1 *"` returns names that contain -`Q1 `. The match ignores letter case where `Equals` does. This is not described in the REST API -documentation, so confirm it on your Tableau Server version and field before you rely on it. The +`Q1 `. The match ignores letter case where `Equals` does. The REST API +documentation does not describe this behavior or say which versions support it, so confirm it on +your Tableau Server version and field before you rely on it. The `like` operator is rejected on workbook names (`400 Bad Request`), as are `CaseInsensitiveEquals` and `Has`.