diff --git a/modules/ROOT/pages/3rd-party-script.adoc b/modules/ROOT/pages/3rd-party-script.adoc index 680cbfa75..a978ada50 100644 --- a/modules/ROOT/pages/3rd-party-script.adoc +++ b/modules/ROOT/pages/3rd-party-script.adoc @@ -1,4 +1,4 @@ -= Integrate external tools and allow custom scripts += External tools and script integration :toc: true :toclevels: 2 @@ -52,6 +52,11 @@ image::./images/csp-script-domain.png[CSS script-src domain] * The *CSP script-src domains* cannot be enabled and configured at the Org level. When configured, this setting will apply to all the Orgs configured on your instance. ==== +=== Allow Websocket endpoints +If your tool uses WebSockets, add the tool’s `wss://` endpoint to the CSP and CORS allowlists in ThoughtSpot. This enables secure WebSocket connections from an embedded ThoughtSpot page to the tool's WebSocket endpoint without being blocked by the browser’s Content Security Policy. + +Only hosts explicitly listed with `wss://` are permitted. You can add `wss://` URL in the **Develop** > **Security Settings** page. + == Passing variables to the hosted script To pass variables to the customer's hosted script, Visual Embed SDK provides the `customVariablesForThirdPartyTools` parameter. The `customVariablesForThirdPartyTools` is an object containing the variables that you wish to pass to the customer’s hosted JavaScript. These may include private information such as credentials or keys. The hosted JavaScript will access these variables via the `window.tsEmbed` object. diff --git a/modules/ROOT/pages/abac_rls-variables.adoc b/modules/ROOT/pages/abac_rls-variables.adoc index 13155c0cf..7d3cc95f5 100644 --- a/modules/ROOT/pages/abac_rls-variables.adoc +++ b/modules/ROOT/pages/abac_rls-variables.adoc @@ -2,75 +2,58 @@ :toc: true :toclevels: 2 -:page-title: ABAC via tokens +:page-title: ABAC via RLS with variables :page-pageid: abac-via-rls-variables :page-description: Attribute-based access control pattern with variable attributes referenced in Row-Level Security (RLS) rules on a given table. -Attribute-Based Access Control (ABAC) is an access control model in which security entitlements are determined by evaluating a set of attributes included in a token generated for a user. The attributes are passed in a JSON Web Token (JWT) at session creation to dynamically filter data and enable user-specific security policies. +Attribute-Based Access Control (ABAC) is an access control model in which security entitlements are assigned to a ThoughtSpot user directly as a set of attributes with lists of values, rather than relying on a JOINed entitlements table within the data model. + +ThoughtSpot allows assigning attribute values to a user at session creation time by adding the values to the user's access token request. + +RLS rules are defined on table objects, which bind dynamically generated `WHERE` clauses to any generated query. Within RLS rules, attributes are referenced by their variable names using the `ts_var()` function to dynamically filter data and enable user-specific security policies. == Overview -To implement data security for application users, administrators can define RLS rules that use system variables such as `ts_username` or `ts_groups`. If a ThoughtSpot deployment requires granular access control and dynamic assignments beyond what system variables can support, administrators can use formula variables within RLS rules. +RLS rules have a defined set of system variables such as `ts_username` or `ts_groups`. Once ABAC via RLS is enabled, the `ts_var()` formula is available within the RLS rule editor to refer to any defined Formula variable within ThoughtSpot. -Formula variables are custom variables that enable dynamic and context-aware logic in RLS rules. They can be assigned at the Org, user, and data model levels. +Formula variables are custom variables defined within ThoughtSpot that enable dynamic and context-aware logic in RLS rules. They are assigned at the user level during session creation for the ABAC pattern, although they can be set at Org and data model levels as well. +//// In embedded analytics scenarios, where each user may require different data access, administrators can assign security attributes and rules on a per-user basis. For these use cases, administrators can implement a JWT-based ABAC model combined with RLS to enforce data security using dynamic attributes derived from formula variables. In the ABAC via RLS with variables method, administrators add formula variables to RLS rules and pass their values (`variable_values`) as security attributes and entitlements to the user session through a JWT. All derived objects then inherit the data security rules from the underlying Table and are filtered according to the user’s entitlements provided in the token. +//// +=== Implementation steps [NOTE] ==== - -* Formula variables are available on ThoughtSpot starting from 10.15.0.cl. If this feature is not enabled on your instance, contact ThoughtSpot Support. - -* In the legacy JWT ABAC token requests, you could set the `persist_option` parameter to `NONE`, `APPEND`, `REPLACE`, and `RESET`. However, when you use the `variable_values` parameter in the JWT API token request to set up RLS values for a given user, only `APPEND` and `REPLACE` are supported. - -* To reset the formula variable attributes of a user, use the `/api/rest/2.0/template/variables/update-values` API endpoint. - -* The ability to set variable values only for the current session, previously achieved by setting `persist_option: NONE`, is not supported with RLS via ABAC. + -For session-based rules, create dedicated user accounts for your application users and apply persisted rules. This approach ensures that Liveboard schedule attachments enforce security rules and deliver only secured output to your end users. When combined with cookieless authentication, this configuration addresses all use cases that previously relied on session-based JWT. You can simplify user provisioning and programmatically manage user creation and deletion workflows using ThoughtSpot's REST APIs. +Formula variables are available on ThoughtSpot starting from 10.15.0.cl. If this feature is not enabled on your instance, contact ThoughtSpot Support. ==== -=== Indexing -Several features within ThoughtSpot, such as autocompletion in Search on values within columns, use ThoughtSpot indexing. Due to the runtime nature of ABAC tokens, ThoughtSpot indexing will not be restricted by the values supplied in a token. This means the indexed columns may expose values in search suggestions or autocompletion that a user should not see, even if ABAC filters would block access to the underlying data. To prevent this, you can do one of the following: - -* Disable indexing for columns and fields that must be restricted by ABAC. You may also want to disable indexing on all sensitive columns. -* Define an RLS rule on those fields, since RLS is enforced at the indexing layer and will secure suggestions and sample values. - -=== Implementation steps The ABAC implementation with formula variables and RLS rules includes the following steps: * xref:abac_rls-variables.adoc#_create_formula_variables[Creating formula variables] + To generate tokens with variable attributes, the variables must be available in ThoughtSpot. To create variables, use the xref:variables.adoc#_create_a_variable[Variable REST API]. -* xref:abac_rls-variables.adoc#_add_rls_rules_with_variable_references[Adding RLS rules with formula variables] + -When defining an RLS rule with variables, use the `ts_var` function. These RLS rules will apply to the Models, Liveboards, and other objects derived from that Table. -* xref:abac_rls-variables.adoc#_define_values_and_scope_for_variables[Creating a token request with variable attributes] + -To generate a JWT token, use the `/api/rest/2.0/auth/token/custom` REST API endpoint. The token generation request must include the variable attributes, which will be used for RLS evaluation to enable per‑user entitlements and data filters across all the objects derived from the Table. +* xref:abac_rls-variables.adoc#_add_or_update_rls_rules_with_variable_references[Adding RLS rules with formula variables] + +When defining an RLS rule with variables, use the `ts_var` function. These RLS rules will apply to the Models, Liveboards, and other objects derived from that Table. *A formula variable must be defined before it can be used in an RLS rule.* +* xref:abac_rls-variables.adoc#_create_an_abac_token_request_with_variable_attributes[Creating a token request with variable attributes] + +Attribute values are assigned to users by requesting a token using the `/api/rest/2.0/auth/token/custom` REST API endpoint. * xref:abac_rls-variables.adoc#_verify_the_entitlements[Verifying entitlements] + -To ensure data security rules are applied, check user entitlements and verify if they are translated accurately during query generation. - -The ABAC via tokens method requires the xref:trusted-authentication.adoc[trusted authentication] setup. - -//// -=== Mandatory token filters +To ensure data security rules are applied, check user entitlements and verify that they are translated accurately during query generation. Variables and their assigned values are visible to administrators using the `/api/rest/2.0/template/variables/search` endpoint with the `response_content` parameter set to `METADATA_AND_VALUES`. -The `is_mandatory_token_filter: true` setting in object TML enforces that a filter rule must be provided for a specific column. When this attribute is set on a column in a Model, ThoughtSpot will deny all data access for users who do not have a corresponding filter rule for that column in their ABAC token. - -When setting filter rules within the token, you must place the `is_mandatory_token_filter: true` property on every column in a Model where a filter rule is expected. This setting will deny any access to data if a user has not been assigned values for the expected set of fields. +=== Indexing +Several features within ThoughtSpot, such as autocompletion in Search on values within columns, use ThoughtSpot indexing. Due to the runtime nature of ABAC tokens, ThoughtSpot indexing will not be restricted by the values supplied in a token. This means the indexed columns may expose values in search suggestions or autocompletion that a user should not see, even if ABAC filters would block access to the underlying data. To prevent this, you can do one of the following: -[#column-name-warning] -The filter rules require passing the *exact* column name as defined in the Model. Otherwise, the values will not bind to any column. You must coordinate between the team that maintains the data objects and the team that builds the xref:trusted-auth-token-request-service.adoc[token request service] to know if any changes will be made to a Model and to ensure column names remain consistent. + -For this reason, end users of an embedded app must not be granted edit access to any Model using ABAC rules via tokens. Setting the `is_mandatory_token_filter: true` property on every column where a filter rule is expected ensures that no data is returned for users when column names change. +* Disable indexing for columns and fields that must be restricted by ABAC. You may also want to disable indexing on all sensitive columns. +* Define an RLS rule on those fields, since RLS is enforced at the indexing layer and will secure suggestions and sample values. -[NOTE] -==== -If a column is set with both `is_hidden: true` and `is_mandatory_token_filter: true`, and filter conditions for that column are defined in the ABAC token, the filter will be applied as expected. The column will be hidden from the user interface, but the mandatory filter requirement will still be enforced, and data will be shown according to the filter values provided in the token. -==== -//// == Create formula variables +Formula variables must be defined in ThoughtSpot before they can be used in any RLS rule via the `ts_var()` formula. + +To view the variables available on your instance, use the `POST /api/rest/2.0/template/variables/search` API call. -To view the variables available on your instance, use the `POST /api/rest/2.0/template/variables/search` API call. To create a new variable, use the `/api/rest/2.0/template/variables/create` API endpoint. +To create a new variable, use the `/api/rest/2.0/template/variables/create` API endpoint. To configure formula variables for all Orgs on your instance or the Primary Org, cluster administration privileges are required. Org administrators can configure formula variables for their respective Orgs. Users with the `CAN_MANAGE_VARIABLES` (*Can manage variables*) role privilege can also create and manage variables for their Org context. @@ -87,33 +70,46 @@ During variable creation, specify the xref:variables.adoc#data_type[`data_type`] Formula variables for `BOOLEAN` and `TIME` data types are not supported. -[source,cURL] +[source,JSON] ---- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/]api/rest/2.0/template/variables/create' \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ +{ "type": "FORMULA_VARIABLE", "name": "country_var", "is_sensitive": false, "data_type": "VARCHAR" -}' +} ---- -The variable update API allows assigning variable values and setting the scope. In the ABAC implementation, administrators can set the variable values and scope when xref:abac_rls-variables.adoc#_create_an_abac_token_request_with_variable_attributes[generating a JWT] using the `/api/rest/2.0/auth/token/custom` API endpoint. +The variable update API (`/api/rest/2.0/template/variables/{identifier}/update`) allows updating the variable name and other attributes of the variable definition, but not the values assigned to users or other principals. -== Add RLS rules with variable references -To define RLS rules with variables for a Table: +Variable values are set either by xref:abac_rls-variables.adoc#_create_an_abac_token_request_with_variable_attributes[generating a token] using the `/api/rest/2.0/auth/token/custom` API endpoint or via the Update Variable Values REST API. + +== Add or update RLS rules with variable references +RLS rules are defined on Table objects: . Navigate to the Data workspace and click the Table for which to define RLS rules. . Click *Row security* and then click *+ Add row security*. -. In the *Row Security Editor*, define the rules. To reference the formula variable in the rule, use the `ts_var` function. For example, If you want to limit user access to data of a specific region, you can create a region-specific variable, `region = ts_var(region_var)`, and assign values in the token request. +. In the *Row Security Editor*, define the rules. To reference the formula variable in the rule, use the `ts_var(varName)` function, with no quotes around the formula variable name. For example, to limit a column called `region` to the values set in a formula variable called `region_var`, set the RLS rule to: `region = ts_var(region_var)`. + +[NOTE] +==== +Variable values are set through the token request. The RLS rule specifies how the values will be used in the generated RLS WHERE clauses in the SQL. +==== + +=== RLS rule examples +RLS rules must always evaluate logically to SQL boolean `TRUE` or `FALSE`. +If a user has no variable values for a given formula variable, this results in `FALSE`. -=== RLS rule with a single variable reference +There is a special wildcard value `['TS_WILDCARD_ALL']` that a formula variable can be set to represent "Allow all". +In this example, `customer` represents the `customer` column in the table, and `customer_var` represents a variable. If the value of `customer_var` is set to `TS_WILDCARD_ALL`, the user can access all customers in the column. + +---- +customer = ts_var(customer_var) +---- + +==== RLS rule with a single variable reference In this formula example, `country` refers to the "country" column in the data table, and `country_var` is the variable. ---- @@ -124,7 +120,7 @@ If `country_var` is assigned a single value, the user is permitted to view only If `country_var` is assigned multiple values, the formula translates to `country IN ('value1', 'value2', ...)`. The query engine interprets `=` as the `IN` clause in this case and returns rows that match these values; for example, `WHERE country IN ('Australia', 'Germany')`. -=== RLS rules with multiple variables +==== RLS rules with multiple variables The RLS rules support the `AND` operator, which means that you can combine multiple conditions in a single RLS rule, so that a row is accessible only if all the specified conditions are met. The following rule restricts data access to rows if the `country` column in the data table matches the value assigned to `country_var` and the `Department` column matches the value assigned to `department_var` for that user. @@ -139,14 +135,7 @@ The rule in this example restricts data access to rows where the `region` column region = ts_var(region_var) AND product = ts_var(product_var) ---- -=== Allow all rule with a TS_WILDCARD_ALL variable -In this example, `customer` represents the column `customer` in the table and `customer_var` represents variable. If the value of the customer_var variable is set to `TS_WILDCARD_ALL`, the user can access all customers in the column. - ----- -customer = ts_var(customer_var) ----- - -=== Group override rule with variable-based check +==== Group override rule with variable-based check In any security formula you build, you may want a clause that gives access to all data to certain groups. In the rule definition, you can include system variables, such as `ts_groups`, to build your preferred logic: In this example, users can access data if they are in the "data developers" group, or if the `Department` column matches the value assigned to their `department_var` variable. @@ -157,7 +146,7 @@ In this example, users can access data if they are in the "data developers" grou ==== Variables with numeric and Date data types -The following rule enforces a numeric threshold and restricts access to rows where the Revenue value is less than or equal to the value provided by the `revenue_cap_var` variable. +The following rule enforces a numeric threshold and restricts access to rows where the Revenue value is less than or equal to the value provided by the `revenue_cap_var` variable. ---- Revenue <= to_double(ts_var(revenue_cap_var)) @@ -171,9 +160,11 @@ The following rule restricts access to rows where the `date_column` is within th == Create an ABAC token request with variable attributes -To generate a token with variable attributes, use the `POST /api/rest/2.0/auth/token/custom` API call. +To set or update variable values for a user, use the `POST /api/rest/2.0/auth/token/custom` endpoint when logging in the user. -The variable attributes defined in the token request take effect only if they are referenced in an RLS rule. If the variables are not used in any formula or RLS rule, they will have no impact on data access. Before generating the request with variable attributes, ensure that the xref:abac_rls-variables.adoc#_add_rls_rules_with_formula_variables_to_tables[variables are added to the RLS rules] for the Table. +You can also use the `/api/rest/2.0/template/variables/update-values` endpoint for bulk operations or targeted resets. + +The variable attributes defined in the token request take effect only if they are referenced in an RLS rule. If the variables are not used in any formula or RLS rule, they have no impact on data access. Before generating the request with variable attributes, ensure that the xref:abac_rls-variables.adoc#_add_or_update_rls_rules_with_variable_references[variables are added to the RLS rules] for the table. In the token request, include the following properties along with the `username`, xref:trusted-auth-secret-key.adoc[`secret_key`]: @@ -189,7 +180,7 @@ The `variable_values` array requires the following parameters: * `name` + __String__. Name of the formula variable. The formula variable referenced on the token request must be available in ThoughtSpot and included in the RLS rule. * `values` + -__Array of strings or numeric values__. When assigning values, ensure the data format of values matches the data type set of that variable. If you are adding a variable to filter by country with the `VARCHAR` data type, specify the string values as shown in this example: +__Array of strings or numeric values__. When assigning values, ensure the data format of the values matches the data type set for that variable. If you are adding a variable to filter by country with the `VARCHAR` data type, specify string values as shown in this example: [source,JSON] ---- @@ -207,15 +198,19 @@ __Array of strings or numeric values__. When assigning values, ensure the data f All values are passed into the token as *arrays of strings*, even if the column is a numeric or date type in ThoughtSpot and the database. The column data type will be respected in the query issued to the database. -==== Allow all values by default +==== Allow all wildcard value -To allow all values by default, specify `["TS_WILDCARD_ALL"]` as the variable value to grant access to all values in a given column. +To allow all values for a given field, set the formula variable value to an array using the wildcard: `["TS_WILDCARD_ALL"]`. -In this example, the user is allowed all access for one variable, while for the others, specific values are set. +In this example, the user is allowed all access for one variable, while for the other, specific values are set. [source,JSON] ---- "variable_values": [ + { + "name": "product_var", + "values": ["TS_WILDCARD_ALL"] + }, { "name": "country_var", "values": [ @@ -223,19 +218,6 @@ In this example, the user is allowed all access for one variable, while for the "Singapore", "Australia" ] - }, - { - "name": "department_var", - "values": [ - "Sales", - "Marketing" - ] - }, - { - "name": "product_var", - "values": [ - "TS_WILDCARD_ALL" - ] } ] ---- @@ -243,10 +225,13 @@ In this example, the user is allowed all access for one variable, while for the If `TS_WILDCARD_ALL` is set for variable attributes, ensure that the RLS rules are defined clearly on the Table to avoid unintended data exposure. ==== Deny all by default -For every variable included in the token request, you can assign one or more values. All variables referenced in RLS rules are required. If a variable is not assigned any value, query generation will fail with the following error. +For every variable included in the token request, you can assign one or more values. All variables referenced in RLS rules are required. If a variable is not assigned any value, query generation fails with the following error: -`Error in loading data -No values are assigned to some or all Formula Variables` +[source,text] +---- +Error in loading data +No values are assigned to some or all Formula Variables +---- [.bordered] [.widthAuto] @@ -256,25 +241,76 @@ Due to this error, no data is returned, effectively denying all data access for === Persist options and session-based rules -Variable attributes must be *persisted* for them to apply to user sessions when using xref:trusted-authentication.adoc#cookie[cookie-based trusted authentication] or scheduled reports. To specify whether variable attributes and rules should persist for user sessions, you must define the `persist_option` parameter. +Variable attributes must be *persisted* for them to apply. -To append or replace the attributes, use the following options: - -* `APPEND` + -Adds the attributes defined in the API request to the user properties. These properties will be applied to the current and future user sessions and scheduled reports until they are explicitly changed through a token update request. +To append or replace attribute values for a user, use one of the following `persist_option` values in the token request: * `REPLACE` + -Replaces existing variable assignments with the new values. +Replaces the full set of existing variable assignments with the new values from the token request. + +* `APPEND` + +Adds the attribute values defined in the API request to the existing attribute values for the user. + +If you don't want to append or replace any attribute values, do not pass any details about the variable in the token update request. [NOTE] ==== -* The ABAC implementation with RLS and formula variables does not support session-based rules. Therefore, ThoughtSpot does not recommend setting the `persist_option` attribute to `NONE`. -* If you don't want to append or replace any attributes, do not pass any variable values in the token update request. -* Resetting attributes using the`"persist_option": "RESET"` attribute in the token request is not supported. Passing an empty array does not reset the attributes. To reset the formula variable attributes of a user, use the `/api/rest/2.0/template/variables/update-values` API endpoint. +* The ABAC implementation with RLS and formula variables does not support session-based rules. Do not use the legacy `persist_option` value of `NONE`. +* `"persist_option": "RESET"` attribute is also a legacy value and is not supported. ==== +=== Resetting a user or a variable +Passing an empty array along with a formula variable name in the token request *does not reset the attribute values* for that formula variable for that user. + +To change formula variable attributes of a user, especially to set entitlements to an empty set, use the `/api/rest/2.0/template/variables/update-values` API endpoint. + +[WARNING] +==== +The `RESET` operation erases all variable value settings for all users for a variable, regardless of any `variable_value_scope` provided. Use with caution; it is a complete reset. +==== + +A formula variable exists across all Orgs in ThoughtSpot, but the values are recorded on a per Org and per Principal basis. To use the Update Variable Values REST API, you'll need to provide the `org_identifier` as well as the username as `principal_identifier` and set `principal_type` to `USER` as seen below: + +[,json] +---- +{ + "variable_assignment": [ + { + "variable_identifier": "country_var", + "variable_values": [], + "operation": "REPLACE" + } + ], + "variable_value_scope": [ + { + "org_identifier": "Prod", + "principal_type": "USER", + "principal_identifier": "jane.smith@company.com" + } + ] +} +---- +The above command results in `jane.smith@company.com` being denied any access when `country_var` is used in an RLS rule. + + +[NOTE] +==== +Do not use the `/api/rest/2.0/users/{user_identifier}/update` endpoint, as it does not support updating variable values. +==== + +=== Session-based ABAC and one-time users + +The ability to set variable values only for the current session, previously achieved by setting `persist_option: NONE`, is not supported with RLS via ABAC. + +For session-based rules, create dedicated one-time user accounts for your application users and apply persisted rules. Unless specifically stated in your contract, there is no limit to the number of users that can be created and provisioned in ThoughtSpot. + +This approach ensures that Liveboard schedule attachments enforce security rules and deliver only secured output to your end users. When combined with cookieless authentication, this configuration addresses all use cases that previously relied on session-based JWT. + +You can simplify user provisioning and programmatically manage user creation and deletion workflows using ThoughtSpot's REST APIs. + + === Variable scope -To restrict the scope of the variable attributes and rules to a specific Org context and object, define the `org_identifier` and `objects`. +To restrict the scope of variable attributes and rules to a specific Org context and object, define `org_identifier` and `objects`. ==== Apply to specific objects To apply variable entitlements to a specific object, specify the object IDs in the `objects` array as shown in this example: @@ -298,25 +334,11 @@ The API supports only the `LOGICAL_TABLE` object type. If the object ID is not specified in the API request, the variable values will be applied to all formulas and rules that use those variables, across all objects in the Org for that user. -==== Apply to Org context - -The `org_identifier` attribute in the token request specifies the Org context for the user session and entitlements. - -If the `org_identifier` parameter is not defined in the token request, the token is issued for the user's last logged-in Org. For new users, the token will be assigned to the default Org on their instance. - -To apply variable entitlements to a user session, you must ensure that the RLS rules with variables and relevant objects are available in the Org context specified in the token request. - -=== Example request body +The following example shows the request body for generating a token with formula variable attributes scoped to a particular Model object: -The following example shows the request body for generating a token with formula variable attributes: - -[source,cURL] +[source,JSON] ---- - curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/auth/token/custom' \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - --data-raw '{ +{ "username": "UserA", "validity_time_in_sec": 300, "persist_option": "APPEND", @@ -324,24 +346,17 @@ The following example shows the request body for generating a token with formula "secret_key": "f8aa445b-5ff1-4a35-a58f-e324133320d5", "variable_values": [ { - "name": "country_var", - "values": [ - "Japan", - "Singapore", - "Australia" - ] - }, - { - "name": "department_var", + "name": "product_var", "values": [ - "Sales", - "Marketing" + "TS_WILDCARD_ALL" ] }, { - "name": "product_var", + "name": "country_var", "values": [ - "TS_WILDCARD_ALL" + "Japan", + "Singapore", + "Australia" ] } ], @@ -351,17 +366,27 @@ The following example shows the request body for generating a token with formula "identifier": "35aa85fe-fbb4-4862-a335-f69679ebb6e0" } ] -}' +} ---- -If the request is successful, ThoughtSpot generates a token and sends the token details in the API response. +==== Apply to Org context + +The `org_identifier` attribute in the token request specifies the Org context for the user session and entitlements. + +If the `org_identifier` parameter is not defined in the token request, the token is issued for the user's last logged-in Org. For new users, the token will be assigned to the default Org on their instance. + +To apply variable entitlements to a user session, you must ensure that the RLS rules with variables and relevant objects are available in the Org context specified in the token request. [NOTE] ==== -ABAC details are sent in a JWT that can be used as a bearer token for cookieless trusted authentication, REST API calls, or as a sign-in token to start a session. JWTs are compressed by default to handle large payloads. It is recommended to keep the compression enabled to ensure all JWT tokens can get properly interpreted by the application regardless of their size, and to obfuscate the values passed in the JWT payload. If you want to disable it, contact ThoughtSpot Support. +ThoughtSpot access tokens are JWTs that are compressed by default to handle large payloads. It is recommended to keep the compression enabled to ensure all tokens can get properly interpreted by the application regardless of their size, and to obfuscate the values passed in the payload. If you want to disable it, contact ThoughtSpot Support. ==== + +//// +--- THIS IS NOT TRUE ANYMORE === Verify the variable assignment + To retrieve user information and object properties, you can use the `POST /api/rest/2.0/users/search` API call. To include variable details in the response, set the `include_variable_values` parameter to `true` in the API request body. This allows you to fetch variable values associated with the user in the specified context. [source,JSON] @@ -393,13 +418,55 @@ To retrieve user information and object properties, you can use the `POST /api/r } } ---- +//// + +== Verify the entitlements You can also use the `POST /api/rest/2.0/template/variables/search` API call to xref:variables.adoc#_get_variables[get the list of variables] assigned to a specific user, Org, and Model. -==== Updating variable values for a user -To update variable values for a user, you can use the `/api/rest/2.0/template/variables/update-values` endpoint, or `/api/rest/2.0/auth/token/custom` endpoint when logging in the user. Do not use the `/api/rest/2.0/users/{user_identifier}/update` endpoint, as it does not support updating variable values. +Set the `response_content` parameter to `METADATA_AND_VALUES` to see the values that have been set for each user per Org: + +[,json] +---- +{ + "record_offset": 0, + "record_size": -1, + "response_content": "METADATA_AND_VALUES" +} +---- + +This results in the following response: + +[,json] +---- +[ + { "id":"d3abc655-b706-4f91-90ea-cc26bc966d46", + "name":"country_var", + "variable_type":"FORMULA_VARIABLE", + "sensitive":false, + "values":[ + { + "value": null, + "value_list": ["CustomerC","CustomerD"], + "org_identifier": "Prod", + "principal_type": "USER", + "principal_identifier": "ron.smith@company.com", + "model_identifier": null, + "priority": null + },{ + "value": null, + "value_list": null, + "org_identifier": "Prod", + "principal_type": "USER", + "principal_identifier": "jane.smith@company.com", + "model_identifier": null, + "priority": null + } + ] + } +] +---- -== Verify the entitlements To verify the entitlements: . Log in to your app with a user account that does not have the *Can administer and bypass RLS* privilege, and initiate the user session with the ABAC token. @@ -412,4 +479,4 @@ To verify the entitlements: == Additional resources * For information about variables and variable APIs, see link:https://docs.thoughtspot.com/cloud/latest/rls-variables-reference[Variables] and xref:variables.adoc[Variable APIs]. -* For information about RLS rules,see xref:rls-rules.adoc[RLS Rules] and link:https://docs.thoughtspot.com/cloud/latest/security-rls[ThoughtSpot Product Documentation, window=_blank]. +* For information about RLS rules, see xref:rls-rules.adoc[RLS rules] and link:https://docs.thoughtspot.com/cloud/latest/security-rls[ThoughtSpot product documentation, window=_blank]. diff --git a/modules/ROOT/pages/about-rest-apis.adoc b/modules/ROOT/pages/about-rest-apis.adoc index 608f729d1..3ac6e7ca6 100644 --- a/modules/ROOT/pages/about-rest-apis.adoc +++ b/modules/ROOT/pages/about-rest-apis.adoc @@ -26,11 +26,22 @@ ThoughtSpot users with Developer or Administrator privileges can access the REST * To try out the xref:rest-api-v1.adoc[REST API v1 endpoints], click **REST Playground v1**. + * To access the xref:rest-api-v2.adoc[REST API v2 Playground], click **REST Playground v2.0**. +== Rate limits for API requests +To ensure API stability, optimize resource usage, and maintain service quality for all users, ThoughtSpot limits the number of public API requests allowed per client to prevent excessive requests from reaching application servers. + +By default, on instances running 26.2.0.cl and later, a global rate limit of 100 requests per second per client IP is enforced at the cluster level for all public APIs. This limit is applied per client IP across all public APIs combined, not per endpoint. If a client IP exceeds this combined rate limit, a burst of 10 additional API requests is allowed before rejecting the requests with the 'HTTP 429: Too Many Requests' error. + +For async status endpoints such as `/api/rest/2.0/metadata/tml/async/status`, up to 100 requests per minute per client IP are allowed, with a burst of 100 requests before requests are rejected with an HTTP 429 error. + +These rate limits are enforced by default on all ThoughtSpot instances. Currently, rate limits are applied at the cluster level; Org-level rate limits are not supported. + +To update rate limits or adjust the rate limit settings for your dev or prod environment, contact ThoughtSpot Support. + +//ThoughtSpot administrators can monitor logs, add or update rate limits via TSCLI, and adjust these settings for different environments (dev or prod) as required. + == API endpoints For a complete list of API endpoints and information about how to make an API call to these endpoints, see the following reference pages: * xref:rest-api-reference.adoc[REST API v1 Reference] * xref:rest-api-v2-reference.adoc[REST API v2.0 Reference] -//// - diff --git a/modules/ROOT/pages/ai-integration-options.adoc b/modules/ROOT/pages/ai-integration-options.adoc new file mode 100644 index 000000000..5e67530b7 --- /dev/null +++ b/modules/ROOT/pages/ai-integration-options.adoc @@ -0,0 +1,61 @@ += ThoughtSpot AI analytics integration +:toc: true +:toclevels: 3 + +:page-title: AI integration options +:page-pageid: ai-analytics-integration +:page-description: Learn the different ways to integrate ThoughtSpot analytics and AI experiences into your applications and AI agents, including MCP Server, Spotter Embed, and Spotter APIs. + +ThoughtSpot provides several options to bring governed analytics and AI-powered experiences into your applications, AI agents, and workflows. + +== AI integration options + +The primary ways to integrate ThoughtSpot analytics and AI into your environment are: + +* xref:ai-integration-options.adoc#_thoughtspot_mcp_server[ThoughtSpot Model Context Protocol (MCP) Server] +* xref:ai-integration-options.adoc#_embedding_spotter_in_your_app[Embedding Spotter in your app] +* xref:ai-integration-options.adoc#_spotter_rest_apis[Spotter REST APIs] + +[NOTE] +==== +All options allow using your existing ThoughtSpot data models, Liveboards, Answers, row-level and column-level security, and governance. The main differences are where the UI or conversation layer exists and who orchestrates the analytics workflow. +==== + +=== ThoughtSpot MCP Server + +ThoughtSpot xref:mcp-integration.adoc[MCP Server] exposes governed analytics as MCP tools and resources to AI agents and clients. The MCP Server can be integrated with your MCP client, agent, LLM, or application UI, allowing your users to explore ThoughtSpot's agentic capabilities within the context of your application. + +ThoughtSpot recommends using the MCP Server in these scenarios: + +* When you want to plug ThoughtSpot into AI agents and clients that already support MCP, such as Claude, ChatGPT, Gemini, IDEs, and custom MCP clients. +* If you are building your own MCP-based chatbot or application, and want to call ThoughtSpot MCP tools behind a custom web experience. + +For more information, see the xref:mcp-integration.adoc[MCP Server] documentation. + +=== Embedding Spotter in your app + +Developers can embed ThoughtSpot's xref:embed-spotter.adoc[conversational UI experience and its agentic capabilities] directly into their applications using the Visual Embed SDK. + +If your business requires you to quickly integrate the Spotter experience into your applications and workflows, and provide a native AI search and analysis experience within your app, use this option. + +For more information, see the xref:embed-ai-analytics.adoc[Embed AI Search and Analytics] and xref:embed-spotter.adoc[Spotter embed] documentation. + +=== Spotter REST APIs + +Spotter REST APIs provide programmatic access to Spotter conversation sessions, analytics, and agentic workflows. REST API clients use these APIs to send questions and receive structured answers, charts, or get relevant questions for a specific data model. + +ThoughtSpot recommends using Spotter REST APIs in the following scenarios: + +* When you want your application, agent, or orchestration logic to interact with ThoughtSpot programmatically, without requiring MCP. +* If you need to integrate ThoughtSpot responses and workflows with other systems. +* For fine-grained control over the user experience. + +//* For fine-grained control over data context, query options, and prompt structure, and . + +For more information, see the xref:spotter-apis.adoc[Spotter AI API] documentation. + +== Additional resources + +* For information about MCP, see the link:https://modelcontextprotocol.io[Model Context Protocol specification, window=_blank]. +* For information about SDK libraries for embedding, see the link:https://github.com/thoughtspot/visual-embed-sdk[Visual Embed SDK GitHub repository, window=_blank]. +* To view Spotter APIs, visit the +++REST API v2.0 Playground+++ and navigate to the **AI** section. diff --git a/modules/ROOT/pages/api-changelog.adoc b/modules/ROOT/pages/api-changelog.adoc index 4022f96ea..0e0cccee8 100644 --- a/modules/ROOT/pages/api-changelog.adoc +++ b/modules/ROOT/pages/api-changelog.adoc @@ -8,12 +8,128 @@ This changelog lists only the changes introduced in the Visual Embed SDK. For information about new features and enhancements available for embedded analytics, see xref:whats-new.adoc[What's New]. +== Version 1.46.x, March 2026 + +[width="100%" cols="1,4"] +|==== +|[tag redBackground]#DEPRECATED# a| **dataPanelV2** + +The `dataPanelV2` parameter is deprecated and can no longer be used to switch between the classic and new data panel experience. By default, the new data panel v2 experience is enabled on all ThoughtSpot embedded instances. + +|[tag greenBackground]#NEW FEATURE# a| **Spotter experience** +The SDK includes the following parameters, action IDs, and events to customize the Spotter embed experience. + +Chat history sidebar customization:: + +//* `SpotterSidebarViewConfig` interface with configuration parameters for customizing the visibility and appearance of the chat history sidebar. +//* `spotterSidebarConfig` properties for customizing the appearance and available options in the chat history sidebar. +* Action IDs for customizing the visibility and status of actions in the embedded Spotter interface: +** `Action.DataModelInstructions` for the data model instructions icon. +** `Action.SpotterSidebarHeader` for the chat history sidebar header +** `Action.SpotterSidebarFooter` for the chat history sidebar footer +** `Action.SpotterSidebarToggle` for the chat history toggle that expands or collapses the sidebar. +** `Action.SpotterNewChat` for the new chat icon in the chat history sidebar. +** `Action.SpotterPastChatBanner` for the banner in the chat history sidebar. +** `Action.SpotterChatMenu` for the chat menu component in the chat history sidebar. +** `Action.SpotterChatRename` for **Rename** action in the chat menu of a saved chat. +** `Action.SpotterChatDelete` for **Delete** action in the chat menu of a saved chat. +//** `Action.SpotterDocs` for best practices documentation icon in the chat history sidebar. + +Events:: +* `HostEvent.DataModelInstructions` + +Opens the Data Model instructions modal. +* `EmbedEvent.DataModelInstructions` + +Is emitted when a user clicks the Data Model instructions icon in the Spotter interface. +* `EmbedEvent.SpotterConversationRenamed` + +Is emitted when a user renames a saved chat. +* `EmbedEvent.SpotterConversationDeleted` + +Is emitted when a saved chat is deleted. +* `EmbedEvent.SpotterConversationSelected` + +Is emitted when a saved chat is selected in the chat history sidebar. + +|[tag greenBackground]#NEW FEATURE# a| **Page context settings for host events** +The Visual Embed SDK includes the `getCurrentContext()` function to fetch the current context and route host events to a specific xref:ContextType.adoc[context type] in the embedded view. +For more information, see xref:events-context-aware-routing.adoc[Host events in multi-modal contexts]. + + +|[tag greenBackground]#NEW FEATURE# | `enableLinkOverridesV2` + + +Use this enhanced configuration to override ThoughtSpot URLs on hover or when opening in a new tab. This is recommended over the earlier `linkOverride` flag for a better user experience. + +|[tag greenBackground]#NEW FEATURE# a| **Liveboard experience enhancements** + +* The `isLiveboardXLSXCSVDownloadEnabled` attribute adds XLSX and CSV to the available Liveboard download formats. +* The `isGranularXLSXCSVSchedulesEnabled` attribute allows you to include the entire Liveboard, specific visualizations, or only tables and pivot tables in the XLSX and CSV schedules. +|==== + +== Version 1.45.0, February 2026 + +[width="100%" cols="1,4"] +|==== +|[tag greenBackground]#NEW FEATURE# a| **Spotter enhancements** + +You can now embed the Spotter 3 experience in your application and use features such as Auto mode for automatic data model selection, chat history, and a new chat prompt interface. + +* To enable the new chat prompt interface, set `updatedSpotterChatPrompt` to `true`. +* To use Auto mode, set the `worksheetId` to `auto_mode`. +* To enable Chat history, set `enablePastConversationsSidebar` to `true`. + +For more information, see xref:embed-spotter.adoc[Embedding Spotter] and xref:embed-ai-analytics.adoc#_feature_status_and_availability_in_embed_mode[Features available with Spotter 3 experience]. + +Events:: + +* `EmbedEvent.AddToCoaching` for the *Add to coaching* workflow in a Spotter conversation session +* `HostEvent.AddToCoaching` to trigger the *Add to coaching* action in a Spotter conversation session. +* `HostEvent.StartNewSpotterConversation` to trigger the action to start a new chat session with Spotter. + +[NOTE] +==== +On Spotter embed deployments running version 26.2.0.cl or later, the *Add to Coaching* feature is enabled by default. To disable or hide the **Add to Coaching** button, use the xref:Action.adoc#_inconversationtraining[InConversationTraining] action ID. +==== + +|[tag greenBackground]#NEW FEATURE# a| **Liveboard experience enhancements** + + +Styling and grouping:: + +* The `isLiveboardStylingAndGrouping` attribute, used to enable the Liveboard styling and grouping feature, is now replaced with `isLiveboardMasterpiecesEnabled`. While your existing configuration with the deprecated `isLiveboardStylingAndGrouping` attribute continues to work, we recommend switching to the new configuration setting. +* The following action IDs are now available to show, disable, or hide the grouping menu actions on a Liveboard: +** `Action.MoveToGroup` for the **Move to Group** menu action. +** `Action.MoveOutOfGroup` for the **Move out of Group** menu action. +** `Action.CreateGroup` for the *Create Group* menu action. +** `Action.UngroupLiveboardGroup` for the **Ungroup Liveboard Group** menu action. + +Filter chip masking:: +The `showMaskedFilterChip` boolean parameter is now available to control the visibility of masked filter chips on a Liveboard. When set to `true`, if a Liveboard is shared with a user who has restricted access due to column-level security, the filter chip corresponding to those inaccessible columns will be displayed as masked to that user. When set to `false`, the filter chip for inaccessible columns will not be visible to the user. ++ +For more information, see link:https://docs.thoughtspot.com/cloud/latest/security-data-object#csr-liveboard[Column security rules on Liveboards]. ++ +The `showMaskedFilterChip` setting is also available in full application embedding. + +|[tag greenBackground]#NEW FEATURE# a| **Publishing objects** + +The following action IDs are available for the data publishing menu actions in the *Data workspace* page: + +* `Action.Publish` for *Publish* +* `Action.ManagePublishing` for *Manage publishing* +* `Action.Unpublish` for *Unpublish* +* `Action.Parameterize` for *Parameterize* +|[tag greenBackground]#NEW FEATURE# a| **Error handling improvements** + +To handle errors in the embedding workflows, the SDK includes the following features: + +* `ErrorDetailsTypes` enum for categorizing error types, such as `API`, `VALIDATION_ERROR`, and `NETWORK`. +* `EmbedErrorCodes` enum with specific error codes for programmatic error handling. +* `EmbedErrorDetailsEvent` interface for structured error event handling. + +For more information, see link:https://developers.thoughtspot.com/docs/Enumeration_EmbedErrorCodes[EmbedErrorCodes] and link:https://developers.thoughtspot.com/docs/Enumeration_ErrorDetailsTypes[ErrorDetailsTypes]. +|==== + == Version 1.44.x, January 2026 [width="100%" cols="1,4"] |==== -|[tag redBackground]#DEPRECATED# | ** Use `minimumHeight` instead of `defaultHeight` ** + +|[tag redBackground]#DEPRECATED# | **Use `minimumHeight` instead of `defaultHeight`** + The `defaultHeight` parameter is deprecated in Visual Embed SDK v1.44.2 and later. To set the minimum height of the embed container for ThoughtSpot components such as a Liveboard, use the `minimumHeight` attribute instead. @@ -28,19 +144,20 @@ Allows configuring which API calls to intercept. * `interceptTimeout` + Sets the timeout duration for handling interception. * `isOnBeforeGetVizDataInterceptEnabled` + -When set to true, it enables the use of `EmbedEvent.OnBeforeGetVizDataIntercept` event to emit and intercept search execution calls initiated by the users and implement custom logic or workflow to allow or restrict search execution. +When set to true, it enables use of `EmbedEvent.OnBeforeGetVizDataIntercept` to emit and intercept search execution calls initiated by users and implement custom logic or workflows to allow or restrict search execution. * `EmbedEvent.ApiIntercept` + Emits when an API call matching the conditions defined in `interceptUrls` is detected. For more information, see xref:api-intercept.adoc[Intercept API calls and search requests]. |==== + == Version 1.43.0, November 2025 [width="100%" cols="1,4"] |==== |[tag greenBackground]#NEW FEATURE# a| *Code-based custom actions* -The following enumerations are available for code based custom actions: +The following enumerations are available for code-based custom actions: * `CustomActionTarget` + To define the target object for the custom action, such as on a Liveboard, visualization, Answer, or in Spotter. diff --git a/modules/ROOT/pages/api-intercept.adoc b/modules/ROOT/pages/api-intercept.adoc index a3ba7e5e5..85153b063 100644 --- a/modules/ROOT/pages/api-intercept.adoc +++ b/modules/ROOT/pages/api-intercept.adoc @@ -11,8 +11,8 @@ Developers can intercept data fetch and other API requests initiated by the embe * Intercept data fetch requests: + To enable interception of search execution requests by search embed or full application embed, use the `isOnBeforeGetVizDataInterceptEnabled` attribute. When enabled, you can implement custom logic using the `OnBeforeGetVizDataIntercept` embed event, allow or block search requests, and show custom messages to users. -* Intercept a specific API call or all requests: + -If you want to intercept other API calls initiated by the embedded application, define the URLs that you want to intercept in the `interceptUrls` attribute and handle interception using the `ApiIntercept` embed event. +* Intercept a specific API call or all API requests: + +If you want to intercept other API calls initiated by the embedded application, define the requests that you want to intercept in the `interceptUrls` attribute and handle interception using the `ApiIntercept` embed event. Developers can use these interception features for: @@ -34,7 +34,7 @@ const embed = new LiveboardEmbed('#embed', { }); ---- -When enabled, you can intercept and control search execution and data fetch requests, and implement a custom logic to trigger a response when the `EmbedEvent.OnBeforeGetVizDataIntercept` event is emitted. +When enabled, you can intercept and control search execution and data fetch requests, and implement custom logic to trigger a response when the `EmbedEvent.OnBeforeGetVizDataIntercept` event is emitted. The following example blocks the search request and returns a custom error message. @@ -76,42 +76,28 @@ embed.on(EmbedEvent.OnBeforeGetVizDataIntercept, }) ---- -== Intercept specific URLs or all API calls +== Intercept specific requests or all API calls The API intercept feature lets you intercept API calls made by the embedded application, modify or block requests, and provide custom responses before they are sent to the backend. -//// -=== Enable API interception - -To enable this feature on your embed, you must set the `enableApiIntercept` flag to `true` in the SDK. - -[source,JavaScript] ----- -const embed = new LiveboardEmbed('#embed', { - //...viewConfig, - enableApiIntercept: true, - //... -}); ----- -//// - -To intercept API requests from specific URLs, define the URLs in the `interceptUrls` array: - -Valid values for `interceptUrls` are: +To intercept API requests from specific URLs, specify one of the following values in the `interceptUrls` array: ** `ALL` - Allows intercepting all API requests + ** `AnswerData` - Allows intercepting APIs that fetch data for a search query or visualization. + -** `LiveboardData` - Allows intercepting APIs requesting data for the embedded Liveboard. +** `LiveboardData` - Allows intercepting APIs requesting data for an embedded Liveboard. +//// You can also set a specific URL that you want to intercept by specifying the array in the following format: `interceptUrls: [Type.AnswerData, '{URL-to-intercept}']` +//// [NOTE] ==== -You must specify at least one API type or URL in the array for interception to be effective. If `interceptUrls` is set as an empty array, no URLs will be intercepted. +You must specify at least one API type in the array for interception to be effective. If `interceptUrls` is set as an empty array, no API requests will be intercepted. ==== + === Intercept timeout threshold To set a threshold for the interception handling, configure the `interceptTimeout` value in milliseconds. The default value is 30000. If the interception is not handled within the configured threshold, the API returns an error. diff --git a/modules/ROOT/pages/common/nav.adoc b/modules/ROOT/pages/common/nav.adoc index 3489b7ec9..b3bd8d0ee 100644 --- a/modules/ROOT/pages/common/nav.adoc +++ b/modules/ROOT/pages/common/nav.adoc @@ -63,7 +63,7 @@ **** link:{{navprefix}}/embed-liveboard[Embed a Liveboard] **** link:{{navprefix}}/embed-a-viz[Embed a visualization] *** link:{{navprefix}}/embed-ai-search-analytics[Embed AI Search and Analytics] -**** link:{{navprefix}}/embed-spotter[Embed Spotter] +**** link:{{navprefix}}/embed-spotter[Embed Spotter experience] **** link:{{navprefix}}/embed-spotter-agent[Embed Spotter Agent] **** link:{{navprefix}}/embed-nls[Embed Natural Language Search (legacy interface)] *** link:{{navprefix}}/full-embed[Embed full application] @@ -215,19 +215,28 @@ include::generated/typedoc/CustomSideNav.adoc[] *** link:{{navprefix}}/webhooks-kpi[Webhook for KPI alerts] *** link:{{navprefix}}/webhooks-lb-schedule[Webhook for Liveboard schedule events ^Beta^] +* MCP Servers and Tools +** link:{{navprefix}}/SpotterCode[SpotterCode for IDEs] +*** link:{{navprefix}}/integrate-SpotterCode[Integrating SpotterCode] +*** link:{{navprefix}}/spottercode-prompting-guide[SpotterCode prompting guide] +** link:{{navprefix}}/ai-analytics-integration[ThoughtSpot AI analytics integration] +*** link:{{navprefix}}/mcp-integration[ThoughtSpot MCP server] +*** link:{{navprefix}}/connect-mcp-server-to-clients[Connecting MCP Server to MCP clients] +*** link:{{navprefix}}/custom-chatbot-integration-mcp[Integrating MCP Server in a custom application or chatbot] + * link:{{navprefix}}/development-and-deployment[Deployment and integration] ** link:{{navprefix}}/development-and-deployment[Development and deployment] *** link:{{navprefix}}/thoughtspot-objects[ThoughtSpot objects overview] -*** link:{{navprefix}}/variables[Custom variables ^Beta^] +*** link:{{navprefix}}/variables[Custom variables] *** link:{{navprefix}}/git-integration[Deploy with Git] **** link:{{navprefix}}/git-configuration[Configure Git integration] **** link:{{navprefix}}/git-api[Version Control REST APIs] **** link:{{navprefix}}/guid-mapping[GUID mapping] *** link:{{navprefix}}/deploy-with-tml-apis[Deploy with TML APIs] **** link:{{navprefix}}/modify-tml[TML modification] -*** link:{{navprefix}}/publish-data-overview[Publish content to Orgs ^Beta^] -**** link:{{navprefix}}/parameterze-metdata[Parameterize metadata ^Beta^] -**** link:{{navprefix}}/publish-to-orgs[Publish objects to Orgs ^Beta^] +*** link:{{navprefix}}/publish-data-overview[Publish content to Orgs] +**** link:{{navprefix}}/parameterze-metdata[Parameterize metadata] +**** link:{{navprefix}}/publish-to-orgs[Publish objects to Orgs] ** link:{{navprefix}}/multi-tenancy[Multi-tenancy] *** link:{{navprefix}}/orgs[Multi-tenancy with Orgs] @@ -235,10 +244,10 @@ include::generated/typedoc/CustomSideNav.adoc[] *** link:{{navprefix}}/single-tenant-data-models[Single-tenant data models with Orgs] *** link:{{navprefix}}/orgs-api-op[Org administration] ** link:{{navprefix}}/tse-cluster[Cluster maintenance and upgrade] + * Integration with external tools ** link:{{navprefix}}/external-tool-script-integration[External tools and scripts] ** link:{{navprefix}}/pendo-integration[Pendo integration with embed] -** link:{{navprefix}}/mcp-integration[MCP server integration] ** link:{{navprefix}}/sf-integration[Integration with Salesforce] ** link:{{navprefix}}/vercel-integration[Vercel integration] * Additional references diff --git a/modules/ROOT/pages/customize-css-styles.adoc b/modules/ROOT/pages/customize-css-styles.adoc index f2f06e780..523961072 100644 --- a/modules/ROOT/pages/customize-css-styles.adoc +++ b/modules/ROOT/pages/customize-css-styles.adoc @@ -176,6 +176,11 @@ Use the following variables to customize the Liveboard page elements. |`--ts-var-liveboard-edit-bar-background`| Background color of the edit panel on the Liveboard. The edit panel is displayed when the Liveboard is in edit mode. |`--ts-var-liveboard-cross-filter-layout-background`| Background color of the cross-filter layout. |`--ts-var-liveboard-layout-background`| Background color of the Liveboard. +|`--ts-var-liveboard-tile-border-radius`| Border radius, which is the roundness of the corners of the tiles in a ThoughtSpot Liveboard. It does not apply to the Liveboard header. +|`--ts-var-parameter-chip-text-color`| Font color of the text on the parameter chips in the Liveboard. +|`--ts-var-liveboard-header-font-color`| Font color of the text on the Liveboard header. +|`--ts-var-liveboard-notetitle-heading-font-color`| Font color of the title of the note tile on the Liveboard. +|`--ts-var-liveboard-notetitle-body-font-color`| Font color of the text of the note tile on the Liveboard. |====== [.bordered] @@ -189,7 +194,7 @@ Use the following variables to customize the Liveboard visualization groups and [NOTE] ==== -To enable this feature contact ThoughtSpot support and set `isLiveboardStylingAndGroupingEnabled` to `true` in the SDK . +To enable this feature contact ThoughtSpot support and set `isLiveboardMasterpiecesEnabled` to `true` in the SDK . ==== [width="100%" cols="7,7"] @@ -202,6 +207,8 @@ To enable this feature contact ThoughtSpot support and set `isLiveboardStylingAn |`--ts-var-liveboard-group-description-font-color`| Color of the group description text. |`--ts-var-liveboard-group-tile-title-font-color`| Color of the title of the vizualizations in the group. |`--ts-var-liveboard-group-tile-description-font-color`| Color of the description of the vizualizations in the group. +|`--ts-var-liveboard-tile-border-color`| Border color of the tiles in the Liveboard. +|`--ts-var-liveboard-tile-background`| Background color of the tiles in the Liveboard. |====== [.bordered] @@ -589,3 +596,4 @@ ThoughtSpot provides a default CSS file containing the most common variables and == Additional resources * link:https://github.com/thoughtspot/custom-css-demo/blob/main/css-variables.css[Custom CSS demo GitHub Repo, window=_blank] + diff --git a/modules/ROOT/pages/customize-homepage-full-embed.adoc b/modules/ROOT/pages/customize-homepage-full-embed.adoc index e97bdff66..20f9de70e 100644 --- a/modules/ROOT/pages/customize-homepage-full-embed.adoc +++ b/modules/ROOT/pages/customize-homepage-full-embed.adoc @@ -27,9 +27,22 @@ Enables the basic modular home page experience with customizable components. After migrating from V2 to V3 experience, the home page experience shows the following changes: -* The **Watchlist** module is vertically arranged, includes menu actions to remove the KPI charts from the watchlist and create alerts, and allows drag-and-drop reordering of charts. +* The charts in the **Watchlist** module are arranged horizontally. Each chart includes menu actions to remove the KPI charts from the watchlist and create alerts, and allows drag-and-drop reordering. ++ +[.bordered] +[.widthAuto] +image::./images/watchlistv3andv2.png[V2 and V3 Watchlist module] * The **Trending** module displays separate lists for Liveboards and Answers objects. Both these lists show the objects trending for the last 15 days, or based on the overall views, or both. -* The **Favorites** and **Learning** modules have enhanced visual styles and improved look and feel. ++ +[.bordered] +[.widthAuto] +image::./images/trendingv2andv3.png[V2 and V3 Trending module] +* The **Favorites** module can be accessed from the left navigation panel. ++ +[.bordered] +[.widthAuto] +image::./images/favoritesV3.png[V2 and V3 Trending module, scaledwidth=50%] +* Style and CSS improvements to the **Learning** module. In both V2 and V3, the SDK allows customization to include or exclude modules, change their order, and adjust the overall layout. diff --git a/modules/ROOT/pages/customize-icons.adoc b/modules/ROOT/pages/customize-icons.adoc index f0d6b7ba5..883c7363b 100644 --- a/modules/ROOT/pages/customize-icons.adoc +++ b/modules/ROOT/pages/customize-icons.adoc @@ -6,7 +6,7 @@ :page-pageid: customize-icons :page-description: Customize icons displayed on the ThoughtSpot application interface -You can customize the icons on a ThoughtSpot page using an icon sprite SVG file and load it from a Web server or CDN. +You can customize icons in the ThoughtSpot interface by using an SVG sprite file loaded from a web server or CDN. == Before you begin @@ -15,20 +15,18 @@ You can customize the icons on a ThoughtSpot page using an icon sprite SVG file . On your ThoughtSpot instance, right-click on the icon and select *Inspect*. . Inspect the `` element. -. Inside should be a `` element, like: `` +. The `` element should include a `` element, for example: `` . Copy the icon ID, which is the portion after the `#` within the `xlink:href=` property. + [.widthAuto] [.bordered] image::./images/locate-icon-customization.png[Locate icon ID] -The most common icon ID to override is `rd-icon-spotter`, the Spotter image, but any SVG icon can be identified and an override supplied in the file. +=== Update allowlists on the Security Settings page -=== Update allowlists in Security Settings page +For ease of testing, the domain `https://cdn.jsdelivr.net/` is already allowlisted on the ThoughtSpot link:https://try-everywhere.thoughtspot.cloud/v2/#/everywhere/playground/search[public Playground] and trial sites. -For ease of testing, the domain `https://cdn.jsdelivr.net/` is already whitelisted on the ThoughtSpot link:https://try-everywhere.thoughtspot.cloud/v2/#/everywhere/playground/search[public Playground] and trial sites. - -If you want to enable the use of any existing examples on your own instance, or any file from GitHub, add the `https://cdn.jsdelivr.net/` domain to the SVG hosting domain to the following allowlists on the *Develop* > *Security Settings* page: +If you want to use the examples on your own instance, add the `https://cdn.jsdelivr.net/` domain to the following allowlists on the *Develop* > *Security Settings* page: ** xref:security-settings.adoc#csp-connect-src[CSP connect-src domains allowlist] ** xref:security-settings.adoc#csp-trusted-domain[CSP img-src domains allowlist] @@ -37,7 +35,7 @@ You can add any other domains where you host the SVG override files to the same === Test an override file -The Developer Embed Playground allows you to xref:customize-icons.adoc#tryItOut[try out any override] from an allowlisted origin. +The Developer Embed Playground lets you xref:customize-icons.adoc#tryItOut[try any override] from an allowlisted origin. == Create an icon override The basic structure of an icon override file is shown in the following snippet: @@ -58,9 +56,9 @@ The `` portion within the `` tags is the definition of the actua You are defining a small icon, so it should fit within a square boundary and have a single solid color. -There are many simple SVG icon examples available online, for example, the link:https://www.svgviewer.dev/[SVG viewer site, window=_blank]. +There are many simple SVG icon examples available online, for example, link:https://www.svgviewer.dev/[SVG Viewer^]. -You only need to copy the `` tags from your example SVG within the ` ` tags. +You only need to copy the `` tags from your source SVG into the `` tags. You can declare multiple `` tags within one SVG file if you are substituting a number of icons. @@ -68,9 +66,9 @@ You can declare multiple `` tags within one SVG file if you are substitu The link:https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox[viewBox property^] is in the order `min-x`, `min-y`, `width`, and `height`. -The first two properties should be `0 0` while the second should match any `width` and `height` properties from the source of your SVG paths. +The first two values should be `0 0`, and the last two should match the source SVG `width` and `height` values for your paths. -The `width` and `height` properties may be added directly in the `` tag, or as part of `viewBox` property in that tag, or perhaps in another tag above ``. Use the values from your source SVG in the `viewBox` property of the `` element within your override file. +The `width` and `height` values can appear directly on the `` element, in its `viewBox`, or in another element above ``. Use those source values in the `` element's `viewBox` in your override file. === fill property You can add the `fill` property to the `` tag to define a different fill color than the default: @@ -80,18 +78,27 @@ You can add the `fill` property to the `` tag to define a different fill ---- -== Override an icon +== Apply overrides To override an icon: . Ensure that you have xref:#identifyIconId[the ID of the icon] you want to replace. . To replace the icon with an SVG, open the icon in a web browser, click **Inspect**, and then copy the SVG code. . Create an icon sprite file with the SVG code. -. In the `` element, specify ID of the icon you want to replace. For example, `rd-icon-spotter`. -. Modify the xref:#_viewbox_property[viewBox] and xref:_fill_property[fill] properties as required. -+ -Th following code snippet shows an example of the SVG code for the icon sprite that overrides the Spotter icon: -+ -[source,HTML] +. In the `` element, specify the ID of the icon you want to replace. For example, `rd-icon-spotter`. +. Modify the xref:#_viewbox_property[viewBox] and xref:#_fill_property[fill] properties as required. +. Save the icon sprite file on a web server. +. To override icons on the ThoughtSpot page, specify the icon sprite URL in the `iconSpriteUrl` property of the `customizations` object in the Visual Embed SDK. +. Load the application page and check the icon. + + +== Icon override examples + +The most common icon ID to override is `rd-icon-spotter` (the Spotter image), but you can identify any SVG icon and provide an override in the file. + +=== Spotter icon +The following example shows the SVG elements of the icon sprite used to override the Spotter icon (`rd-icon-spotter`): + +[source,html] ---- @@ -103,81 +110,142 @@ Th following code snippet shows an example of the SVG code for the icon sprite t ---- -+ -The following example overrides the chart icon (`rd-icon-chart`) on the *Answers* page. -+ -[source,HTML] +The following code snippet uses the `alternate-spotter-icon.svg` containing the overrides for the Spotter icon (`rd-icon-spotter`): + +[source,javascript] ---- - - - - - - - - + init({ + //... + customizations: { + // Use the SVG sprite file containing icon overrides for the Spotter icon, "rd-icon-spotter". + iconSpriteUrl: "https://cdn.jsdelivr.net/gh/thoughtspot/custom-css-demo/alternate-spotter-icon.svg" // Replace with the URL where your SVG sprite file is hosted + } + }); ---- -. To override multiple icons at once, you can use the following format: -+ -[source,HTML] +The following figures show the icons before and after the override. + +[width="100%" cols="6,6"] +|====== +a|**Before** + +[.bordered] +image::./images/spotter-icon.png[Spotter embed] +a|**After** + +[.bordered] +image::./images/spotter-icon-customization.png[Custom Spotter icon] +|====== + +=== Column chart icon +The column chart icon appears in the chart/table toggle and in the chart selection panel on Answer pages. The icon ID is `rd-icon-chart-column`. + +The following example shows the SVG for the icon override: + +[source,html] ---- - - - - - + + + + + + ---- -+ -. Save the icon sprite file on a Web server. -. To override the icons on the ThoughtSpot page, specify the icon sprite URL in the `iconSpriteURL` property of the `customizations` object in Visual Embed SDK. -+ -For example, the following code snippets use the link:https://github.com/thoughtspot/custom-css-demo/blob/main/icon-override1.svg[icon-override1.svg] and link:https://github.com/thoughtspot/custom-css-demo/blob/main/alternate-spotter-icon.svg[alternate-spotter-icon.svg] files in the link:https://github.com/thoughtspot/custom-css-demo[Custom CSS demo GitHub Repo, window=_blank] to override the chart (`rd-icon-chart`) and Spotter (`rd-icon-spotter`) icons respectively: +The following example uses the `rd-icon-chart-column.svg` SVG sprite file containing the overrides for the column chart icon: -+ -[source,JavaScript] +[source,javascript] ---- init({ //... customizations: { - // rd-icon-chart - iconSpriteUrl: "https://cdn.jsdelivr.net/gh/thoughtspot/custom-css-demo/icon-override1.svg" + // Use the SVG sprite file containing icon overrides for the column chart icon, "rd-icon-chart-column". + iconSpriteUrl: "https://cdn.jsdelivr.net/gh/thoughtspot/developer-docs/static/svgs/rd-icon-chart-column.svg" // Replace with the URL where your SVG sprite file is hosted } }); ---- -+ -[source,JavaScript] +The following figures show the icons before and after the override. + +[width="100%" cols="6,6"] +|====== +a|**Before** + +[.bordered] +image::./images/answer-chart-toggle.png[Column chart icon] +a|**After** + +[.bordered] +image::./images/answer-chart-toggle-custom.png[Custom column chart icon] +|====== + +=== Chart settings icon +The chart type icon appears in the settings panel of the Answer edit layout if the xref:https://docs.thoughtspot.com/cloud/latest/charts-new[new chart settings UI experience, window=_blank] is enabled on your instance. The icon ID is `rd-icon-chart-type-settings`. + +The following example shows SVG for the icon override: + +[source,html] +---- + + + + + + + +---- + +The following example uses the `rd-icon-chart-type-settings.svg` SVG sprite file containing the overrides for the chart type icon: + +[source,javascript] ---- init({ //... customizations: { - // rd-icon-spotter - iconSpriteUrl: "https://cdn.jsdelivr.net/gh/thoughtspot/custom-css-demo/alternate-spotter-icon.svg" + // Chart icon in the chart settings panel (rd-icon-chart-type-settings) + iconSpriteUrl: "https://cdn.jsdelivr.net/gh///rd-icon-chart-type-settings.svg" // Replace with the URL where your SVG sprite file is hosted } }); ---- -. Load the application page and check the icon. -+ + The following figures show the icons before and after the override. -+ -Spotter icon on the Spotter interface:: -+ + [width="100%" cols="6,6"] |====== a|**Before** + [.bordered] -image::./images/spotter-icon.png[Conversation embed] +image::./images/chart-selection-icon.png[Chart type icon] a|**After** + [.bordered] -image::./images/spotter-icon-customization.png[Spotter icon customization] +image::./images/chart-selection-icon-custom.png[Custom chart type icon] |====== -Chart icon on the Answer page:: -The chart icon is available on the Answer page, which can be viewed in full app, Search data, or Natural Language Search embed. -+ +If the xref:https://docs.thoughtspot.com/cloud/latest/charts-new[new chart settings UI experience, window=_blank] is not enabled on your instance, use the `rd-icon-chart` ID in your SVG file. + +[source,html] +---- + + + + + + + + +---- + +The following example uses the `icon-override1.svg` SVG sprite file containing the overrides for the chart icon: + +[source,javascript] +---- + init({ + //... + customizations: { + // Chart icon in the classic layout of the Answer edit panel (rd-icon-chart) + iconSpriteUrl: "https://cdn.jsdelivr.net/gh/thoughtspot/custom-css-demo/icon-override1.svg" // Replace with the URL where your SVG sprite file is hosted + } + }); +---- + +The following figures show the icons before and after the override. + [width="100%" cols="6,6"] |====== a|**Before** + @@ -188,22 +256,34 @@ a|**After** + image::./images/post-icon-override.png[After icon override] |====== +=== Multiple icon overrides using an SVG sprite file + +To override multiple icons at once, you can use the following format: + +[source,html] +---- + + + + + + + + + + + +---- + [#tryItOut] == Try it out in the Playground -The +++Visual Embed SDK Playground +++ allows you to try out the icon customization framework. +The +++Visual Embed SDK Playground+++ allows you to try out the icon customization framework. To view the code for customization: . In the Playground, select the embed type. For example, select *Search* and specify the data source. . Select the *Apply custom styles* checkbox in the Playground. + -The `customizations` code for CSS modifications appears in the code panel. -. To override the chart icon on the Answer page with `icon-override1.svg`, replace the `customization` section with the following code and click *Run*. -+ -[source,JavaScript] ----- - customizations: { - iconSpriteUrl: "https://cdn.jsdelivr.net/gh/thoughtspot/custom-css-demo/icon-override1.svg" - } ----- +The `customizations` code appears in the code panel. +. To override the chart icon on the Answer page, add the icon sprite URL in the `customizations` section and click *Run*. . To view the result, execute search tokens to create an Answer. -. Check the chart icon on the Answer page. +. Check the chart icon in the Answer layout. diff --git a/modules/ROOT/pages/data-report-v2-api.adoc b/modules/ROOT/pages/data-report-v2-api.adoc index 1e5f6a9c3..87c24235a 100644 --- a/modules/ROOT/pages/data-report-v2-api.adoc +++ b/modules/ROOT/pages/data-report-v2-api.adoc @@ -214,7 +214,7 @@ curl -X POST \ ThoughtSpot provides the following REST API v2 endpoints to fetch data: * xref:_liveboard_report_api[`POST /api/rest/2.0/report/liveboard`] + -Download a Liveboard and its visualizations in PDF or PNG file format. +Download a Liveboard and its visualizations in PDF, PNG, CSV, or XLSX file format. * xref:#_answer_report_api[`POST /api/rest/2.0/report/answer`] + Download data from a saved Answer in PDF, PNG, CSV, or XLSX file format. @@ -235,11 +235,92 @@ To download a personalized view of the Liveboard, specify the view name in the ` * Attempting to override existing filter values with runtime filters while exporting a Liveboard will result in an error. ==== -==== File Format +==== File Formats -The default `file_format` is PDF. For PDF downloads, you can specify additional parameters to customize the page orientation and include or exclude the cover page, logo, footer text, and page numbers. You can also download the report in PNG format. +The default `file_format` is *CSV*. -For PNG downloads, you can now define +[NOTE] +If you do not have .csv downloads enabled for your ThoughtSpot instance, select either `PDF` or `PNG` `file_format` to successfully download the report. Using any other format will cause the API to return an error. + + +For *CSV* downloads [earlyAccess eaBackground]#Early Access#, + +* Each visualization is exported as a separate .csv file. +* If multiple visualizations are selected, the downloaded report is a single compressed .zip file containing all .CSV files. +* It does not support any additional parameters to customize the page orientation and `include_cover_page`, `include_filter_page`, logo, footer text, and page numbers. +* Charts are exported as tabular data. Downloaded reports may include columns not seen in the visualization if they were used as tokens in the underlying search query. + +===== Sample API payload for CSV downloads + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/liveboard' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Content-Type: application/json' \ +--data-raw '{ +"metadata_identifier": "416052fd-ad22-4d48-be0a-e43b53109957", +"file_format": "CSV", +"tab_identifiers": [ +"bc6d6fb8-1e06-4617-b02f-51745e6933a6" +] +}' +---- + +For *XLSX* downloads [earlyAccess eaBackground]#Early Access#, + +* Visualization is exported as an Excel workbook (.xlsx). +* If multiple visualizations are selected, the downloaded report is a single Excel workbook (.xlsx) containing each visualization in their individual tab. +* A maximum of 255 tabs per .xlsx workbook are allowed. +* It does not support any additional parameters to customize the page orientation and `include_cover_page`, `include_filter_page`, logo, footer text, and page numbers. +* Charts are exported as tabular data. Downloaded reports may include columns not seen in the visualization if they were used as tokens in the underlying search query. +* Unlike the pivot tables that are downloaded for any pivot table Answer in the ThoughtSpot UI, pivot tables generated in .xlsx workbooks using this API endpoint are exported as their underlying raw data. The .xlsx currently does not support the pivot table format. + +===== Sample API payload for XLSX downloads + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/liveboard' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Content-Type: application/json' \ +--data-raw '{ +"metadata_identifier": "416052fd-ad22-4d48-be0a-e43b53109957", +"file_format": "XLSX", +"visualization_identifiers": [ +"254c6e30-680c-41ea-aa4d-bb059f745462" +] +}' +---- + +For *PDF* downloads, you can specify additional parameters to customize the page orientation and include or exclude the cover page, logo, footer text, and page numbers. + +===== Sample API payload for XLSX downloads + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/liveboard' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Content-Type: application/json' \ +--data-raw '{ +"metadata_identifier": "416052fd-ad22-4d48-be0a-e43b53109957", +"file_format": "PDF", +"visualization_identifiers": [ +"254c6e30-680c-41ea-aa4d-bb059f745462" +], +"pdf_options": { +"include_cover_page": true, +"include_custom_logo": true, +"include_filter_page": true, +"include_page_number": true, +"page_orientation": "LANDSCAPE", +"page_footer_text": "Sample footer text" +} +}' +---- + +For *PNG* downloads, you can now define * `image_resolution` [earlyAccess eaBackground]#Early Access# * `image_scale` [earlyAccess eaBackground]#Early Access# @@ -250,13 +331,14 @@ Contact ThoughtSpot support to enable these settings for PNG downloads on your T [IMPORTANT] ==== * If the above settings are enabled on your instance or you are using a ThoughtSpot release 10.9.0.cl or later, -** You will no longer be able to use the `include_cover_page`,`include_filter_page` within the `png_options`. +** You will no longer be able to use the `include_cover_page`, `include_filter_page` within the `png_options`. ** PNG download will support exporting only one tab at a time. If the `tab_identifier` is not specified, the first tab will be downloaded. * Due to UI limitations in the REST API Playground, you'll notice that some parameters are automatically included in the PNG options JSON. This may cause your API request to fail. As a workaround, click *View JSON* next to the `png_options`, review the parameters, remove additional parameters, and then click *Try it out*. ==== -==== Example +===== Sample API payload for PNG downloads + [source,cURL] ---- curl -X POST \ @@ -264,23 +346,25 @@ curl -X POST \ -H 'Authorization: Bearer {access-token}'\ -H 'Content-Type: application/json' \ --data-raw '{ - "metadata_identifier": "9bd202f5-d431-44bf-9a07-b4f7be372125", + "metadata_identifier": "416052fd-ad22-4d48-be0a-e43b53109957", "file_format": "PNG", - "visualization_identifiers": [ - "9bd202f5-d431-44bf-9a07-b4f7be372125", - "9bd202f5-d431-44bf-9a07-b4f7be372125", - "9bd202f5-d431-44bf-9a07-b4f7be372125" + "tab_identifiers": [ + "bc6d6fb8-1e06-4617-b02f-51745e6933a6" ], "png_options": { - "include_cover_page": true, - "include_filter_page": true + "include_cover_page": null, + "include_filter_page": null, + "personalised_view_id": null, + "image_resolution": 1920, + "image_scale": 100, + "include_header": true } }' ---- ==== Override filters -If the Liveboard has filters applied and you want to override the filters before downloading the Liveboard, you can specify the filters in the `override_filters` array. +If the Liveboard has filters applied, and you want to override the filters before downloading the Liveboard, you can specify the filters in the `override_filters` array. [source,JSON] ---- diff --git a/modules/ROOT/pages/embed-ai-analytics.adoc b/modules/ROOT/pages/embed-ai-analytics.adoc index 1641ce495..c2abb742c 100644 --- a/modules/ROOT/pages/embed-ai-analytics.adoc +++ b/modules/ROOT/pages/embed-ai-analytics.adoc @@ -4,72 +4,290 @@ :page-title: Embed AI Search and Analytics :page-pageid: embed-ai-search-analytics -:page-description: To embed ThoughtSpot Spotter and conversational analytics experience in your app, you can use the `SpotterEmbed` or `SpotterAgentEmbed` SDK library. +:page-description: To embed the ThoughtSpot Spotter and conversational analytics experience in your app, you can use the `SpotterEmbed` or `SpotterAgentEmbed` SDK components. -ThoughtSpot Spotter provides an interactive AI-powered Search and conversational analytics experience for its application users. With ThoughtSpot Spotter, users can query data in plain language, ask follow-up questions, and get insights directly from their data. ThoughtSpot also provides an agentic version of Spotter for a more advanced experience with context-based conversations and responses for deeper analysis. +Spotter provides an interactive AI-powered search and conversational analytics experience for ThoughtSpot application users. It empowers users to ask questions in natural language and analyzes data to generate business-ready insights instantly. -== Embed components -ThoughtSpot provides two distinct SDK libraries to embed Spotter capabilities in your app: +ThoughtSpot supports three experience modes: Spotter Classic, Spotter Agent (Spotter 2), and Spotter 3. Spotter 3 supports several new features, agentic analytics, and provides an enhanced user experience. + +[width="100%" cols="2,4"] +[options="header"] +|==== +|Version| Supported features +|Spotter 3 [tag purpleBackground]#Early Access# +a| Spotter 3 is the latest and most advanced version of Spotter. + +**Key features and user experience**: + +In addition to the Spotter Classic and Spotter 2 capabilities, Spotter 3 supports the following features and enhancements to improve the AI search and analytics experience: + +* Is fully data-aware and capable of understanding data models and schemas +* Supports advanced analysis +* Supports automatic discovery and selection of data models based on user prompts. +* Supports quick search and deep research modes +* Supports saving chats and accessing chat history +* Supports third-party MCP connectors + +__Available from 26.2.0.cl and later. To enable Spotter 3 on your instance, contact your ThoughtSpot administrator__. + +**When to use**: + +Use this version if you want to include advanced AI search, research, and analytics capabilities in your ThoughtSpot embedded app. + +|Spotter 2 a|Also known as *Spotter Agent*, it's the second version of Spotter with the following capabilities: + +**Key features and user experience**: + + +* Agentic AI analytics experience +* Context-aware analysis +* Why questions for in-depth analysis +* Coaching in conversations +* Data model instructions and guidance + +__Available when the Spotter 2 experience is enabled on the instance__. + +**When to use**: + +Use this version if you want to include agentic analytics and richer insights in your ThoughtSpot embedded app. + +|Spotter Classic a| An early version of Spotter. + +**Key features and user experience**: + + +* Quick search with queries in natural language format + +* Visualization generation + +__Available if the Spotter Classic version is enabled on the instance__. + +**When to use**: + +You can use this version if your ThoughtSpot embedded app needs only metadata-level insights and does not require or support agentic workflows. +|| +|==== + +== SDK libraries for embedding Spotter +ThoughtSpot provides the following Visual Embed SDK libraries for embedding Spotter capabilities in your app: * xref:embed-spotter.adoc[`SpotterEmbed`] + -To embed the full Spotter interface with a conversation panel that allows natural language queries, data source selection, and interactions with AI-generated Answers, use the `SpotterEmbed` component. -For more information, see xref:embed-spotter.adoc[Embed Spotter]. +Use this SDK component to xref:embed-spotter.adoc[embed the full Spotter experience] in your app. The features in a Spotter embed vary based on the Spotter version. + * xref:embed-spotter-agent.adoc[`SpotterAgentEmbed`] + -The Spotter Agent embedding, also known as `bodyless` embedding, allows you to integrate natural language data search and analysis into your own applications or chatbot. Unlike the standard Spotter embed, which provides a ready-made search bar and interface, the `SpotterAgentEmbed` component is designed for deeper customization, allowing full control over user experience and workflow of embedded analytics. It allows you to build your own UI or agent experience, route user questions to ThoughtSpot, and receive structured answers and visualizations. +Also known as `bodyless` embedding, `SpotterAgentEmbed` allows you to integrate Spotter capabilities into your own applications or chatbot, route user questions to ThoughtSpot, and receive structured answers and visualizations. Unlike the full Spotter experience, the "bodyless" embed includes only a prompt panel with no additional buttons or selectors. + +== Feature status and availability in embed mode + +To link:https://docs.thoughtspot.com/cloud/latest/spotter-enable[enable Spotter experience and AI features, window=_blank] on your instance, contact your ThoughtSpot administrator. + +[width="100%" cols="7,7"] +[options="header"] +|==== +|Feature |Supported version, feature availability, and SDK controls +|https://docs.thoughtspot.com/cloud/latest/spotter-getting-started#_how_to_use_spotter[Spotter search and prompt panel for conversational analytics, window=_blank] + +For quick searches with queries in natural language and for generating visualizations. + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag greenBackground tick]#✓# Spotter 2 + +[tag greenBackground tick]#✓# Spotter Classic + +**Feature status**: Generally Available (GA) on all ThoughtSpot Cloud instances. + + +**Required settings**: Spotter feature must be enabled at the instance level. + +**Embed SDK component**: If you want to embed the full Spotter experience, use `SpotterEmbed`. + +To embed only the Spotter search bar with no additional features or standard Spotter user experience, use `SpotterAgentEmbed`. + + +**Default state in embed**: Enabled by default if the ThoughtSpot instance has Spotter experience enabled. + + +|link:https://docs.thoughtspot.com/cloud/latest/spotter-localization[Localization support, window=_blank] + + +Locale settings and language support for Spotter queries and responses. + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag greenBackground tick]#✓# Spotter 2 + +[tag greenBackground tick]#✓# Spotter Classic + +**Feature status**: GA. Available on all ThoughtSpot Cloud instances with Spotter feature enabled. + + +**Embed SDK component**: Use `SpotterEmbed`. The SDK also supports configuring locale settings for `SpotterAgentEmbed`. + + +**Required settings**: Locale settings can be configured at the user level in the UI or via REST API. + +**Default state in embed**: By default, the locale settings configured at the instance level will be used. To override the locale settings in your embed, use the xref:locale-setting.adoc#_set_locale_in_the_sdk[locale property in the SDK]. + +|xref:embed-spotter.adoc#_optional_settings_for_spotter_3[New chat interface] + + +The updated chat interface that provides a more intuitive and interactive analytics experience. + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +**Feature status**: Early Access. Available by default on instances that have Spotter 3 enabled. + + +**Required settings**: Spotter 3 must be enabled at the instance level. + + +**Embed SDK component**: Use `SpotterEmbed`. + + +**Default state in embed**: Disabled by default. To enable this feature, set `updatedSpotterChatPrompt` to `true` in the SDK. + +|Thinking and reasoning UX + + +The thinking and reasoning UX in Spotter conversations shows step-by-step reasoning, planning, and analysis process as Spotter works through a complex question. + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag greenBackground tick]#✓# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + + +**Feature status**: Early Access. Enabled by default on instances with Spotter 2 or Spotter 3 enabled. +**Required settings**: Spotter 2 or Spotter 3 experience must be enabled at the instance level. + + +**Embed SDK component**: Use `SpotterEmbed`. + + +**Default state in embed**: Enabled by default if the feature is enabled at the instance level. + +|link:https://docs.thoughtspot.com/cloud/latest/spotter-coach-conversation[Spotter coaching within conversation sessions, window=_blank] + +The coaching workflow in Spotter conversations. + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag greenBackground tick]#✓# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + + +**Feature status**: GA in 26.2.0.cl and disabled by default. + +**Embed SDK component**: Use `SpotterEmbed`. + +**Required settings**: Requires Spotter 2 or Spotter 3 experience to be enabled at the instance level. +**Default state in embed**: Enabled by default in 26.2.0.cl and later versions. Developers can use the `Action.InConversationTraining` action ID to control the visibility of this feature in their embeds. + +|link:https://docs.thoughtspot.com/cloud/latest/data-model-instructions[Data model instructions, window=_blank] + + +Global rules that provide data model guidance to the Spotter system and direct how Spotter should interpret queries and construct responses for user prompts. +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag greenBackground tick]#✓# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + + +**Feature status**: GA. Enabled by default on ThoughtSpot instances with 26.2.0.cl release version or later. + +**Required settings**: Spotter 2 or Spotter 3 experience must be enabled at the instance level. + + +**Embed SDK component**: Use `SpotterEmbed` + + +**Default state in embed**: Enabled by default. + +|link:https://docs.thoughtspot.com/cloud/latest/spotter-research-mode[Deep Research and analysis mode, window=_blank] + + +Ability to autonomously perform an in-depth and multi-step analysis on a user's question. + + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +**Feature status**: GA. Enabled by default on instances with Spotter 3 enabled. + +**Required settings**: Spotter 3 experience must be enabled at the instance level. + + +**Embed SDK component**: Use `SpotterEmbed` + + +**Default state in embed**: Available by default if Spotter 3 is enabled on the instance. ThoughtSpot embedded app users can select the deep research mode in the Spotter interface. + +|link:https://docs.thoughtspot.com/cloud/latest/spotter-advanced-analysis[Advanced analysis, window=_blank] + + +Ability to function as a data-aware analyst, derive context data model, and perform complex research in Research mode for accurate analysis and deeper insights. Supports forecasting, correlation, and query-on-query analysis. + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +**Feature status**: Early Access. Enabled by default if Spotter 3 is enabled on the instance. + +**Required settings**: Spotter 3 experience must be enabled on the instance. + +**Embed SDK component**: Use `SpotterEmbed`. + + +**Default state in embed**: Available by default if Spotter 3 experience is enabled on the instance. + +|link:https://docs.thoughtspot.com/cloud/latest/spotter-why[Why questions, window=_blank] + +Ability to ask questions to automatically generate explanations and identify key drivers behind changes in a metric using change analysis and AI-generated summaries. + +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag greenBackground tick]#✓# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +**Feature status**: Early Access. Disabled by default. + +**Required settings**: Spotter 2 or Spotter 3 experience must be enabled on the instance. + +**Embed SDK component**: Use `SpotterEmbed` + + +**Default state in embed mode**: Disabled by default. If the feature is enabled on the instance, it will be available in the embed mode. + + +|link:https://docs.thoughtspot.com/cloud/latest/spotter-auto-mode[Auto mode, window=_blank] + +Automatic data source discovery and model selection by Spotter. + +|**Supported Spotter version**: + + +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic + +**Feature status**: Early Access. Disabled by default. + +**Required settings**: Spotter 3 experience and the *Auto-mode* feature must be enabled at the instance level. + + +**Embed SDK component**: Use `SpotterEmbed`. + + +**Default state in embed**: Disabled by default. To enable this feature, set the `worksheetId` attribute to `auto_mode` in the SDK. When the Auto mode is enabled, the *Preview data* option in the conversation panel is hidden. + +|link:https://docs.thoughtspot.com/cloud/latest/spotter-conversation-history[Chat history, window=_blank] + + +Saves Spotter conversations and allows reloading chat history with past conversations. -[NOTE] -==== -* The `ConversationEmbed` and `BodylessConversation` components are deprecated and replaced with `SpotterEmbed` and `SpotterAgentEmbed` respectively in Visual Embed SDK v1.38.0 and later. -* If you are embedding the full ThoughtSpot experience in your app via `AppEmbed`, you must set the search bar mode on the home page to `aiAnswer` to view Spotter components. For more information, see xref:full-app-customize.adoc#_include_spotter_interface[Customize full application embedding]. -==== +|**Supported Spotter version**: + +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic -== Spotter embed and Spotted Agent embed comparison +**Feature status**: Early Access. Enabled by default if Spotter 3 is enabled on the instance. -[width="100%" cols="7,5,5"] -[options='header'] +**Required settings**: Spotter 3 experience and the *Chat history* feature must be enabled at the instance level. + -|===== -| -| Spotter embed -| Spotter Agent embed (Bodyless/Agent) +**Embed SDK component**: Use `SpotterEmbed`. + -|Use case -|Use this method to integrate the built-in AI search and conversation analytics interface in your app. -|Use this method to embed Spotter Search capabilities in your chatbot, virtual agent or an app with your own interface elements and user-experience. +**Default state in embed**: Disabled by default. To enable this feature in the embed mode, set `enablePastConversationsSidebar` to `true` in the SDK. -| Embedding component -| Use `SpotterEmbed` component in the Visual Embed SDK library -| Use `SpotterAgentEmbed` component in the Visual Embed SDK library +|link:https://docs.thoughtspot.com/cloud/latest/spotter-connectors-use[Third-party connectors and MCP tools, window=_blank] + +Third-party tools and services that Spotter can connect to and interact with via Model Context Protocol (MCP). -| Data context -a| * Supported data object is Model + - * Allows data source selection -a| * Supported data object is Model - * Data source is passed in the code. No explicit selection is allowed unless the embedding application UI allows it. +|**Supported Spotter version**: + -| Customization -| The SDK provides several props, object properties, CSS and text customization options for branding and styling, event handlers for host and embed app interaction, and menu action configuration -| The SDK provides limited customization options as the UI/UX controlled by host application. +[tag greenBackground tick]#✓# Spotter 3 + +[tag redBackground tick]#x# Spotter 2 + +[tag redBackground tick]#x# Spotter Classic -| Sample Questions -| The SDK provides the ability to show or hide sample questions via `hideSampleQuestions`. -| Not applicable -|===== +**Feature status**: Early Access. Enabled by default if Spotter 3 is enabled on the instance. -== Customization options in the SDK +**Required settings**: Spotter 3 experience and Spotter connectors feature must be enabled on the instance. For connectors to be available in the embed mode, ThoughtSpot administrators must configure Spotter connectors. -Visual Embed SDK provides several configuration settings and controls for customizing Spotter embed view: +**Embed SDK component**: Use `SpotterEmbed`. + -* Configuration properties that enable or disable features. -For more information, see xref:SpotterEmbedViewConfig.adoc[SpotterEmbedViewConfig] and xref:SpotterAgentEmbedViewConfig.adoc[SpotterAgentEmbedConfig] -* The action customization framework to show or hide actions in the embedded view + -For more information, see xref:Action.adoc[Action] and xref:embed-action-ref.adoc[Action IDs in the SDK] -* Event handlers for host and embed app interaction + -For more information, see xref:EmbedEvent.adoc[Embed events], xref:HostEvent.adoc[Host events], and xref:embed-events.adoc[Events and app interactions] -* Style customization framework for customizing styles, text strings, and icons + -See xref:css-customization.adoc[style customization framework] +**Default state in embed**: Visible by default if the `updatedSpotterChatPrompt` attribute is set to `true`. We do not recommend using this feature in your production environment. You can hide this option using the CSS selectors. For more information, see xref:embed-spotter.adoc#_mcp_connectors_and_resource_selection_icon[MCP connectors in Spotter embedding]. +|| +|==== +== Related information -== Additional resources -* link:https://docs.thoughtspot.com/cloud/latest/spotter[Spotter Documentation] -* link:https://docs.thoughtspot.com/cloud/latest/spotter-agent[Spotter Agent Documentation] +* For more information about Spotter versions and capabilities, see link:https://docs.thoughtspot.com/cloud/latest/spotter[ThoughtSpot Product Documentation, window=_blank]. +* For information about how to embed Spotter and customize the Spotter interface, see xref:embed-spotter.adoc[Embed Spotter] and xref:SpotterEmbedViewConfig.adoc[SpotterEmbedViewConfig]. +* For information about bodyless embedding, see xref:embed-spotter-agent.adoc[Embed Spotter Agent] and xref:SpotterAgentEmbedViewConfig.adoc[SpotterAgentEmbedConfig]. +* For information about the action customization framework to show or hide actions in the embedded view, see xref:Action.adoc[Action] and xref:embed-action-ref.adoc[Action IDs in the SDK]. +* For information about event hooks, see xref:embed-events.adoc[Events and app interactions], xref:EmbedEvent.adoc[Embed events], and xref:HostEvent.adoc[Host events]. +* For information about customization style and CSS variables, see xref:css-customization.adoc[style customization framework]. diff --git a/modules/ROOT/pages/embed-pinboard.adoc b/modules/ROOT/pages/embed-pinboard.adoc index 455283606..452730976 100644 --- a/modules/ROOT/pages/embed-pinboard.adoc +++ b/modules/ROOT/pages/embed-pinboard.adoc @@ -503,7 +503,8 @@ liveboardEmbed.trigger(HostEvent.UpdateFilters, { === Liveboard grouping and styling [earlyAccess eaBackground]#Early Access# You can now create a visual group of Answers and note tiles together in the Liveboard. You can select multiple Answers and notes in the Liveboard editor. You can also style parts of the Liveboard, groups and Answers with the new styling panel. -To enable this feature, set `isLiveboardStylingAndGroupingEnabled` to `true`. It is important to note the following changes which happen in the Liveboard UI and layout when this feature is active. +To enable this feature, set `isLiveboardMasterpiecesEnabled` to `true`. +It is important to note the following changes which happen in the Liveboard UI and layout when this feature is active. * All tiles on the Liveboard will now have a default border and an increased border-radius, resulting in more pronounced curved corners. This is part of the broader visualization tile customization options done to enhance the visual appearance of charts and tables. * For Note tiles, the default scrollbar is now hidden for long content. Users must scroll within the tile area itself, and if the tile is not sized appropriately for its content, it may appear clipped due to the new container styles. This change emphasizes the importance of properly sizing Note tiles to avoid content being visually cut off. @@ -515,7 +516,7 @@ To enable this feature, set `isLiveboardStylingAndGroupingEnabled` to `true`. It image::./images/lb-grp-styling-error.png[Liveboard with groups styling error] -- + -To embed a Liveboard that uses Groups, you must set `isLiveboardStylingAndGroupingEnabled` to `true` in your embedding configuration. This is required for compatibility with the new grouping and styling features; otherwise, the embedded Liveboard will not render correctly. +To embed a Liveboard that uses Groups, you must set `isLiveboardMasterpiecesEnabled` to `true` in your embedding configuration. This is required for compatibility with the new grouping and styling features; otherwise, the embedded Liveboard will not render correctly. For more information, see link:https://docs.thoughtspot.com/cloud/latest/liveboard-grouping-styling[Liveboard grouping and styling, window=_blank]. diff --git a/modules/ROOT/pages/embed-spotter-agent.adoc b/modules/ROOT/pages/embed-spotter-agent.adoc index d8d53c6eb..3dbd95cf8 100644 --- a/modules/ROOT/pages/embed-spotter-agent.adoc +++ b/modules/ROOT/pages/embed-spotter-agent.adoc @@ -18,7 +18,7 @@ Before you begin, check the following: == Import the SDK package -Import the `SpotterEmbed` SDK library to your application environment: +Import the `SpotterAgentEmbed` SDK library to your application environment: **npm** [source,JavaScript] diff --git a/modules/ROOT/pages/embed-spotter.adoc b/modules/ROOT/pages/embed-spotter.adoc index 14cc8120b..4a17680a9 100644 --- a/modules/ROOT/pages/embed-spotter.adoc +++ b/modules/ROOT/pages/embed-spotter.adoc @@ -1,23 +1,22 @@ -= Embed Spotter += Embed Spotter experience :toc: true -:toclevels: 3 +:toclevels: 2 :page-title: Embed Spotter :page-pageid: embed-spotter -:page-description: You can use the SpotterEmbed SDK library to embed Conversational analytics experience in your application. +:page-description: You can use the SpotterEmbed SDK library to embed conversational analytics experience in your application. -To embed the full Spotter interface with a conversation panel that allows natural language queries, data source selection, and interactions with AI generated Answers, use the `SpotterEmbed` component. +You can embed the full Spotter experience in your applications using the `SpotterEmbed` component in the Visual Embed SDK. Using the customization settings available in the SDK for each Spotter version, you can configure the Spotter interface to suit the needs of your embedding application. == Before you begin -Before you begin, check the following: +To embed Spotter, you need the following access and setup: -* You have a ThoughtSpot instance with Spotter and Spotter Agent enabled. -* Your host application domain is added to ThoughtSpot CSP and CORS allowlists. -* You have access to the latest version of the Visual Embed SDK or at least v1.33.1. +* Access to a ThoughtSpot instance with the Spotter feature. If you want a specific version of Spotter enabled, work with your ThoughtSpot administrator to enable the xref:embed-ai-analytics.adoc#_feature_status_and_availability_in_embed_mode[required features and settings] on your instance. +* Your host application domain is added to xref:security-settings.adoc[ThoughtSpot CSP and CORS allowlists]. +* Your application project has access to the xref:api-changelog.adoc[latest version of the Visual Embed SDK]. == Import the SDK package - Import the `SpotterEmbed` SDK library to your application environment: **npm** @@ -28,6 +27,8 @@ import { AuthType, init, prefetch, + EmbedEvent, + HostEvent } from '@thoughtspot/visual-embed-sdk'; ---- @@ -41,6 +42,8 @@ from '@thoughtspot/visual-embed-sdk'; AuthType, init, prefetch, + EmbedEvent, + HostEvent } from 'https://cdn.jsdelivr.net/npm/@thoughtspot/visual-embed-sdk/dist/index.js'; ---- @@ -50,154 +53,200 @@ from 'https://cdn.jsdelivr.net/npm/@thoughtspot/visual-embed-sdk/dist/index.js'; To initialize the SDK, the following information is required: * `thoughtSpotHost` + -The hostname of your ThoughtSpot application instance. See xref:faqs.adoc#tsHostName[FAQs] to know how to find the hostname of your application instance. +The xref:faqs.adoc#tsHostName[hostname] of your ThoughtSpot application instance. * `authType` + -Authentication type. ThoughtSpot supports a variety of Authentication types. For testing purposes, you can use `AuthType.None`. For other authentication options, see xref:embed-authentication.adoc[Authentication]. +Authentication type. For testing purposes, you can use `AuthType.None`. For information about other authentication options, see xref:embed-authentication.adoc[Authentication]. [source,JavaScript] ---- init({ thoughtSpotHost: 'https://your-thoughtspot-host', // Replace with your ThoughtSpot application URL - authType: AuthType.None, + authType: AuthType.None, // Use the appropriate AuthType for your setup }); ---- == Create an instance of the SpotterEmbed object -Create an instance of the `SpotterEmbed` object and specify the data source ID. Optionally, you can specify the search query string to generate a chart or table at load time. +Create an instance of the `SpotterEmbed` object. + +If you are embedding the Spotter Classic or Spotter 2 experience, the data source ID is required. If Spotter 3 experience is enabled on your instance, you can either specify the data source ID or enable the *Auto mode* to allow Spotter to automatically discover and select data sources. + +[IMPORTANT] +==== +Auto mode is disabled by default on ThoughtSpot Embedded instances. To enable this feature on your instance, contact ThoughtSpot Support. +==== [source,JavaScript] ---- -const conversation = new SpotterEmbed(document.getElementById('ts-embed'), { +const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { frameParams: { width: '100%', height: '100%', }, - worksheetId: '<%=datasourceGUID%>', // ID of the data source object to query data - searchOptions: { - searchQuery: 'sales by region', // Optional: initial search query string to pass on load - }, + worksheetId: '<%=datasourceGUID%>', // ID of the data source object. To use the Auto mode, set the ID to 'auto_mode', + //... other attributes }); ---- -[#configControls] -=== Configuration controls for embed view (Optional) - -The embed package for Spotter includes the additional configuration flags to customize the Spotter interface. -For example, you can hide or disable data source selection using the `hideSourceSelection` and `disableSourceSelection` + -parameters. Disables data source selection panel for embed users when set to `true`. -You can also set locale preference for Spotter interactions using the `locale` property. - -The following code sample sets the locale to English (United Kingdom) and enables viewing Spotter feature limitations. +=== Customize your embed (Optional) +The SDK provides configuration settings to customize the embedded Spotter interface. +For example, you can hide sample questions or disable data source selection using the `hideSampleQuestions` and `disableSourceSelection` parameters. [source,JavaScript] ---- const conversation = new SpotterEmbed(document.getElementById('ts-embed'), { - frameParams: { - width: '100%', - height: '100%', - }, - worksheetId: '<%=datasourceGUID%>', // ID of the data source object to query data - searchOptions: { - searchQuery: 'sales by region', // Optional: initial search query string to pass on load - }, - locale: 'en-GB', - showSpotterLimitations: true, + //...other embed configuration attributes + hideSampleQuestions: true, + disableSourceSelection: true }); ---- +For more information and examples, see xref:embed-spotter.adoc#configControls[Customizing the embedded Spotter interface]. -For a complete list of Spotter embed view configuration settings, see xref:SpotterEmbedViewConfig.adoc[SDK reference Documentation]. +=== Register event listeners -== Customize your embed view -To customize your embedded Spotter views, the following options are available with the Visual Embed SDK: +To listen to the events emitted by the embedded ThoughtSpot component, register xref:embed-events.adoc#embed-events[embed event] handlers. -* Control the xref:embed-spotter.adoc#spotterMenuActions[visibility of menu actions in the embedded view] -* xref:embed-spotter.adoc#_customize_styles_and_interface_elements[Customize styles and interface elements] -* xref:embed-spotter.adoc#_customize_app_interactions_with_events[Customize app interactions] +The following example shows how to register xref:EmbedEvent.adoc#_init[EmbedEvent.Init] and xref:EmbedEvent.adoc#_load[EmbedEvent.Load] listeners. -[#spotterMenuActions] -=== Customize menu actions and elements +[source,JavaScript] +---- +// Register event listeners +spotterEmbed.on(EmbedEvent.Init, showLoader); // Show loader when initialization starts +spotterEmbed.on(EmbedEvent.Load, hideLoader); // Hide loader when embed is fully loaded +---- -The SDK provides action IDs to disable, show, or hide the following elements and menu actions via `disabledActions`, `visibleActions`, or `hiddenActions` array. +To trigger actions on the embedded interface, use the xref:HostEvent.adoc[Host events]. -The following menu actions are available by default in the embedded Spotter interface: +The following example shows the host event to reset a Spotter conversation session: -* *Preview data* and *Reset* actions on the conversation panel -* The edit and delete icons on the prompt panel -* *Pin*, *Save*, *Download*, *Modify* on Spotter-generated Answers -* Spotter feedback widget and chart switcher icon on Spotter-generated Answers +[source,JavaScript] +---- +// Example: Add a host event to reset the Spotter conversation +document.getElementById('resetBtn').addEventListener('click', () => { + spotterEmbed.trigger(HostEvent.ResetSpotterConversation); +}); +---- -The following example shows how to disable actions and menu elements using xref:embed-actions.adoc[`disabledActions`] array: +=== Render the embedded object [source,JavaScript] ---- - // Show these actions - visibleActions: [Action.Pin,Action.Save,Action.Edit,Action.PreviewDataSpotter,Action.ResetSpotterChat,Action.SpotterFeedback,Action.EditPreviousPrompt,Action.DeletePreviousPrompt], - // Disable these actions - disabledActions:[Action.PreviewDataSpotter,Action.Edit], - disabledActionReason: "Contact your administrator to enable this feature" +spotterEmbed.render(); ---- -For a complete list of supported actions, see xref:embed-action-ref.adoc#_spotter[Spotter menu actions]. +=== Verify your embed -=== Customize styles and interface elements -To customize the look and feel of the Spotter interface, use the xref:css-customization.adoc[CSS customization framework] in the SDK. The `customizations` object allows you to add xref:customize-css-styles.adoc[custom CSS definitions], xref:customize-text-strings.adoc[text strings], and xref:customize-icons.adoc[icons]. +* Load the embedded object. +** If the embedding is successful, you'll see the Spotter page. +** Initiate a chat session, ask a question, and view the results. +** If you see a blank screen: +*** Verify that your embed code has the correct ThoughtSpot host URL. Ensure that your ThoughtSpot instance is accessible. +*** Verify whether the authentication credentials used in your code are valid. +* Verify whether the customization settings are applied. -==== Override icons -To override the icons, you must first identify the icon ID, create an SVG file to replace this icon, and add the SVG hosting URL to your embed customization code. +[#configControls] +== Customizing embedded Spotter interface +When you embed Spotter, you'll notice that the embedded component loads an initial page with a prompt interface. The look and feel of this page vary depending on the Spotter version used for embedding. -The most common icon ID to override is `rd-icon-spotter`, the default Spotter icon. +=== Spotter Classic and Spotter 2 experiences +If you have embedded Spotter Classic or Spotter 2, the initial page includes a prompt bar for user input, a data source selector, and the UI options to preview data and reset a Spotter session. -The following example uses the link:https://github.com/thoughtspot/custom-css-demo/blob/main/alternate-spotter-icon.svg[alternate-spotter-icon.svg, window=_blank] file hosted on `\https://cdn.jsdelivr.net/` to override the Spotter icon. +[.widthAuto] +[.bordered] +image::./images/spotter-embed-legacy.png[Spotter embed] + +=== Spotter 3 experience +In Spotter 3 embedding, you can load the page with a pre-selected data source or use the *Auto mode* to allow Spotter to automatically discover and select a relevant data model for user queries. + +**Default view**: + +[.widthAuto] +[.bordered] +image::./images/spotter3-legacy-interface.png[Spotter 3 interface] + +**With Auto mode enabled**: + +[.widthAuto] +[.bordered] +image::./images/spotter3-leagcy-interface-automode.png[Spotter 3 interface] + +[NOTE] +==== +When Auto mode is enabled, **Preview data** and **Data Model instructions** options will not be available. +==== + +==== Optional settings for Spotter 3 + +Spotter 3 experience is available with a new prompt interface that includes additional features and user elements to enrich your Spotter experience. You can include the *Chat history* panel to allow your users to access the chat history from their previous sessions. + +To enable the new chat interface and chat history features, set the `updatedSpotterChatPrompt` and `enablePastConversationsSidebar` attributes to `true`, as shown in this example: [source,JavaScript] ---- - init({ - //... - customizations: { - // Specify the SVG hosting URL to overide the icon, for example Spotter (`rd-icon-spotter`) icon - iconSpriteUrl: "https://cdn.jsdelivr.net/gh/thoughtspot/custom-css-demo/alternate-spotter-icon.svg" - } - }); +const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { + // ...other embed configuration attributes + + // Enable the updated Spotter chat prompt experience. + updatedSpotterChatPrompt: true, + + // Enable the sidebar for accessing past Spotter conversations + enablePastConversationsSidebar: true +}); ---- +The following figure shows UI elements and functions available in the new chat prompt and chat history panel: + +[.widthAuto] +[.bordered] +image::./images/spotter3-new-interface.png[Spotter 3 new interface] + +==== MCP connectors and resource selection icon +A connector is an external MCP server or tool, such as Google Drive, Slack, Notion, Confluence, or Jira, which can be used as a data source in Spotter sessions. ThoughtSpot administrators can configure connectors to enable Spotter users to include both structured and unstructured data in their conversation sessions. + +If the new prompt interface in Spotter 3 is enabled, the Spotter page displays the *MCP Connectors* menu along with a '\+' icon in the prompt panel. Your application users can connect to a tool preconfigured by your ThoughtSpot administrator directly from the Spotter 3 prompt interface using the '+' icon and add resources to their conversation context. + [NOTE] ==== -When customizing icons, ensure that the SVG hosting server is added to the CSP allowlist on the *Develop* > *Security Settings* page. For more information, see xref:customize-icons.adoc#_update_allowlists_in_security_settings_page[Customize icons]. +The MCP connector module and the '+' icon are displayed by default if the new prompt interface is enabled in your embed. However, we do not recommend using this feature in your production environments. ==== -==== Customize text strings -To replace text strings, you can use the `stringsIDs` and `strings` properties in the content customization object. - -The following example shows how to replace "Spotter" and other text strings on the Spotter interface. +Currently, the Visual Embed SDK does not provide any attributes or action IDs to hide these elements. As a workaround, you can use the CSS selectors to hide these elements: [source,JavaScript] ---- -// Initialize the SDK with custom text string replacements init({ - // ... - customizations: { - content: { - // Use the strings object to replace the visible UI text with custom labels. - strings: { - // Change all instances of "Liveboard" to "Dashboard" - "Liveboard": "Dashboard", - // Change all instances of "Answer" to "Reports" - "Answer": "Reports", - // Change all instances of "Spotter" to "dataAnlyzer" - "Spotter": "dataAnlyzer", - // Change all instances of "Search" to "Analyze" - "Search": "Analyze", - } + thoughtSpotHost: 'https://your-thoughtspot-host', // URL of your ThoughtSpot instance + authType: AuthType.None, // Authentication type; use appropriate AuthType for your environment + customizations: { + style: { + customCSS: { + rules_UNSTABLE: { + // Hide the MCP connectors module in the Spotter prompt panel + ".button-module__buttonWrapper.chat-connector-resources-module__addConnectorResourceButton": { + "display": "none !important" + }, + // Hide the add resources (+) icon in the Spotter prompt panel + "button.button-module__button.button-module__buttonWithIcon.button-module__tertiary.button-module__sizeM.button-module__backgroundLight.button-module__both": { + "display": "none !important" + } } + } } + }, + // ...other configuration attributes }); ---- +=== Customizing styles and interface elements +The Visual Embed SDK provides a comprehensive style customization framework for overriding icons, text strings, and the appearance of UI elements. + +The `customizations` object allows you to add custom CSS definitions, replace text strings, and override icons. If your customization framework uses external sources or hosting servers, ensure they are added to the CSP allowlist. For more information, see the xref:css-customization.adoc[CSS customization framework], xref:customize-text-strings.adoc[Customize text strings], and xref:customize-icons.adoc[Customize icons] sections. + [#SpotterCSS] -==== Customize styles +=== Customize using CSS variables +You can customize the background color of the conversation and prompt panels, button elements, and the components of the charts generated by Spotter using xref:customize-css-styles.adoc[CSS variables]. -There are several CSS variables available for customizing Spotter interface. You can customize the background color of the conversation and prompt panels, button elements, and the components of the charts generated by Spotter. +If Theme Builder is enabled on your ThoughtSpot instance, you can find the variables for Spotter customization by navigating to *Develop* > *Customizations* > *Theme Builder* in the ThoughtSpot UI and downloading the CSS variables. [source,JavaScript] ---- @@ -219,97 +268,217 @@ init({ }, ---- -For more information about CSS variables for style customization, see xref:customize-css-styles.adoc#_spotter_interface[Spotter interface customization]. +==== Customizing text strings +To replace text strings, you can use the `stringsIDs` and `strings` properties in the content customization object. -== Customize app interactions with events +The following example shows how to replace "Spotter" and other text strings on the Spotter interface. -To listen to the events emitted by the embedded ThoughtSpot component, register xref:embed-events.adoc#embed-events[embed event] handlers. +[source,JavaScript] +---- +// Initialize the SDK with custom text string replacements +init({ + // ... + customizations: { + content: { + // Use the strings object to replace the visible UI text with custom labels. + strings: { + // Change all instances of "Preview data" to "Show data" + "Preview data": "Show data", + // Change all instances of "Spotter" to "dataAnalyzer" + "Spotter": "dataAnalyzer", + } + } + } +}); +---- -The following example shows how to register xref:EmbedEvent.adoc#_init[EmbedEvent.Init] and xref:EmbedEvent.adoc#_load[EmbedEvent.Load] listeners. +=== Customizing the Spotter icon +To override an icon, you must find the ID of the icon, create an SVG file to replace this icon, and add the SVG hosting URL to your embed customization code. The most common icon to override is the default Spotter icon and its icon ID is `rd-icon-spotter`. + +The following example uses the link:https://github.com/thoughtspot/custom-css-demo/blob/main/alternate-spotter-icon.svg[alternate-spotter-icon.svg, window=_blank] file hosted on `\https://cdn.jsdelivr.net/` to override the Spotter icon. [source,JavaScript] ---- - conversation.on(EmbedEvent.Init, showLoader) - conversation.on(EmbedEvent.Load, hideLoader) + init({ + //... + customizations: { + // Specify the SVG hosting URL to override the icon, for example Spotter (`rd-icon-spotter`) icon + iconSpriteUrl: "https://cdn.jsdelivr.net/gh/thoughtspot/custom-css-demo/alternate-spotter-icon.svg" + } + }); ---- -Similarly, to trigger actions on the embedded ThoughtSpot interface, use xref:HostEvent.adoc[Host events]. +The following figures show the customized Spotter icon: +[.widthAuto] +[.bordered] +image::./images/spotter-icon-customization.png[Spotter icon customization] -== Render the embedded object +=== Hiding the Spotter icon and ThoughtSpot branding in the reasoning interface +If you want to hide the Spotter icon from the prompt response page and reasoning interface, or if you want to remove ThoughtSpot branding, you can use the CSS rules with selectors, as shown in this example: [source,JavaScript] ---- -conversation.render(); +init({ + //... embed configuration attributes + customizations: { + style: { + customCSS: { + rules_UNSTABLE: { + // Hide the Spotter icon in the tool call card under reasoning + "svg.chat-module__spotterIcon.icon-module__iconStyle.icon-module__xxl.icon-module__white": { + "display": "none !important" + }, + // Control the visibility for the ThoughtSpot text in the tool call card under reasoning + // Hide the element completely if MCP connectors are enabled, since the text-indent works for ThoughtSpot text only + ".collapsible-item-response-module__title": { + "text-indent": "-89px", + "overflow": "hidden", + "margin-left": "-24px" + }, + // Hide the ThoughtSpot (or Connector) icon in the tool call card under reasoning + ".collapsible-item-response-module__customIconWrapper": { + "display": "none" + }, + }, + }, + }, + } +}); ---- -== Code sample +[#spotterMenuActions] +=== Customizing menu actions and elements + +The SDK provides action IDs to disable, show, or hide the following elements and menu actions via `disabledActions`, `visibleActions`, or `hiddenActions` arrays. + +For example, you can hide the *Preview data*, *Reset* in the prompt panel, or *Pin*, *Download*, and other actions from a Spotter-generated response. + +The following code sample disables actions and menu elements using the xref:embed-actions.adoc[`disabledActions`] array: [source,JavaScript] ---- -import { SpotterEmbed, AuthType, init } from '@thoughtspot/visual-embed-sdk'; + // Hide these actions + hiddenActions: [Action.Pin,Action.ResetSpotterChat,Action.DeletePreviousPrompt], + // Disable actions + disabledActions:[Action.PreviewDataSpotter,Action.Edit], + disabledActionReason: "Contact your administrator to enable this feature" +---- +For a comprehensive list of supported actions, see xref:Action.adoc[Spotter menu actions]. + + +== Code samples -// Initialize the SDK +**Code sample for embedding Spotter Classic and Spotter 2 experience** + +[source,JavaScript] +---- +import { + SpotterEmbed, + AuthType, + init, + EmbedEvent, + HostEvent +} from '@thoughtspot/visual-embed-sdk'; +// Initialize the ThoughtSpot Visual Embed SDK with your ThoughtSpot URL and authentication type. init({ - thoughtSpotHost: 'https://your-thoughtspot-host', // Replace with your ThoughtSpot application URL - authType: AuthType.None, // Use the appropriate AuthType for your setup + thoughtSpotHost: 'https://your-thoughtspot-host', // Replace with your ThoughtSpot application URL + authType: AuthType.None, // Use the appropriate AuthType for your setup }); -// Find the container element in your HTML +//Define event handler to show a loading indicator when the embed is initializing. +function showLoader() { + // Show loading indicator +} + +// Define event handler to hide the loading indicator when the embed has loaded. +function hideLoader() { + // Hide loading indicator +} + +// Find the container element in your HTML where the SpotterEmbed will be rendered. const container = document.getElementById('ts-embed'); if (container) { - // Create and render SpotterEmbed - const spotterEmbed = new SpotterEmbed(container, { - frameParams: { - height: '600px', - width: '100%', - }, - worksheetId: 'your-worksheet-id', // ID of the data source object (Model) to query data - searchOptions: { - searchQuery: 'Sales by year', // Optional: initial search query string to populate on load - }, - // Add more configuration options as needed - // Add event listeners as needed - onInit: () => console.log('Spotter initialized'), - onLoad: () => console.log('Spotter loaded'), + // Create and configure the SpotterEmbed + const spotterEmbed = new SpotterEmbed(container, { + frameParams: { + height: '100%', // Set the height of the embedded frame + width: '100%', // Set the width of the embedded frame + }, + worksheetId: 'your-worksheet-id', // ID of the data source object to query data from + //... other configuration attributes }); - spotterEmbed.render(); + // Register event listeners + spotterEmbed.on(EmbedEvent.Init, showLoader); // Show loader when initialization starts + spotterEmbed.on(EmbedEvent.Load, hideLoader); // Hide loader when embed is fully loaded + + // Render the SpotterEmbed in the container. + spotterEmbed.render(); + // Example: Add a host event to reset the Spotter conversation + document.getElementById('resetBtn').addEventListener('click', () => { + spotterEmbed.trigger(HostEvent.ResetSpotterConversation); + }); +} ---- -== Test your embed +**Code sample for embedding Spotter 3 experience** -* Build your app and load the embedded object. +[source,JavaScript] +---- +import { + SpotterEmbed, + AuthType, + init, + EmbedEvent, + HostEvent +} from '@thoughtspot/visual-embed-sdk'; +// Initialize the ThoughtSpot Visual Embed SDK with your ThoughtSpot URL and authentication type. +init({ + thoughtSpotHost: 'https://your-thoughtspot-host', // Replace with your ThoughtSpot application URL + authType: AuthType.None, // Use the appropriate AuthType for your setup +}); -** If the embedding is successful, you'll see the Spotter page with a conversation panel. -+ -[.widthAuto] -[.bordered] -image::./images/converseEmbed_default.png[Spotter embed] +//Define event handler to show a loading indicator when the embed is initializing. +function showLoader() { + // Show loading indicator +} -** Add a query, click the prompt button, and view the results. -+ -[.widthAuto] -[.bordered] -image::./images/converseEmbed-with-query.png[Spotter embed] +// Define event handler to hide the loading indicator when the embed has loaded. +function hideLoader() { + // Hide loading indicator +} -** If you see a blank screen: -*** Check if your code has the correct ThoughtSpot host URL. Ensure that your instance is accessible. -*** Check if the authentication credentials in your code are valid +// Find the container element in your HTML where the SpotterEmbed will be rendered. +const container = document.getElementById('ts-embed'); +if (container) { + // Create and configure the SpotterEmbed + const spotterEmbed = new SpotterEmbed(container, { + frameParams: { + height: '100%', // Set the height of the embedded frame + width: '100%', // Set the width of the embedded frame + }, + worksheetId: 'your-worksheet-id', // ID of the data source object to query data from. For automatic model discovery and selection (Auto mode), specify 'auto_mode' + updatedSpotterChatPrompt: true, // Enable new chat interface + enablePastConversationsSidebar: true, // Enable chat history + //... other configuration attributes + }); -* Verify the customized objects and elements. + -The following figures show the customized Spotter icon and text: -+ -[.widthAuto] -[.bordered] -image::./images/spotter-icon-customization.png[Spotter icon customization] + // Register event listeners + spotterEmbed.on(EmbedEvent.Init, showLoader); // Show loader when initialization starts + spotterEmbed.on(EmbedEvent.Load, hideLoader); // Hide loader when embed is fully loaded -+ -[.widthAuto] -[.bordered] -image::./images/spotter-text-customization.png[Spotter customization] + // Render the SpotterEmbed in the container. + spotterEmbed.render(); + // Example: Add a host event to reset the Spotter conversation + document.getElementById('resetBtn').addEventListener('click', () => { + spotterEmbed.trigger(HostEvent.ResetSpotterConversation); + }); +} +---- == Additional resources -* link:https://docs.thoughtspot.com/cloud/latest/spotter[Spotter Documentation] +* xref:embed-ai-analytics.adoc[Spotter features and embedding options] * link:https://developers.thoughtspot.com/docs/Class_SpotterEmbed[SpotterEmbed classes and methods] * link:https://developers.thoughtspot.com/docs/Interface_SpotterEmbedViewConfig[Configuration options for Spotter interface customization] * link:https://github.com/thoughtspot/developer-examples/tree/main/visual-embed/spotter/spotter-embed[Developer examples, window=_blank] +* link:https://docs.thoughtspot.com/cloud/latest/spotter[Spotter Product Documentation] diff --git a/modules/ROOT/pages/full-app-customize.adoc b/modules/ROOT/pages/full-app-customize.adoc index a63084aa0..c13a13eb1 100644 --- a/modules/ROOT/pages/full-app-customize.adoc +++ b/modules/ROOT/pages/full-app-customize.adoc @@ -27,6 +27,7 @@ The key differences between these UI experience modes are listed in the followin -- [width="100%", cols="2,4,4,5"] [options='header'] + |===== |Feature component |Classic (V1) experience | V2 experience | V3 experience |**UI experience**| Classic layout + diff --git a/modules/ROOT/pages/intro-thoughtspot-objects.adoc b/modules/ROOT/pages/intro-thoughtspot-objects.adoc index 372452d42..3096ec818 100644 --- a/modules/ROOT/pages/intro-thoughtspot-objects.adoc +++ b/modules/ROOT/pages/intro-thoughtspot-objects.adoc @@ -6,7 +6,7 @@ :page-pageid: thoughtspot-objects :page-description: -ThoughtSpot is a business intelligence and data analytics platform that helps you explore, analyze and share real-time business analytics and interactive insights. Besides being an interactive data analytics platform, ThoughtSpot provides a robust and guided search functionality using which business users can search data instantly. ThoughtSpot is different from other BI tools, because ThoughtSpot Search is the core of the ThoughtSpot system. +ThoughtSpot is a business intelligence and data analytics platform that helps you explore, analyze, and share real-time business analytics and interactive insights. Besides being an interactive data analytics platform, ThoughtSpot provides robust, guided search functionality that business users can use to search data instantly. ThoughtSpot is different from other BI tools because ThoughtSpot Search is the core of the ThoughtSpot system. Before you look at the rest of the developer documentation, please review this page to understand how ThoughtSpot works relative to other tools you may be familiar with. @@ -17,39 +17,39 @@ The following figure illustrates the object model hierarchy in ThoughtSpot withi image::./images/object_model_hierarchy.png[Object Model Hierarchy] == Object identifiers -Every object on a ThoughtSpot has a globally unique ID (GUID), visible in URLs and in REST API responses as the `id` or `metadata_id` property. GUIDs are unique within a ThoughtSpot instance and thus cannot repeat in different Orgs. +Every object in ThoughtSpot has a globally unique ID (GUID), visible in URLs and in REST API responses as the `id` or `metadata_id` property. GUIDs are unique within a ThoughtSpot instance and thus cannot repeat in different Orgs. Objects have an additional `obj_id` property that is *user-settable* and *unique per Org*. It appears as `metadata_obj_id` in responses from the `/metadata/search` REST API. -Each Org can have one object with a particular `obj_id`. The combination of `org_id` + `obj_id` is completely unique per instance, so it is equivalent to the object's GUID. +Each Org can have one object with a particular `obj_id`. The combination of `org_id` + `obj_id` is unique per instance, so it is equivalent to the object's GUID. -`obj_id` allows exporting TML that can be imported into any Org on any instance, letting ThoughtSpot determine the GUIDs of the object automatically without requiring any additional effort on your part. +`obj_id` allows you to export TML that can be imported into any Org on any instance, letting ThoughtSpot determine the object's GUID automatically without requiring any additional effort on your part. == Data modeling -You must create a data model comprising at least one link:https://docs.thoughtspot.com/cloud/latest/connections[connection, window=_blank] with one link:https://docs.thoughtspot.com/cloud/latest/connect-data[Table, window=_blank] to begin using link:https://docs.thoughtspot.com/cloud/latest/search-data[Search data, window=_blank] to create content. -Most often, there will be multiple *Tables*, with a variety of link:https://docs.thoughtspot.com/cloud/latest/tables-join[joins, window=_blank] defined in ThoughtSpot, with a link:https://docs.thoughtspot.com/cloud/latest/models[Model, window=_blank] bringing those tables together into a presentable analytic data model for the end-users. +You must create a data model with at least one link:https://docs.thoughtspot.com/cloud/latest/connections[connection, window=_blank] and one link:https://docs.thoughtspot.com/cloud/latest/connect-data[Table, window=_blank] before you can use link:https://docs.thoughtspot.com/cloud/latest/search-data[Search data, window=_blank] to create content. +Most often, there will be multiple *Tables* with a variety of link:https://docs.thoughtspot.com/cloud/latest/tables-join[joins, window=_blank] defined in ThoughtSpot, and a link:https://docs.thoughtspot.com/cloud/latest/models[Model, window=_blank] that brings those tables together into a presentable analytics model for end users. -Data engineers with *Can manage data* privilege can add connections either link:https://docs.thoughtspot.com/cloud/latest/connections[in the UI, window=_blank] or via xref:connections.adoc[REST API]. Connections are owned and accessible only to their creator, who then imports *Tables* from the connection. Once imported, tables can be shared with other ThoughtSpot groups and users. +Data engineers with the *Can manage data* privilege can add connections either link:https://docs.thoughtspot.com/cloud/latest/connections[in the UI, window=_blank] or via xref:connections.adoc[REST API]. Connections are owned and accessible only to their creator, who then imports *Tables* from the connection. Once imported, tables can be shared with other ThoughtSpot groups and users. *Tables* can have link:https://docs.thoughtspot.com/cloud/latest/security-rls[Row Level Security (RLS), window=_blank] rules that filter the data results based on the signed-in link:https://docs.thoughtspot.com/cloud/latest/user-management[username, window=_blank] or the link:https://docs.thoughtspot.com/cloud/latest/group-management[ThoughtSpot groups, window=_blank] to which the user belongs, and those rules apply to any *Model* that uses the *Table*. [NOTE] ==== -Worksheets are deprecated and replaced with Models in ThoughtSpot Cloud 10.12.0.cl and later release versions. +Worksheets are deprecated and replaced with Models in ThoughtSpot Cloud 10.12.0.cl and later versions. ==== === Data modeling workflow 1. Create a *connection* to a cloud data warehouse. 2. Import *tables* from the *connection*. -3. Create *Models* (analytic data models) based on tables. You can also create link:https://docs.thoughtspot.com/cloud/latest/models[Models, window=_blank] and add tables. +3. Create link:https://docs.thoughtspot.com/cloud/latest/models[*Models*, window=_blank] (analytic data models) based on tables. 4. Create link:https://docs.thoughtspot.com/cloud/latest/views[ThoughtSpot Views, window=_blank] or link:https://docs.thoughtspot.com/cloud/latest/sql-views[SQL Views, window=_blank] as necessary. -ThoughtSport also supports programmatic deployment of data models via link:https://docs.thoughtspot.com/cloud/latest/tml[ThoughtSpot Modeling Language (TML), window=_blank] and table import from link:https://docs.thoughtspot.com/cloud/latest/dbt-integration#integrate[dbt, window=_blank]. +ThoughtSpot also supports programmatic deployment of data models via link:https://docs.thoughtspot.com/cloud/latest/tml[ThoughtSpot Modeling Language (TML), window=_blank] and table import from link:https://docs.thoughtspot.com/cloud/latest/dbt-integration#integrate[dbt, window=_blank]. == Content creation -ThoughtSpot Search data creates a single table or chart view based on the query in the search bar and other configurations to the view made after the search results are visible. +ThoughtSpot Search data creates a table or chart view based on the query in the search bar and any additional view configuration applied after the search results are displayed. -Search data serves the role of report builder or widget designer, while *Liveboards* serve the role of dashboards in other tools. A single search can be saved as an link:https://docs.thoughtspot.com/cloud/latest/answers[Answer, window=_blank] object, or the search result can be pinned to a Liveboard. +Search data serves the role of report builder or widget designer, while *Liveboards* serve the role of dashboards in other tools. A single search can be saved as a link:https://docs.thoughtspot.com/cloud/latest/answers[*Answer*, window=_blank] object, or the search result can be pinned to a Liveboard. A link:https://docs.thoughtspot.com/cloud/latest/liveboard[Liveboard, window=_blank] is a collection of many visualizations presented in a defined layout. You do not create the visualizations on a Liveboard directly; they are created from search data results and then pinned to a Liveboard. You can create a new Liveboard from the *Liveboards* page and then add a visualization from the search data result, or you can create a new Liveboard when pinning an Answer retrieved from search data. @@ -60,8 +60,8 @@ To create content: 1. Use the link:https://docs.thoughtspot.com/cloud/latest/search-data[Search data, window=_blank] functionality to build visualizations from data sources such as *Models* or *Views*. 2. Save the search result as an *Answer* or pin it to a Liveboard as a visualization. -=== Visualizations on a Liveboard -You can add any number of visualizations retrieved from the search to a Liveboard object. Pinned visualizations exist only within the Liveboard and are independent of the objects saved as *answers*. +=== Visualizations on a Liveboard +You can add any number of visualizations from search results to a Liveboard object. Pinned visualizations exist only within the Liveboard and are independent of objects saved as *Answers*. Each time you pin a search result, a separate new visualization is created on the Liveboard. @@ -81,40 +81,40 @@ A tag object is created by the administrator, is visible to all users, and can b Tag search is always an *OR* operation: filtering on multiple tags results in all objects with any of the tags, not just those with all of the specified tags. == Access control (sharing) -ThoughtSpot's link:https://docs.thoughtspot.com/cloud/latest/data-security[access control model, window=_blank] works by an `author` or `administrator` sharing objects to link:https://docs.thoughtspot.com/cloud/latest/groups-privileges[ThoughtSpot groups, window=_blank] or other individual users: +ThoughtSpot's link:https://docs.thoughtspot.com/cloud/latest/data-security[access control model, window=_blank] works by having an `author` or `administrator` share objects with link:https://docs.thoughtspot.com/cloud/latest/groups-privileges[ThoughtSpot groups, window=_blank] or individual users: * The creator of an object is referred to as the *author*. * The author can share the object with their groups using the *Shareable* property. * The author can share the object with other users in *Shareable* groups that the *author* belongs to, and if the other *user* is also marked *Shareable*. -An administrator user can share any object with any group or user with no restrictions. ThoughtSpot administrators can add users locally link:https://docs.thoughtspot.com/cloud/latest/user-management[in the UI, window=_blank] or via xref:user-api.adoc[REST API]. Similarly, they can manage groups and sharing privileges by using the *Groups* feature in the UI or via REST API. +An administrator can share any object with any group or user without restrictions. ThoughtSpot administrators can add users locally link:https://docs.thoughtspot.com/cloud/latest/user-management[in the UI, window=_blank] or via xref:user-api.adoc[REST API]. Similarly, they can manage groups and sharing privileges by using the *Groups* feature in the UI or via REST API. === Single sign-on -If xref:configure-saml.adoc[SAML] or xref:configure-oidc.adoc[OpenID Connect (OIDC)] integration support is enabled on your instance, users that authenticate to external identity providers (IdP) can log in to ThoughtSpot with their Single Sign-On credentials. -Embedded ThoughtSpot instances also support the xref:trusted-authentication.adoc[trusted authentication] method to sign in their application users. +If xref:configure-saml.adoc[SAML] or xref:configure-oidc.adoc[OpenID Connect (OIDC)] integration is enabled on your instance, users who authenticate with external identity providers (IdP) can log in to ThoughtSpot with their Single Sign-On credentials. +Embedded ThoughtSpot instances also support the xref:trusted-authentication.adoc[trusted authentication] method to sign in application users. == Object properties in REST API -The object representations in ThoughtSpot REST API include the following properties: +Object representations in the ThoughtSpot REST API include the following properties: * `id` + -GUID of the object. Unique within a given ThoughtSpot instance -* `obj_id` + -User-defined string identifer of the object. Unique within a given Org +GUID of the object. Unique within a given ThoughtSpot instance. +* `obj_id` + +User-defined string identifier for the object. Unique within a given Org. * `author` + GUID of the user who created / uploaded the object, or had the object transferred to them. * `owner` + -GUID representing the relationship between hierarchical objects, For example, a *column* would have the GUID of a *Table* or *Model* as owner. +GUID representing the relationship between hierarchical objects. For example, a *column* would have the GUID of a *Table* or *Model* as owner. * `created` + -timestamp of object creation +Timestamp of object creation. * `modified` + -timestamp from last time object was modified +Timestamp of the last time the object was modified. * `modifiedBy` + -GUID of the user who last modified the object +GUID of the user who last modified the object. * `tags` + -An array of tag objects representing the tags assigned to the object. +Array of tag objects representing the tags assigned to the object. == Object names in REST API v1 -The object type names in the ThoughtSpot REST API v1 differ from the current names seen in the ThoughtSpot UI. Data objects have both a `type` and a `subtypes` within the REST API, allowing you to request all valid data objects or specify the individual subtype. +Object type names in ThoughtSpot REST API v1 differ from the current names shown in the ThoughtSpot UI. Data objects have both a `type` and a `subtypes` field in the REST API, allowing you to request all valid data objects or specify an individual subtype. The following notation is used in REST API v1 for object types: @@ -133,7 +133,7 @@ The following notation is used in REST API v1 for object types: * *Users*: `USER` * *Groups*: `USER_GROUP` -Column and join objects with their own GUIDs do exist within the ThoughtSpot system, but they are connected to *Tables*, *Models*, or other data objects. Columns and joins can be viewed or modified only within the context of the data object to which they belong. +Column and join objects with their own GUIDs do exist within the ThoughtSpot system, but they are connected to *Tables*, *Models*, or other data objects. Columns and joins can be viewed or modified only within the context of the data object to which they belong. == Related resources diff --git a/modules/ROOT/pages/mcp-connect-custom-chatbot.adoc b/modules/ROOT/pages/mcp-connect-custom-chatbot.adoc new file mode 100644 index 000000000..918cdb0e1 --- /dev/null +++ b/modules/ROOT/pages/mcp-connect-custom-chatbot.adoc @@ -0,0 +1,355 @@ += Integrating MCP Server in a custom application or chatbot +:toc: true +:toclevels: 3 + +:page-title: Integrating MCP Server in a custom application or chatbot +:page-pageid: custom-chatbot-integration-mcp +:page-description: Learn how to build custom applications and chatbots that use ThoughtSpot MCP Server. + +If you are building a chatbot client with your own agent and orchestration logic, you can use the MCP Server to call MCP tools behind a custom web experience and integrate it with other systems or services as needed. + +When integrated, the agent in your custom application can: + +* Automatically discover ThoughtSpot MCP tools. +* Support natural language conversation sessions for data questions. +* Generate embeddable visualizations and programmatically create a Liveboard. + +[IMPORTANT] +==== +* Currently, the MCP Server integration does not support link:https://docs.thoughtspot.com/cloud/latest/spotter-versions[Spotter 3 capabilities]. +==== + +== Before you begin +Before you begin, review the following prerequisites: + +* Node.js version 22 or later is installed and available in your environment. +* Ensure that your setup has access to a ThoughtSpot application instance with 10.11.0.cl or a later release version. +* Ensure that the users have the necessary permissions to view data from relevant models and tables in ThoughtSpot. Existing RLS/CLS rules on tables are enforced automatically in data source responses. To create charts or Liveboards from a conversation session, data download and content creation privileges are required. + +== Authenticating users +If your own application or backend service manages user identities, and you want to implement a seamless authentication experience without redirecting users to an external OAuth flow from the chatbot host, use the trusted authentication method. + +=== Trusted authentication flow +In a typical trusted authentication flow, your backend service calls the `/api/rest/2.0/auth/token/full` REST API endpoint to obtain a full access token (`TS_AUTH_TOKEN`) for a ThoughtSpot user or service account. + +The token generated for the user session is used as a bearer token when your backend calls ThoughtSpot APIs or when it brokers MCP tool calls. + +== Connecting clients +If your custom chatbot implementation uses Claude, OpenAI, or Gemini LLM APIs to call MCP tools, ensure that your MCP Server endpoint, authentication token, and ThoughtSpot host are included in the API request. + +=== Claude MCP connector +If your application uses Claude MCP connector, use the following API request format to connect Claude to the MCP Server: + +[source,bash] +---- +curl https://api.anthropic.com/v1/messages \ + -H "Content-Type: application/json" \ + -H "X-API-Key: $ANTHROPIC_API_KEY" \ + -H "anthropic-version: 2023-06-01" \ + -H "anthropic-beta: mcp-client-2025-04-04" \ + -d '{ + "model": "claude-3-5-sonnet-latest", + "max_tokens": 1000, + "messages": [{ + "role": "user", + "content": "How do I increase my sales?" + }], + "mcp_servers": [ + { + "type": "url", + "url": "https://agent.thoughtspot.app/bearer/mcp", + "name": "thoughtspot", + "authorization_token": "TS_AUTH_TOKEN@my-instance.thoughtspot.cloud" + } + ] + }' +---- + +In the above example, the API call includes: + +* The user’s message. +* ThoughtSpot’s MCP Server endpoint `https://agent.thoughtspot.app/bearer/mcp`. +* An `authorization_token` that encodes which ThoughtSpot instance and user/token to use. + +Claude uses the configured MCP Server to call ThoughtSpot MCP tools as needed, using the bearer-style token you provided. + +=== OpenAI Responses API +If your application uses an OpenAI LLM, use the following API request format to connect OpenAI to the MCP Server: + +[source,bash] +---- +curl https://api.openai.com/v1/responses \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $OPENAI_API_KEY" \ + -d '{ + "model": "gpt-4.1", + "tools": [ + { + "type": "mcp", + "server_label": "thoughtspot", + "server_url": "https://agent.thoughtspot.app/bearer/mcp", + "headers": { + "Authorization": "Bearer TS_AUTH_TOKEN", + "x-ts-host": "my-instance.thoughtspot.cloud" + } + } + ], + "input": "How can I increase my sales?" + }' +---- + +In the above example, the API call includes the following parameters: + +* MCP as the tool type. +* ThoughtSpot MCP Server URL. +* Authentication token and ThoughtSpot host URL. + +The OpenAI LLM model uses the configured MCP Server, sends the provided headers on each MCP tool call, and gets the requested data from your ThoughtSpot instance under that token's identity. + +=== Gemini API + +If your application is the MCP host and Gemini is the LLM provider, use the following code example to connect Gemini to the ThoughtSpot MCP Server. + +[source,typescript] +---- +import { + GoogleGenAI, + mcpToTool, +} from '@google/genai'; +import { Client } from "@modelcontextprotocol/sdk/client/index.js"; +import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; + +const transport = new StreamableHTTPClientTransport( + new URL("https://agent.thoughtspot.app/bearer/mcp"), + { + requestInit: { + headers: { + "Authorization": "Bearer TS_AUTH_TOKEN", + "x-ts-host": "my-instance.thoughtspot.cloud" + }, + } + } +); + +const mcpClient = new Client({ + name: "example-client", + version: "1.0.0", +}); + +await mcpClient.connect(transport); + +const ai = new GoogleGenAI({}); + +const response = await ai.models.generateContent({ + model: "gemini-2.5-flash", + contents: `Show me last quarter's sales by region`, + config: { + tools: [mcpToTool(mcpClient)], + }, +}); + +console.log(response.text); +await mcpClient.close(); +---- + +The above example: + +* Creates an MCP client and connects it to the ThoughtSpot MCP Server using `StreamableHTTPClientTransport`. +* Sends the required headers with the authentication token and ThoughtSpot host URL in MCP requests. +* Wraps the MCP client as a tool and passes it into `GoogleGenAI` so Gemini can call ThoughtSpot tools as part of answering a user's query. + +== Verifying the integration + +To verify the integration: + +. Start a chat session by asking a question and verify whether your chatbot's LLM is calling the ThoughtSpot MCP tools to generate a response. + +A typical agentic workflow follows this pattern: +* Calls `getRelevantQuestions` to break the request into sub-queries +* Calls `getAnswer` to run those questions in ThoughtSpot and receive structured data and visualization metadata +* Based on a user prompt, calls `createLiveboard` to save the results in a ThoughtSpot Liveboard. +. Verify whether the metadata in the output includes `frame_url` to embed a visualization in an iframe or HTML snippet. + +== Troubleshooting errors + +Cannot connect to MCP Server:: + +* Verify if the MCP Server is reachable. +* Ensure that the correct MCP Server URL is used in API requests. +* If the issue persists, verify the logs and contact ThoughtSpot Support for assistance. + +Authentication failure:: +* Ensure that the correct ThoughtSpot host URL and authentication token are in the API requests. +* Verify whether the token used for authorizing MCP requests has expired. If the token is invalid, generate a new token and retry the API calls. +* Verify whether the MCP Server and ThoughtSpot host are reachable. +* Verify whether the user has the necessary privileges to view data or create content. + +== MCP tool calls and response output +The following sections outline the MCP request input schema and data structure of the response. + +=== ping +Runs a basic health check to validate that the MCP Server is reachable. + +[source,ts] +---- +const tsPing = await callMCPTool("ping", {}); +---- + +=== getDataSourceSuggestions +Suggests appropriate ThoughtSpot data models for a given natural language question. + + +==== Example request + +[source,ts] +---- +const dsSuggestions = await callMCPTool("getDataSourceSuggestions", { + query: "show me sales by region" // user's query +}); +---- + +==== Response format + +Returns an object containing an array of suggestions: + +[source,json] +---- +{ + "suggestions": [ + { + "header": { + "guid": "worksheet-guid-123", + "displayName": "Sales Analytics", + "description": "Sales performance by region, product, and channel" + }, + "confidence": 0.92, + "llmReasoning": "This worksheet contains sales metrics and regional dimensions relevant to the query." + } + ] +} +---- + +Key fields are: + +* `header.guid`: Unique ID for the datasource. The `datasourceId` is used in `getRelevantQuestions` and `getAnswer` calls. +* `header.displayName`: Name of the data source. +* `header.description`: Optional description of the data source. +* `confidence`: Numeric score indicating the confidence of the system about a data model being the right match for the user’s query. +* `llmReasoning`: LLM's reasoning for the suggestion. + +=== getRelevantQuestions +Uses ThoughtSpot’s reasoning engine to generate AI-suggested sub-queries that help generate specific answers for a given data context. + +==== Example call + +[source,ts] +---- +const result = await callMCPTool("getRelevantQuestions", { + query: "show me sales data", // User's natural language query + datasourceIds: ["model-guid-123"], // Array of worksheet/datasource GUIDs + additionalContext: "User is interested in the data for underperforming regions and products" +}); +---- + +==== Response example + +[source,json] +---- +{ + "questions": [ + "What is the total sales revenue by region?", + "Which products have the highest revenue?", + "What are the top selling categories?" + ] +} +---- + +Each returned question can then be passed individually into `getAnswer`. + +=== getAnswer +Executes a natural language question for a given data context and returns the resulting data and visualization metadata. Clients can use this data and frame URL to render visualizations. + +==== Example call + +[source,ts] +---- +const result = await callMCPTool("getAnswer", { + question: "Total sales by region", // Natural language question + datasourceId: "model-guid-123" // Worksheet/datasource GUID +}); +---- + +==== Response example + +[source,json] +---- +{ + "question": "Total sales by region", + "session_identifier": "abc-123-def-456", + "generation_number": 2, + "data": "\"Region\",\"Total Sales\"\n\"East\",100000\n...", + "frame_url": "https://...", + "fields_info": "..." +} +---- + +Key fields are: + +* `session_identifier`: Unique session ID used to group answers. Required when creating a Liveboard from this answer using the `createLiveboard` MCP tool. +* `generation_number`: Version number for this answer. Required for Liveboard creation. +* `question`: The executed question; useful for display and to pass it into the `createLiveboard` request. +* `data`: Data returned in encoded format. Contains column headers and all returned rows in comma-separated format, which can be parsed to render tables or charts in your application. +* `frame_url`: Optional iframe URL for embedding the visualization in your UI. +* `fields_info`: Descriptive metadata about the fields and chart, useful for explanations. + +=== createLiveboard + +Creates a ThoughtSpot Liveboard with one or more answers from the results. This is a two-step process and includes the following calls: + +. Call `getAnswer` to generate visualizations and obtain `session_identifier` and `generation_number`. +. Call `createLiveboard` with those values to create the Liveboard. + +==== Example call + +[source,ts] +---- +const answerData = JSON.parse(answerResult.result.content); + +const liveboardResult = await callMCPTool("createLiveboard", { + name: "My Sales Dashboard", + noteTile: "My Sales Dashboard was created by TS MCP Chat", // Description text for the Liveboard + answers: [{ + question: answerData.question, // Display name for the Liveboard + session_identifier: answerData.session_identifier, + generation_number: answerData.generation_number + }] +}); +---- + +Required attributes are: + +* `noteTile`: Use this field for any Liveboard description or notes; a separate description field is not supported. +* `answers`: Required array. Each item must include `question`, `session_identifier`, and `generation_number` from a prior `getAnswer` call. + +==== Response example + +[source,json] +---- +{ + "liveboardId": "liveboard-guid-here", + "name": "My Sales Dashboard", + "frame_url": "https://..." +} +---- + +Key fields are: + +* `liveboardId`: GUID of the created Liveboard. +* `name`: Name of the Liveboard. +* `frame_url`: URL that can be embedded to display the Liveboard. + +== Additional resources + +* To view the MCP Server code, go to the link:https://github.com/thoughtspot/mcp-server[MCP Server GitHub repository, window=_blank]. +* For a chat client example, see link:https://github.com/thoughtspot/developer-examples/tree/main/mcp/python-react-agent-simple-ui[Python Agent with Simple React UI]. + + diff --git a/modules/ROOT/pages/mcp-integration.adoc b/modules/ROOT/pages/mcp-integration.adoc index 6b877e5ae..19a630b1f 100644 --- a/modules/ROOT/pages/mcp-integration.adoc +++ b/modules/ROOT/pages/mcp-integration.adoc @@ -1,410 +1,140 @@ -= MCP server integration += ThoughtSpot MCP Server :toc: true :toclevels: 3 :page-title: MCP integration :page-pageid: mcp-integration -:page-description: Learn how to use the ThoughtSpot Model Context Protocol (MCP) server to interact with ThoughtSpot data via MCP tools and AI APIs and get relevant questions and answers for a given query and create Liveboards at runtime. +:page-description: Learn what ThoughtSpot MCP Server is, when to use it, and how it fits into your AI and analytics architecture. -ThoughtSpot’s Agentic Model Context Protocol (MCP) Server allows you to integrate ThoughtSpot analytics directly into any AI agent, custom chatbot, or LLM-based platforms that support MCP. It acts as a connector between the ThoughtSpot instance and external AI client, and provides a set of tools for interacting with ThoughtSpot’s data and its analytics capabilities programmatically. - -The ThoughtSpot MCP Server is an add-on feature available with the link:https://www.thoughtspot.com/pricing[ThoughtSpot Analytics and ThoughtSpot Embedded offerings, window=_blank]. + -To purchase the MCP Server subscription and enable the MCP Server in your environment, you must have an active subscription to one of the following ThoughtSpot license plans: +ThoughtSpot’s Agentic Model Context Protocol (MCP) Server allows you to integrate ThoughtSpot analytics into any AI-native application, custom chatbot, or LLM platform that supports MCP. Instead of rebuilding analytics logic yourself, you connect an LLM/AI agent to the ThoughtSpot MCP Server. -* Enterprise Edition of ThoughtSpot Analytics -* ThoughtSpot Embedded subscription +== Overview +ThoughtSpot MCP Server exposes ThoughtSpot analytics as tools and resources that MCP-compatible agents can discover and call. -To learn more about the MCP Server subscription options and to get started, please contact your ThoughtSpot Sales representative. +When integrated, the MCP Server equips your AI agent/LLM with the following capabilities: -== Integration overview +* Automatic discovery of ThoughtSpot MCP tools +* Natural language queries and responses +* Programmatic creation of Liveboards and visualizations +* Generating embeddable visualizations for custom chatbot workflows -The Agentic MCP Server integration requires the following core components and authentication framework: +=== Supported use cases -MCP Server:: -The MCP Server exposes a set of tools that can be invoked by an LLM or external AI. ThoughtSpot's MCP Server acts as a bridge between the LLM/agent and ThoughtSpot application backend. +ThoughtSpot supports MCP Server integration for the following use cases: -MCP tools and resources:: -MCP tools are the actions that the MCP Server exposes to the agent for interaction with ThoughtSpot. +* *Plug-and-play clients* + +If your application already has an AI chat interface, you can use the MCP Server to plug ThoughtSpot analytics into your application's agentic experience. This integration works with agents or LLMs that natively support MCP, such as Claude, OpenAI, Gemini, or custom MCP clients. It allows your AI agent to call tools and leverage ThoughtSpot’s governed analytics, business semantic layer, data context, and row-level/object-level security, so you don’t need to build your own analytics logic. -* Ask natural language questions and get data in a structured format from ThoughtSpot -* Retrieve relevant analytical questions based on user queries -* Create a Liveboard with the answers generated from the queries -//* Get data source recommendations based on a user's query and intent +* *Custom chatbot integration* + +If you are building an MCP-based chatbot or application with your own orchestration logic or LLM, and you want to call ThoughtSpot MCP tools behind a custom web experience, integrate the MCP Server into your application. This approach is recommended when you need fine-grained control over conversation flow, backend orchestration, and the analytics experience. -+ -Currently, the MCP Server supports the following tools: - -* `ping` to test connection to ThoughtSpot -* `getRelevantQuestions` to get relevant analytical questions + -The `getRelevantQuestions` tool to fetch relevant data questions for a given data context by breaking down a user's query. -* `getAnswer` to execute the queries and fetch data + -The `getAnswer` tool generates answers and insights for a given data context. -* `createLiveboard` to create a Liveboard in ThoughtSpot + - -The `createLiveboard` tool calls the Liveboard creation workflow and creates a Liveboard with the answers generated from the user's query. +==== Choosing the right integration option -//// -* `getDataSourceSuggestions` to get data source suggestions + -Based on the type of data that users want to fetch, `getDataSourceSuggestions` gets a list of data source recommendations. Currently, `getDataSourceSuggestions` is not exposed as an MCP tool and is available as an MCP `resource`. To get data source suggestions, the user or MCP client must have at least view access to ThoughtSpot data sources. -//// +Your integration choice depends on where the conversational UI is presented to the user and whether your application relies on ThoughtSpot, a third-party AI agent, or your own agentic AI to orchestrate the analytics workflow. -MCP client/ LLM agent:: +Regardless of the integration mode, you can leverage ThoughtSpot’s semantic layer, data context, object-level, row-level, and column-level security to ensure trusted, governed analytics for your users. -The external system or application environment with AI Agent, Claude, OpenAI, or a custom chatbot that acts as a user interface and orchestrates interaction with the ThoughtSpot MCP Server. -This is the model or system that processes the user’s natural language input, determines which tool to call, and integrates the tool results into its final output. +=== Architecture and roles +The MCP Server integration and orchestration layer includes the following core components: -//// -Configuration settings to enable the integration:: -Integration requires configuration, typically via a config file, to specify server addresses, credentials, and other connection details. -//// +[width="100%" cols="2,4"] +[options='header'] +|====== +|Component|Role -Authentication and security settings:: +|*Client Interface* a| +User interface that renders chat, responses, and charts. For example, Claude AI web app, Claude Desktop, ChatGPT, OpenAI-based integrations, Gemini-based agents, custom web applications, or internal tools. -* Access to ThoughtSpot instance + -For MCP Server connection, users require access to a ThoughtSpot instance. For tool invocation, the MCP server must accept authenticated requests, and the LLM tool specification must carry those credentials or headers. + -ThoughtSpot administrators can use the SSO framework with SAML or OAuth token-based authentication methods to authenticate and sign in users. + +|*Agent or LLM* +a| Acts as orchestrator. + -* SAML redirect settings: + -For SAML SSO users, the SAML redirect domain configuration is required to ensure that users are redirected to an allowed and trusted domain after they are authenticated. + -* To get answers to their data queries, your application users require at least view access to ThoughtSpot data sources. To generate an Answer or to create a Liveboard, users require the data download privilege. -* CSP and CORS settings: + -To secure communication between the MCP client and the ThoughtSpot instance, administrators must add the MCP Server URL to CSP (Content Security Policy) and CORS (Cross-Origin Resource Sharing) allowlists in ThoughtSpot. -* Client connection configuration: + -MCP Server integration also requires configuration on the client side, typically via a config file, to include the MCP Server addresses, credentials, and other details. - - -=== How it works +- Receives the user’s prompt +- Discovers ThoughtSpot MCP tools +- Decides which tools to call and in what order. +- Combines ThoughtSpot results with other sources and generates the final answer. -The MCP Server integration with an agentic framework or LLM clients enables the following workflow: +|*ThoughtSpot MCP Server* a| +- Acts as a gateway between the agent and ThoughtSpot. +- Exposes analytics as MCP tools. +- Validates requests and forwards calls to ThoughtSpot. -. User sends a query to get data from a specific ThoughtSpot data model context. -. The LLM / AI agent receives the request and sends it to the MCP server endpoint with the user's query. -. The MCP server responds with the available tools. +|*ThoughtSpot instance* +| Your ThoughtSpot instance where data models, Liveboards, and security policies exist. + -. The LLM / AI Agent determines the appropriate MCP tool to call. Based on the user's query or prompt, the MCP tools are invoked. For example, to get information for a specific data context from ThoughtSpot, break down the user's query into relevant questions or programmatically create an artifact in ThoughtSpot. -. The MCP server processes the request and returns the result. -. The agent receives the response, constructs the output, and presents it to the user. -. User receives the response. The user can refine the analysis with follow-up queries for further exploration or ask a new question. + -For example, after receiving relevant questions and answers, the user can send follow-up questions or initiate a Liveboard creation request. +- Executes queries and generates visualizations +- Provides access to data +- Enforces data security with RLS and CLS rules. +|*End user* +|Interacts with an AI client or custom application, asks questions, and acts on results. +|====== -The following figure illustrates the sequence of workflows in a typical MCP Server integration setup: +The following figure illustrates the interaction between the user, agent, and MCP Server: [.widthAuto] -image::./images/mcp-integration.png[MCP integration] +image::./images/agents-mcp-server-arch.png[MCP integration] -== Get started -To get started with the integration, complete the steps described in the following sections. In this article, we'll integrate ThoughtSpot MCP Server with Claude and enable agentic interaction and workflows. +=== MCP tools and resources -=== Before you begin +ThoughtSpot MCP Server exposes the following tools and resources: -Before you begin, verify if your application setup has the following: +* `ping` + +Connectivity/health check. Used by the MCP host, such as Claude, Gemini, or ChatGPT, to verify whether it can reach the ThoughtSpot MCP Server and whether the server is available. -* Node.js version 22 or later is installed. -* A ThoughtSpot instance with 10.11.0.cl or later release version. You'll need administrator credentials to configure security settings or set up token-based authentication for your application users. -* Your application users have at least view access to the data source objects to query data and get answers. -* Row-level and column-level security rules are configured for data security and access control. +* `getDataSourceSuggestions` + +Suggests the most relevant ThoughtSpot data sources for a given query. -To enable secure communication between the MCP Server and your ThoughtSpot instance, configure the following settings: +* `getRelevantQuestions` + +Uses ThoughtSpot’s reasoning engine to turn a broad or high‑level user query into a set of concrete analytical questions that should be asked of the data. -. On your ThoughtSpot instance, navigate to *Develop* > *Customizations* > *Security Settings*. -. Add the MCP Server domain to CSP and CORS allowlists. -. If your setup uses SAML SSO logins, add the MCP Server domain to the SAML redirect domain allowlist. +* `getAnswer` + +Executes those analytical questions and returns structured data and answers. -//// -=== Configure security settings on ThoughtSpot +* `createLiveboard` + +Creates a ThoughtSpot Liveboard from a list of answers/questions, typically at the end of a conversation. It turns the conversational analysis into a Liveboard with visualizations. -To allow secure communication between the MCP Server and your ThoughtSpot instance, configure the following settings: - -. On your ThoughtSpot instance, navigate to *Develop* > *Customizations* > *Security Settings*. -. Add the MCP Server domain to CSP and CORS allowlists. -. If your setup uses SAML SSO logins, add the MCP Server domain to the SAML redirect domain allowlist. -//// - -=== Connect your client to the MCP Server - -If using a client that supports remote MCPs natively, such as Claude AI, use the following MCP server URL: ----- -https://agent.thoughtspot.app/mcp ----- +=== How it works -For OpenAI ChatGPT Deep Research, use the following URL: ----- -https://agent.thoughtspot.app/openai/mcp ----- +The agentic interactions in an orchestrated environment typically include these steps: -For MCP clients such as Claude Desktop, Windsurf, and Cursor that do not support a remote MCP Server, you must xref:mcp-integration.adoc#_connecting_other_mcp_clients_claude_desktop[add the MCP server configuration to your MCP client settings]. +. *User asks a question* + +A user sends a query in the chat interface to get data. For example, `What were the total sales of Jackets and Bags in the Northeast last year?`. + +Optionally, the user can specify the data context to generate a response. -=== Call MCP tools via LLM APIs +. *Agent calls `getDataSourceSuggestions` (optional)* + +If the user’s question doesn’t specify a data source, the agent can call `getDataSourceSuggestions`. +ThoughtSpot returns candidate data sources (models) with confidence scores and reasoning. -ThoughtSpot remote MCP Server acts as a wrapper over the ThoughtSpot APIs, making them available as tools for agent frameworks or LLMs such as Claude or OpenAI. It exposes specific tools that can be invoked by the LLMs in response to a user's query or prompt. +. *User's query is decomposed into sub-questions* + +To break the user’s query into smaller analytical questions, the agent calls `getRelevantQuestions`. + +In response to the agent's request, ThoughtSpot returns the AI-suggested, schema-aware questions that are easier to execute analytically. -To enable tool calling: +. *The query is processed for generating answers* + +For each suggested or chosen question, the agent calls `getAnswer`. ThoughtSpot returns the following: + +* Preview data for LLM reasoning. +* Visualization metadata, including an embeddable `frame_url`. +* `session_identifier` and `generation_number` for charts that are used as input for creating a Liveboard. -* Register the ThoughtSpot MCP Server endpoint as a tool provider in your LLM or agent framework. -* Provide an authentication (OAuth or token-based) token. + -You can generate an authentication token for a specific user from ThoughtSpot via a `POST` call to the `/api/rest/2.0/auth/token/full` REST API endpoint. + -Logged-in users can view the authentication token for their current session by using the `/api/rest/2.0/auth/session/token` REST API endpoint or by opening the following URL in a new tab on the web browser: -+ -`\https://{your-ts-instance}/api/rest/2.0/auth/session/token` - -For information about calling MCP tools using LLM APIs and methods, see these sections: - -* xref:mcp-integration.adoc#_claude_mcp_connector[Claude MCP connector] -* xref:mcp-integration.adoc#_openai_api_for_mcp_tool_calling[OpenAI API] -* xref:mcp-integration.adoc#_gemini_api[Gemini API and function calling] - -==== Claude MCP connector -The Claude’s MCP connector allows you to connect to remote MCP Servers directly from the Messages API. - -To connect to the ThoughtSpot remote MCP Server, specify the following properties in the API request: - -* `mcp_servers` + -In the `mcp_servers` array, include these parameters: + -** `type` + -__String__. Type. Specify the type as `url`. -** `url` + -__String__. The URL of the remote MCP Server endpoint. Must start with `https://`. -** `name` + -__String__. A unique identifier/label for the MCP Server. It will be used in the MCP tool call blocks to identify the server and to disambiguate tools to the LLM. -** `authorization_token` + -__String__. OAuth authorization token (`TS_AUTH_TOKEN`) along with the ThoughtSpot application instance URL. In the following example, the authorization token is added as a prefix, and the ThoughtSpot host URL is added with the `@` symbol. - -* `messages` + -In the `messages` array, specify a natural language question in `content` and the user role in `role`. - -* `model` + -LLM model to use for processing queries and interacting with tools. For example, claude-sonnet-4-20250514. - -[source,cURL] ----- -curl https://api.anthropic.com/v1/messages \ - -H "Content-Type: application/json" \ - -H "X-API-Key: $ANTHROPIC_API_KEY" \ - -H "anthropic-version: 2023-06-01" \ - -H "anthropic-beta: mcp-client-2025-04-04" \ - -d '{ - "model": "claude-sonnet-4-20250514", - "max_tokens": 1000, - "messages": [{ - "role": "user", - "content": "How do I increase my sales ?" - }], - "mcp_servers": [ - { - "type": "url", - "url": "https://agent.thoughtspot.app/bearer/mcp", - "name": "thoughtspot", - "authorization_token": "$TS_AUTH_TOKEN@my-thoughtspot-instance.thoughtspot.cloud" - } - ] - }' ----- - -//// -[source,TypeScript] ----- -import { Anthropic } from '@anthropic-ai/sdk'; - -const anthropic = new Anthropic(); - -const response = await anthropic.beta.messages.create({ - model: "claude-sonnet-4-5", - max_tokens: 1000, - messages: [ - { - role: "user", - content: "How do I increase my sales ?", - }, - ], - mcp_servers: [ - { - type: "url", - url: "https://agent.thoughtspot.app/bearer/mcp", - name: "thoughtspot", - authorization_token: "$TS_AUTH_TOKEN@my-thoughtspot-instance.thoughtspot.cloud", - }, - ], - betas: ["mcp-client-2025-04-04"], -}); ----- -//// - -The request uses Claude’s internal tool-calling mechanism to call the MCP endpoint with the provided token, discover the available tools, and retrieve data for the user's query. - -For more information, see the link:https://docs.claude.com/en/docs/agents-and-tools/mcp-connector[Claude MCP connector documentation, window=_blank]. - -==== OpenAI API for MCP tool calling -To enable tool calling and retrieve data from ThoughtSpot via OpenAI, you can use the Responses API endpoint. - -To connect to the ThoughtSpot remote MCP server, call the `\https://api.openai.com/v1/responses` API endpoint and specify the following properties in the API request: - -* `tools` + -In the `tools` array, include these parameters: - -** `server_url` + -The URL of the ThoughtSpot MCP Server. Use the full path of the MCP server URL. -** `server_label` + -Label of the ThoughtSpot MCP Server -** `type` + -Type of tool. For example, MCP. -** `headers` + -Additional headers needed for authentication, for example, the authentication token and URL of the ThoughtSpot host. - -* `input` + -Include the natural language query string as `input`. -* `model` + -LLM model to use for processing queries and interaction with tools. For example, GPT-5 or GPT 4.1. - -[source,cURL] ----- -curl https://api.openai.com/v1/responses \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer $OPENAI_API_KEY" \ - -d '{ - "model": "gpt-4.1", - "tools": [ - { - "type": "mcp", - "server_label": "thoughtspot", - "server_url": "https://agent.thoughtspot.app/bearer/mcp", - "headers": { - "Authorization": "Bearer $TS_AUTH_TOKEN", - "x-ts-host": "my-thoughtspot-instance.thoughtspot.cloud" - } - } - ], - "input": "How can I increase my sales ?" -}' ----- - -If the API request is successful, the LLM discovers the available MCP tools from the MCP Server endpoint. Once the model has access to these tools, it determines the tool to call depending on the user's query and what's in the model's context. - -For more information, see link:https://platform.openai.com/docs/guides/tools-connectors-mcp[Open AI Connectors and MCP Server Documentation]. - -==== Gemini API - -You can use the standard function calling mechanism provided in Gemini Python/Typescript SDK. The Gemini SDK supports MCP natively, and can pass tool definitions and call tools. - -In the following example, a session linked to the ThoughtSpot remote MCP Server is passed along with the authorization token and the ThoughtSpot host, so that the SDK can handle tool calling. - -[source,TypeScript] ----- -import { GoogleGenAI, FunctionCallingConfigMode , mcpToTool} from '@google/genai'; -import { Client } from "@modelcontextprotocol/sdk/client/index.js"; -import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; - -// Create server parameters for stdio connection -const serverParams = new StreamableHTTPClientTransport(new URL("https://agent.thoughtspot.app/bearer/mcp"), { - requestInit: { - headers: { - "Authorization": "Bearer $TS_AUTH_TOKEN", - "x-ts-host": "my-thoughtspot-instance.thoughtspot.cloud" - }, - } -}); - -const client = new Client( - { - name: "example-client", - version: "1.0.0" - } -); - -// Configure the client -const ai = new GoogleGenAI({}); - -// Initialize the connection between client and server -await client.connect(serverParams); - -// Send request to the model with MCP tools -const response = await ai.models.generateContent({ - model: "gemini-2.5-flash", - contents: `What is the weather in London in ${new Date().toLocaleDateString()}?`, - config: { - tools: [mcpToTool(client)], // uses the session, will automatically call the tool - // Uncomment if you **don't** want the sdk to automatically call the tool - // automaticFunctionCalling: { - // disable: true, - // }, - }, -}); -console.log(response.text) - -// Close the connection, -await client.close(); ----- - -For additional information, refer to the following resources: - -* For more information about Gemini API MCP tool calling, see link:https://ai.google.dev/gemini-api/docs/function-calling?example=meeting#mcp[Function calling with the Gemini API documentation, window=_blank]. -* A link:https://github.com/thoughtspot/developer-examples/tree/main/mcp/python-google-adk-trusted-auth[developer example with Google ADK and Python implementation] is also available in the link:https://github.com/thoughtspot/developer-examples[ThoughtSpot Developer Examples GitHub repository, window=_blank]. -* The ThoughtSpot MCP server can also be installed as a Gemini CLI extension. For more information, see link:https://github.com/google-gemini/gemini-cli[Gemini CLI, window=_blank]. - -=== For clients that do not support the remote MCP server - -For clients such as Claude Desktop, Windsurf, and Cursor, which do not support remote MCP servers, add the following configuration to your MCP client settings: - -[source,JSON] ----- -{ - "mcpServers": { - "ThoughtSpot": { - "command": "npx", - "args": [ - "mcp-remote", - "https://agent.thoughtspot.app/mcp" - ] - } - } -} ----- - -After updating the config file: - -. When prompted to connect your ThoughtSpot instance, add the URL of your application instance and complete authentication. -. Restart your MCP client to load the new configuration. +. *A Liveboard is generated from the results* (optional) + +The user can choose to save answers from the conversation in a ThoughtSpot Liveboard. For this workflow, the agent extracts `question`, `session_identifier`, and `generation_number` from each `getAnswer` response and calls `createLiveboard`. + +ThoughtSpot creates a Liveboard and returns identifiers and a `frame_url` for the Liveboard. + -If the connection is successful, you'll see an option to connect to ThoughtSpot and choose the data context. +During this interaction, users typically see a natural-language summary. When a Liveboard is created, a link to open the corresponding Liveboard in ThoughtSpot is generated. + -For example, the Claude Desktop shows the *Add to ThoughtSpot* as shown in the following figure: -+ -[.bordered] -[.widthAuto] -image::./images/claudeDesktop.png[Claude Desktop] +In custom applications, you can embed the visualizations generated from the interaction, load them inside iframe elements, and render interactive charts directly in your webpage. You can also add your own buttons or links, such as 'Save as Liveboard' or 'Pin this analysis', which call `createLiveboard` to create or persist a Liveboard that contains your current charts and analysis. -. Verify if the MCP tools are available. + -For example, on Claude Desktop, click the Search and tools icon to view the MCP tools. -+ -[.bordered] -[.widthAuto] -image::./images/mcp-tools-claude.png[Claude Desktop] +== Getting access to the MCP Server -. Select a data source to set the context of your query and verify the request and response flow. -+ -[.bordered] -[.widthAuto] -image::./images/query-response-claude.png[Claude query response] +ThoughtSpot MCP Server is available as an add-on with the following link:https://www.thoughtspot.com/pricing[license plans]: -. Try sending a query to create a Liveboard and verify if a Liveboard is created on your ThoughtSpot instance. -+ -[.bordered] -[.widthAuto] -image::./images/create-lb-claude.png[Liveboard creation] +* ThoughtSpot Enterprise Edition +* ThoughtSpot Embedded -== Configuration considerations and best practices +To learn more about subscription options, contact your ThoughtSpot Sales representative. -* Users must have at least view access to the data source. Otherwise, it may lead to empty results. -* Ensure that data is modeled. Large or complex data sources may impact response time. -* Streaming responses require client support for real-time updates. Ensure that your system is available to receive and process data. -* Each conversation is session-based. Ensure that session IDs are managed correctly in your integration. +== Next steps +* To learn how to connect existing MCP-aware tools such as Claude, ChatGPT, and Gemini, see xref:mcp-server-client-connection.adoc[Connecting MCP clients to ThoughtSpot MCP Server]. +* To learn how to integrate MCP Server with a custom chatbot or application, see xref:mcp-connect-custom-chatbot.adoc[Integrating MCP Server in a custom chatbot]. == Additional resources - -* Check the link:https://github.com/thoughtspot/mcp-server[MCP Server GitHub repo, window=_blank] for implementation instructions. -* Check your MCP client's documentation for instructions on how to connect to MCP Servers. -* In case of issues with connection or authentication, refer to the link:https://github.com/thoughtspot/mcp-server?tab=readme-ov-file#troubleshooting[troubleshooting steps^]. -* To understand ThoughtSpot's agentic analytics capabilities and AI APIs, refer to the following documentation: - -** link:https://docs.thoughtspot.com/cloud/latest/spotter[Spotter Documentation, window=_blank] -** link:https://docs.thoughtspot.com/cloud/latest/spotter-agent[Spotter Agent Documentation, window=_blank] -** xref:spotter-apis.adoc[Spotter AI APIs] +* For information about MCP, see link:https://modelcontextprotocol.io[Model Context Protocol specification, window=_blank]. +* For implementation details, see link:https://github.com/thoughtspot/mcp-server[MCP Server GitHub repository, window=_blank]. diff --git a/modules/ROOT/pages/mcp-server-client-connection.adoc b/modules/ROOT/pages/mcp-server-client-connection.adoc new file mode 100644 index 000000000..f1497b35c --- /dev/null +++ b/modules/ROOT/pages/mcp-server-client-connection.adoc @@ -0,0 +1,110 @@ += Connecting MCP Server to MCP clients +:toc: true +:toclevels: 3 + +:page-title: Connecting MCP Server to MCP clients +:page-pageid: connect-mcp-server-to-clients +:page-description: Learn how to connect Claude, ChatGPT, Gemini, and other MCP-aware clients to ThoughtSpot MCP Server with minimal configuration. + +If your application already has an AI-native experience or supports MCP-aware agents and LLMs, you can integrate ThoughtSpot analytics directly into your app's agentic experience by connecting the MCP Server to your client. + +In this plug-and-play integration, your application's chat interface and LLM orchestrate conversation sessions. The MCP Server exposes ThoughtSpot's analytics capabilities as tools, which your agent or LLM can invoke as needed. This approach allows you to bring ThoughtSpot analytics into your own AI-native experience and use it as a data and analytics provider through the MCP Server, while your system controls user interaction and orchestration logic. + +When your MCP client is connected to the ThoughtSpot MCP Server, the AI agent/LLM can: + +* Automatically discover ThoughtSpot MCP tools. +* Call the MCP tools to determine the data context and answer data questions. +* Create a Liveboard with the visualizations generated during the interaction. + + +[IMPORTANT] +==== +* Currently, the MCP Server integration does not support link:https://docs.thoughtspot.com/cloud/latest/spotter-versions[Spotter 3 capabilities]. +* In the plug-and-play integration mode, embedding visualizations is not supported. +==== + +== Before you begin +Before you begin, review the following prerequisites: + +* Ensure that your setup has access to a ThoughtSpot application instance with 10.11.0.cl or a later release version. +* Ensure that the users have the necessary permissions to view data from relevant models and tables in ThoughtSpot. Existing RLS/CLS rules on tables are enforced automatically in data source responses. To create charts or Liveboards from a conversation session, data download and content creation privileges are required. + +=== Connecting clients that support remote MCP servers +To connect to a client that supports remote MCP servers natively, add the MCP Server endpoint to your client's configuration settings. + +`https://agent.thoughtspot.app/mcp` + +For clients that require a bearer token for authentication, use the following URL format: + +`https://agent.thoughtspot.app/bearer/mcp` + +For OpenAI MCP and Responses API integration, use the following URL: + +`https://agent.thoughtspot.app/openai/mcp` + +For additional information about how to register a remote MCP Server, refer to your client's documentation. + +=== Connecting MCP Server to local MCP clients +For MCP clients that do not natively support configuring a remote MCP Server URL, you must use the `mcp-remote` component. For desktop clients that rely on local MCP components, ensure that Node.js version 22 or later is installed on your system. + +[source,json] +---- +{ + "mcpServers": { + "ThoughtSpot": { + "command": "npx", + "args": [ + "mcp-remote", + "https://agent.thoughtspot.app/mcp" + ] + } + } +} +---- + +== Authenticating users +In a plug-and-play integration, the most common way to authenticate users is through OAuth tokens. This method allows you to leverage your existing IdP or SSO configuration for ThoughtSpot login and rely on the platform to initiate a browser-based sign-in flow. + +=== OAuth flow +In a typical OAuth flow: + +* The ThoughtSpot MCP Server is configured as a connector/tool in the MCP client. +* When the user connects, the client redirects the user to ThoughtSpot to sign in. +* After successful login, the client stores the issued OAuth tokens and includes them with each MCP tool call to the ThoughtSpot MCP Server, which then calls ThoughtSpot on behalf of that user. + +=== OAuth client registration +OAuth clients can be registered in one of the following ways: + +* For MCP hosts that support Dynamic Client Registration (DCR), the OAuth client is registered automatically. +* For MCP hosts that do not support dynamic registration or that require static client credentials, you must manually register an OAuth client, obtain the OAuth client ID and OAuth client secret, and then configure these in the MCP host when adding ThoughtSpot as an MCP connector. The generated client details are only shown once and cannot be retrieved later. ++ +To register a client, visit link:https://agent.thoughtspot.app/clients[ThoughtSpot MCP OAuth Client Registration, window=_blank]. When registering the OAuth client, add your ThoughtSpot instance URL to the appropriate field. This ensures that users are not prompted to enter the instance URL during the OAuth flow, and the OAuth redirect returns correctly to your ThoughtSpot environment after login. + + +== Verifying integration +After the MCP Server is connected, some clients show *ThoughtSpot Data Sources* under a *Resources* or *Datasets* section. + +To verify the integration: + +. Start a chat session with the agent and verify the response. +. Verify that xref:mcp-integration.adoc#_mcp_tools_and_resources[MCP tools are being called] to generate responses. +. Prompt the agent to create a Liveboard from a query response and verify whether a Liveboard is added to your ThoughtSpot application. + +== Troubleshooting errors + +MCP Server is not connected:: + +* Verify if the MCP Server is reachable. +* Ensure that you have access to a ThoughtSpot instance. +* Ensure that there are no configuration errors. +* If the issue persists, verify the logs and contact ThoughtSpot Support for assistance. + +Authentication failure:: +If user authentication fails, or if the server returns HTTP 500, 401, or 403 status codes: +* Verify whether the MCP Server endpoint and ThoughtSpot host are correctly configured in your client and are reachable. +* Verify if the user session has expired. Log in to your ThoughtSpot application to start a new session. +* Verify whether the user has the necessary privileges to view data or create content. + +== Additional resources +* For information about the MCP Server features and architecture, see xref:mcp-integration.adoc[MCP Server integration]. +* To view the MCP Server code, go to the link:https://github.com/thoughtspot/mcp-server[MCP Server GitHub repository, window=_blank]. \ No newline at end of file diff --git a/modules/ROOT/pages/multi-tenancy-intro.adoc b/modules/ROOT/pages/multi-tenancy-intro.adoc index 47573e469..fa26b8cfb 100644 --- a/modules/ROOT/pages/multi-tenancy-intro.adoc +++ b/modules/ROOT/pages/multi-tenancy-intro.adoc @@ -27,7 +27,7 @@ At a basic level: * if the prod data warehouse is *single-tenanted* and each end customer’s data is separated in different databases or schemas, then a xref:single-tenant-data-models.adoc[prod Org per end customer deployment pattern] is used, with the final deployment from a "release" environment to each individual "end customer prod" environment -The actual level of multi-tenant Org separation is totally up to ThoughtSpot Customer, dependent on your business requirements +The actual level of multi-tenant Org separation is totally up to ThoughtSpot Customer, dependent on your business requirements. //// == Related information diff --git a/modules/ROOT/pages/publish-api.adoc b/modules/ROOT/pages/publish-api.adoc index 323b38239..9d8f65d5d 100644 --- a/modules/ROOT/pages/publish-api.adoc +++ b/modules/ROOT/pages/publish-api.adoc @@ -1,4 +1,4 @@ -= Publish objects to Orgs += Publishing content to Orgs via APIs :toc: true :toclevels: 2 diff --git a/modules/ROOT/pages/publishing-overview.adoc b/modules/ROOT/pages/publishing-overview.adoc index b82b057f2..31899b3e3 100644 --- a/modules/ROOT/pages/publishing-overview.adoc +++ b/modules/ROOT/pages/publishing-overview.adoc @@ -6,7 +6,9 @@ :page-pageid: publish-data-overview :page-description: Use the publishing feature to distrubute and propagete objects to Orgs within a ThoughtSpot instance. -The publishing feature [beta betaBackground]^Beta^ enables administrators to efficiently manage and distribute ThoughtSpot metadata objects across multiple Orgs within a multi-tenant instance. +[earlyAccess eaBackground]#Early Access# + +The publishing feature enables administrators to efficiently manage and distribute ThoughtSpot metadata objects across multiple Orgs within a multi-tenant instance. Unlike the deployment method that relies on TML import and Git integration, publishing allows administrators to create an object in the Primary Org and publish it directly to target Orgs without generating duplicate copies. It also allows dynamic customization of the underlying Table or Connection properties using variables. @@ -14,7 +16,7 @@ Starting with the 10.10.0.cl release, ThoughtSpot provides a set of REST APIs fo [IMPORTANT] ==== -The publishing feature, including the REST APIs for variable creation and update, metadata parameterization, and publishing content across Orgs, is in beta and turned off by default on ThoughtSpot instances. To enable this feature on your instance, contact ThoughtSpot Support. +Publishing to Orgs is an Early Access feature and is disabled by default on ThoughtSpot instances. To enable this feature on your instance, contact ThoughtSpot Support. ==== == When to use publishing feature @@ -77,8 +79,6 @@ Note the following feature limitations in the beta version: * Only ThoughtSpot administrators with access to all Orgs can publish objects. * Objects can be published only from the Primary Org to other Orgs. * In the target Orgs, published objects are available in read-only mode. The original object in the Primary Org remains editable only by the cluster administrator. -* Spotter functionality is not supported for published objects. -* Search data indexing is disabled for published tables. * Git integration is not supported for published objects. [NOTE] diff --git a/modules/ROOT/pages/rest-api-java-sdk.adoc b/modules/ROOT/pages/rest-api-java-sdk.adoc index db8adb37c..cf0b4abaf 100644 --- a/modules/ROOT/pages/rest-api-java-sdk.adoc +++ b/modules/ROOT/pages/rest-api-java-sdk.adoc @@ -281,6 +281,7 @@ Note the recommendation of Java SDK: [options='header'] |==== |ThoughtSpot release version|Supported SDK version +a|ThoughtSpot Cloud: 26.2.0.cl | v2.21.0 or later a|ThoughtSpot Cloud: 10.15.0.cl | v2.20.0 or later a|ThoughtSpot Cloud: 10.14.0.cl | v2.19.0 or later a|ThoughtSpot Cloud: 10.13.0.cl | v2.18.0 or later diff --git a/modules/ROOT/pages/rest-api-sdk-typescript.adoc b/modules/ROOT/pages/rest-api-sdk-typescript.adoc index ce057f24b..cf9e65de5 100644 --- a/modules/ROOT/pages/rest-api-sdk-typescript.adoc +++ b/modules/ROOT/pages/rest-api-sdk-typescript.adoc @@ -203,6 +203,7 @@ Note the version recommendations for your ThoughtSpot instances: [options='header'] |==== |ThoughtSpot release version|Recommended SDK version +a|ThoughtSpot Cloud: 26.2.0.cl | v2.21.0 or later a|ThoughtSpot Cloud: 10.15.0.cl | v2.20.0 or later a|ThoughtSpot Cloud: 10.14.0.cl | v2.19.0 or later a|ThoughtSpot Cloud: 10.13.0.cl | v2.18.0 or later diff --git a/modules/ROOT/pages/rest-api-v2-reference.adoc b/modules/ROOT/pages/rest-api-v2-reference.adoc index ab61008f9..4db2d74f5 100644 --- a/modules/ROOT/pages/rest-api-v2-reference.adoc +++ b/modules/ROOT/pages/rest-api-v2-reference.adoc @@ -159,7 +159,7 @@ a|`POST /api/rest/2.0/connection/update` [tag redBackground]#DEPRECATED# + Updates a connection object. -__Note: This API endpoint is deprecated in ThoughtSpot 10.4.0.cl and later versions. To update a connection, use `/api/rest/2.0/connections/update/{connection_identifier}`. __ +__Note: This API endpoint is deprecated in ThoughtSpot 10.4.0.cl and later versions. To update a connection, use `POST /api/rest/2.0/connections/{connection_identifier}/update`. __ |ThoughtSpot Cloud: __9.2.0.cl or later__ + ThoughtSpot Software: __9.5.0.sw or later__ a| @@ -896,11 +896,19 @@ ThoughtSpot Software: __9.5.1.sw or later__ a| +++Try it out +++ +a|ThoughtSpot Cloud: __10.14.0.cl or later__ a| +++Try it out +++ a|`POST /api/rest/2.0/system/preferences/communication-channels/search` + Allows searching communication channel preferences. -ThoughtSpot Cloud: __10.14.0.cl or later__ a| +++Try it out +++ +a|ThoughtSpot Cloud: __10.14.0.cl or later__ a| +++Try it out +++ + +a|`POST /api/rest/2.0/system/security-settings/configure` + +Allows configuring security settings. +a|ThoughtSpot Cloud: __26.2.0.cl or later__ a| +++Try it out +++ + +a|`POST /api/rest/2.0/system/security-settings/search` + +Allows fetching security settings. +a|ThoughtSpot Cloud: __26.2.0.cl or later__ a| +++Try it out +++ |===== diff --git a/modules/ROOT/pages/rest-apiv2-changelog.adoc b/modules/ROOT/pages/rest-apiv2-changelog.adoc index b6e1c54e0..5b817a8e7 100644 --- a/modules/ROOT/pages/rest-apiv2-changelog.adoc +++ b/modules/ROOT/pages/rest-apiv2-changelog.adoc @@ -8,6 +8,48 @@ This changelog lists the features and enhancements introduced in REST API v2.0. For information about new features and enhancements available for embedded analytics, see xref:whats-new.adoc[What's New]. +== Version 26.2.0.cl, February 2026 + +=== Security settings APIs +This release introduces the following Security settings APIs: + +* `POST /api/rest/2.0/system/security-settings/configure` + +Allows configuring security settings at the Org level or for all Orgs on a ThoughtSpot instance. +* `POST /api/rest/2.0/system/security-settings/search` + +Gets a list of security settings configured on specific Org or for all Orgs on a ThoughtSpot instance. + +For more information, see xref:security-settings.adoc[Security Settings]. + +=== Connection API +ThoughtSpot administrators can now revoke OAuth refresh tokens for users who no longer require access to a data warehouse connection via the `/api/rest/2.0/connections/{connection_identifier}/revoke-refresh-tokens` API endpoint. When a token is revoked, the affected user's session for that connection is terminated, and they must re-authenticate to regain access. + +=== Connection configuration API enhancements +You can now include `same_as_parent` and `policy_process_options` attributes in your API request to `/api/rest/2.0/connection-configurations/create` and `/api/rest/2.0/connection-configurations/{configuration_identifier}/update` endpoints. + +The `same_as_parent` parameter specifies if the configuration should inherit settings from its parent. The `policy_process_options` attribute can be used to define additional policy or processing options for the connection, to allow granular control over connection behavior. + +=== Liveboard Report API enhancements +You can now download Liveboard reports in the CSV and XLSX formats through the `POST /api/rest/2.0/report/liveboard` API endpoint. Both these options are Early Access features. + +For more information, see xref:data-report-v2-api.adoc[Data and Report APIs]. + +=== Email customization API enhancements + +The `template_properties` parameter now has two additional elements for email template customization: + +* `contact_support_url` to add a customized link for contacting customer support. +* `hide_contact_support_url` to hide the option of adding a link for customer support. + +=== System configuration API enhancements +The API response from the `/api/rest/2.0/system/config` endpoint indicates whether SAML or Okta authentication is enabled on the system. + +=== User API enhancements + +* `POST /api/rest/2.0/users/import` + +The `preferred_locale` parameter allows configuring the preferred locale for users being imported via API request. +* `POST /api/rest/2.0/users/search` + +The `include_variable_values` parameter in the API request allows including variable values in the search response. The variable values can be assigned for a user via xref:abac_rls-variables.adoc[ABAC tokens] or xref:variables.adoc#_define_values_and_scope_for_variables[variable API documentation]. + == Version 10.15.0.cl, December 2025 === Spotter APIs @@ -573,15 +615,6 @@ You can now assign the `CAN_MANAGE_VERSION_CONTROL` role using any of the follow The `CAN_MANAGE_VERSION_CONTROL` Role privilege is required for Git integration with ThoughtSpot. -//// -=== Connections - -The following API endpoints available for data connections: - -* `POST /api/rest/2.0/connections/update/{connection_identifier}` -* `POST /api/rest/2.0/connections/delete/{connection_identifier}` -//// - == Version 9.12.0.cl, May 2024 ==== New features diff --git a/modules/ROOT/pages/security-settings.adoc b/modules/ROOT/pages/security-settings.adoc index 050132cc0..80a485d06 100644 --- a/modules/ROOT/pages/security-settings.adoc +++ b/modules/ROOT/pages/security-settings.adoc @@ -1,13 +1,14 @@ = Security settings :toc: true -:toclevels: 2 +:toclevels: 3 :page-title: Security settings :page-pageid: security-settings :page-description: Security settings for embedding -The **Security Settings** page in ThoughtSpot UI allows administrators and developers to configure allowlists for Content Security Policy (CSP) and Cross-origin Resource Sharing (CORS), authentication attributes, and access control settings. +ThoughtSpot allows administrators and developers to configure allowlists for Content Security Policy (CSP) and Cross-origin Resource Sharing (CORS), authentication attributes, and access control settings. +These settings can be done via the **Security Settings** page in the ThoughtSpot UI, or through REST APIs v2, by sending a `POST` request to `POST /api/rest/2.0/system/security-settings/configure` API endpoint. == Overview Most web browsers block cross-site scripting, cross-domain requests, and third-party cookies by default. Web browsers also have built-in security mechanisms such as same-origin and content security policies. These policies restrict how applications and scripts from one origin (domain) can interact with the resources hosted on another origin (domain). To ensure data security and a seamless user experience in embedding applications, configure the settings described in this section. @@ -21,9 +22,9 @@ To avoid this issue, ThoughtSpot recommends the following: * If you are using a ThoughtSpot Cloud instance, set up your instance to the same domain as your host application. For more information, see link:https://docs.thoughtspot.com/cloud/latest/custom-domains[Custom domain configuration, window=_blank]. * If you are using authentication methods that rely on cookies, xref:_enable_partition_cookies[enable partition cookies]. -== Security settings in ThoughtSpot +== Configure security settings -Users with administration privileges can configure security settings on the Security settings page of the ThoughtSpot UI. Note that the following settings on the **Security Settings** page will appear as locked for ThoughtSpot Analytics application users and will require an embedding license: +Users with administration privileges can configure security settings on the Security settings page of the ThoughtSpot UI, or by sending a `POST` request to `POST /api/rest/2.0/system/security-settings/configure` API endpoint. Note that the following settings on the **Security Settings** page will appear as locked for ThoughtSpot Analytics application users and will require an embedding license: * xref:security-settings.adoc#csp-viz-embed-hosts[CSP visual embed hosts] * xref:security-settings.adoc#cors-hosts[CORS whitelisted domains] @@ -31,22 +32,22 @@ Users with administration privileges can configure security settings on the Secu * xref:configure-saml.adoc#saml-redirect[SAML redirect domains] * xref:trusted-authentication.adoc[Trusted authentication] -=== Security settings for Orgs +==== Security settings for Orgs On ThoughtSpot instances with Orgs, security settings can be managed at two levels: -* Global settings for all Orgs + +* Global settings for all Orgs (cluster level) + Cluster administrators can configure security settings globally for all Orgs. On ThoughtSpot instances with Orgs, the *Develop* page opens in the `Primary Org` context, unless you are accessing the Develop tab from a specific Org context. To configure settings for all Orgs, you must switch to *All Orgs* context. * Org-level settings + -Cluster and Org administrators can configure security settings for a specific Org. Configuration modifications at the Org level do not affect other Orgs or the default settings applied at the All Orgs level. +Cluster and Org administrators can configure security settings for the current logged-in Org. Configuration modifications at the Org level do not affect other Orgs or the default settings applied at the All Orgs level. The following table shows the settings available at the All Orgs and per-Org levels: [width="100%" cols="5,7,7,7"] [options='header'] |===== -||Configuration setting|All Orgs level |Per-Org level +|||All Orgs level (cluster level) |Per-Org level .6+|CSP allowlists | **CSP visual embed hosts** a| [tag greenBackground tick]#Yes# a| [tag redBackground tick]#No# |**CSP connect-src domains** a| [tag greenBackground tick]#Yes# a| @@ -86,11 +87,11 @@ Each Org can have a separate secret key, which can be used to authenticate users ==== -== CSP allowlists +=== CSP allowlists To allow another application to embed ThoughtSpot, you must xref:security-settings.adoc#csp-viz-embed-hosts[add your host application domain as a CSP Visual Embed host]. -To allow xref:security-settings.adoc#csp-connect-src[loading script interfaces and JavaScript events for custom actions], or xref:security-settings.adoc##csp-trusted-domain[to enable importing resources from other sites], add the source domain URLs as trusted hosts in the respective CSP allowlist. +To allow xref:security-settings.adoc#csp-connect-src[loading script interfaces and JavaScript events for custom actions], or xref:security-settings.adoc#csp-trusted-domain[to enable importing resources from other sites], add the source domain URLs as trusted hosts in the respective CSP allowlist. [NOTE] ==== @@ -98,7 +99,7 @@ If your instance has Orgs configured, note that the default Org on your instance ==== [#csp-viz-embed-hosts] -=== Add CSP visual embed hosts +==== Add CSP visual embed hosts To allow your host domain to set the `frame-ancestors` CSP policy header and embed a ThoughtSpot object within your application frame, add your application domain as a CSP visual embed host. . On your ThoughtSpot application instance, go to *Develop* page. @@ -108,13 +109,36 @@ To allow your host domain to set the `frame-ancestors` CSP policy header and emb . In the *CSP visual embed hosts* text box, add the domain names. For valid domain name formats, See xref:security-settings.adoc#csp-cors-hosts[Domain name format for CSP and CORS configuration]. . Click *Save changes*. + [NOTE] ==== Only users with a valid embed license can add Visual Embed hosts. ==== +*Through the REST API v2* + +Send a `POST` request to `POST /api/rest/2.0/system/security-settings/configure` API endpoint. Add your application domain as a CSP visual embed host for your ThoughtSpot application instance by entering valid values for the parameter `visual_embed_hosts`. + +[source,cURL] +---- +curl -X POST 'https://{ThoughtSpot-Host}/api/rest/2.0/system/security-settings/configure' \ + -H 'Authorization: Bearer {access-token}' \ + -H 'Content-Type: application/json' \ + --data-raw '{ + "cluster_preferences": { + "csp_settings": { + "visual_embed_hosts": [ + "www.thoughtspot.com", + "mysite.com:8080", + "http://localhost:8080" + ] + } + } + }' +---- + [#csp-connect-src] -=== Add URLs to CSP connect-src allowlist +==== Add URLs to CSP connect-src allowlist If you plan to use a custom action or webhook to send data to an external endpoint or application, you must add the domains of the target endpoints or applications to the `CSP connect-src` allowlist. . On your ThoughtSpot application instance, go to *Develop* page. @@ -124,8 +148,31 @@ If you plan to use a custom action or webhook to send data to an external endpoi . In the *CSP connect-src domains* text box, add the domain names. For valid domain name formats, See xref:security-settings.adoc#csp-cors-hosts[Domain name format for CSP and CORS configuration]. . Click *Save changes*. + +*Through the REST API v2* + +Send a `POST` request to `POST /api/rest/2.0/system/security-settings/configure` API endpoint. Add domains of the target endpoints or applications to the `connect_src_urls` parameter for your ThoughtSpot application instance. + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/system/security-settings/configure' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Content-Type: application/json' \ +--data-raw '{ +"cluster_preferences": { + "csp_settings": { + "connect_src_urls": [ + "localhost:3000", + "thoughtspot.com" + ] + } +} +}' +---- + [#csp-trusted-domain] -=== Add other trusted domains +==== Add other trusted domains To import images, fonts, and stylesheets from external sites, or load the content from an external site using an iFrame element, you must add the source URLs as trusted domains in the CSP allowlist. For example, in the Liveboard Note tiles, if you want to insert an image from an external site or embed content from an external site in an iFrame, you must add domain URLs of these sites to the CSP allowList. Similarly, to import fonts and custom styles from an external source, you must add the source URL as a trusted domain in ThoughtSpot. @@ -148,7 +195,45 @@ Add the domains from which you want host scripts. For more information, see xref Add the iframe source URL domains. //// -=== Add permitted iFrame domains + +*Through the REST API v2* + +Send a `POST` request to `POST /api/rest/2.0/system/security-settings/configure` API endpoint. Add source URLs of sites, where from you can import images, fonts, and stylesheets, as trusted domains to the `img_src_urls`, `font_src_urls`, `style_src_urls`, `script_src_urls` parameters. + +[NOTE] +To be able to add allowed urls for custom JavaScript through `script_src_urls`, `enabled` should be set to `true` for script-src customization. + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/system/security-settings/configure' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Content-Type: application/json' \ +--data-raw '{ +"cluster_preferences": { + "csp_settings": { + "font_src_urls": [ + "*.thoughtspot.com" + ], + "img_src_urls": [ + "thoughtspot.com/products" + ], + "script_src_urls": { + "enabled": true, + "urls": [ + "thoughtspot:*" + ] + }, + "style_src_urls": [ + "*" + ] + } +} +}' +---- + + +==== Add permitted iFrame domains Features such as link:https://docs.thoughtspot.com/software/latest/liveboard-notes[Liveboard Note tiles, window=_blank] and link:https://docs.thoughtspot.com/cloud/latest/chart-custom[custom charts, window=_blank] allow iFrame content. If you are planning to embed content from an external site, make sure the domain URLs of these sites are added to the iFrame domain allowlist: . On your ThoughtSpot application instance, go to *Develop* page. @@ -159,8 +244,29 @@ Features such as link:https://docs.thoughtspot.com/software/latest/liveboard-not . Click *Save changes*. +*Through the REST API v2* + +Send a `POST` request to `POST /api/rest/2.0/system/security-settings/configure` API endpoint. Add domain URLs of external sites using iFrame content are added to the `iframe_src_urls` parameter for your ThoughtSpot application instance. + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/system/security-settings/configure' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Content-Type: application/json' \ +--data-raw '{ +"cluster_preferences": { + "csp_settings": { + "iframe_src_urls": [ + "www.thoughtspot.com" + ] + } +} +}' +---- + [#cors-hosts] -=== Enable CORS +==== Enable CORS To allow your embedding application to call ThoughtSpot, access its resources, and render embedded content, add your host application domain URL as a trusted host for CORS. @@ -182,8 +288,35 @@ To add domain names to the CORS allowlist, follow these steps: . In the *CORS whitelisted domains* text box, add the domain names. For valid domain name formats, See xref:security-settings.adoc#csp-cors-hosts[Domain name format for CSP and CORS configuration]. . Click *Save changes*. +*Through the REST API v2* + +Send a `POST` request to `POST /api/rest/2.0/system/security-settings/configure` API endpoint. Add CORS allowlist for cross-domain communication to the parameter `cors_whitelisted_urls` for the cluster or for the Org. + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/system/security-settings/configure' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Content-Type: application/json' \ +--data-raw '{ + "org_preferences": [ + { + "cors_whitelisted_urls": [ + "localhost" + ] + } + ], + "cluster_preferences": { + "cors_whitelisted_urls": [ + "mysite.com" + ] + } +}' +---- + + [#csp-cors-hosts] -=== Domain name format for CSP and CORS configuration +==== Domain name format for CSP and CORS configuration [IMPORTANT] ==== @@ -195,7 +328,8 @@ To add domain names to the CORS allowlist, follow these steps: ** CORS hosts — The UI allows adding a domain URL with the protocol (`http/https`). If the domain URLs are using `https`, you can exclude the protocol in domain URL strings, because ThoughtSpot assigns `https` to the URLs by default. ** For localhost and non-HTTPS URLs — For non-HTTPs domains or localhost such as `localhost:3000`, if you add the domain without the protocol, the `https` protocol will be assigned to the URL by default. Due to this, the localhost domain with `http` (`\http://localhost:3000`) might result in a CSP or CORS error. Therefore, include the `http` protocol in the domain name strings for non-HTTPS domains and localhost. * **Port**: If your domain URL has a non-standard port such as 8080, specify the port number in the domain name string. - +* **Websocket endpoints**: + +You can add Websocket (`wss://`) endpoints for external tool script integrations, for example, tools that open WebSocket connections from the browser. Only hosts explicitly listed with `wss://` are permitted. ==== The following table shows the valid domain name strings for the CORS and CSP allowlists. @@ -279,13 +413,49 @@ a| Domain names with space, backslash (\), and wildcard (*). a|+++Wildcard (*) for port+++ `thoughtspot:*`|[tag greenBackground tick]#✓# Supported |[tag greenBackground tick]#✓# Supported 2*|[tag greenBackground tick]#✓# Supported +a|Websocket URLs + +`wss://`| [tag greenBackground tick]#✓# Supported |[tag greenBackground tick]#✓# Supported |[tag redBackground tick]#x# Not Supported| [tag greenBackground tick]#✓# Supported +| |==== -== Block access to non-embedded ThoughtSpot pages +=== Block access to non-embedded ThoughtSpot pages If you have embedded ThoughtSpot content in your app, you may want your users to access only the ThoughtSpot pages embedded within the context of your host app. ThoughtSpot allows administrators to restrict user access to non-embedded application pages from the embedding application context or selectively grant access to specific user groups. For information, see xref:selective-user-access.adoc[Control User Access]. -== Enable partitioned cookies +*Through the REST API v2* + +Send a `POST` request to `POST /api/rest/2.0/system/security-settings/configure` API endpoint. Set `block_full_app_access` to `true` to restrict user access to non-embedded application pages from the embedding application context. Enter values for `groups_identifiers_with_access` to selectively grant access to specific user groups. + +[NOTE] +To be able to gives access through `groups_identifiers_with_access`, the selective user access feature must be turned on in the *Admin settings*. + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/system/security-settings/configure' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Content-Type: application/json' \ +--data-raw '{ +"cluster_preferences": { + "non_embed_access": { + "block_full_app_access": false + } +}, +"org_preferences": [ + { + "non_embed_access": { + "block_full_app_access": true, + "groups_identifiers_with_access": [ + "group1" + ] + } + } + ] +}' +---- + + +=== Enable partitioned cookies Many web browsers do not allow third-party cookies. If you are using authentication methods that rely on cookies, users will not be able to access the embedded content when browsers block third-party cookies. Therefore, ThoughtSpot recommends using xref:trusted-auth-sdk.adoc[cookieless authentication] in production environments. However, if your implementation uses cookie-based authentication or xref:embed-authentication.adoc#none[AuthType.None], ensure that you enable partitioned cookies: @@ -304,5 +474,40 @@ With partitioned cookies enabled, when a user logs in to ThoughtSpot and accesse Safari blocks all third-party cookies and does not support partitioned cookies. You can switch to a different browser that supports partitioned cookies, or use cookieless authentication in your embedding implementation. ==== -== Trusted authentication +*Through the REST API v2* + +Send a `POST` request to `POST /api/rest/2.0/system/security-settings/configure` API endpoint. Set `enable_partitioned_cookies` to `true` to ensure a cookie is set with the partitioned attribute for applications using cookie-based authentication . + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/system/security-settings/configure' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Content-Type: application/json' \ +--data-raw '{ +"cluster_preferences": { + "enable_partitioned_cookies": true +} +}' +---- + +=== Trusted authentication See xref:trusted-authentication.adoc[Trusted authentication] and xref:_secret_key_management[Secret key management]. + +[NOTE] +Trusted authentication is not supported through the REST APIs v2. + +== Retrieve security settings +You can retrieve the security settings for your ThoughtSpot instance by sending a `POST` request to `POST /api/rest/2.0/system/security-settings/search` API endpoint. +You can define the `scope` to get the cluster-level settings (`scope` as `CLUSTER`), or the Org-level settings for the current Org (`scope` as `ORG`). If the `scope` is not specified, the API returns both cluster and Org settings based on user privileges. + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/system/security-settings/search' \ + -H 'Authorization: Bearer {access-token}'\ + -H 'Content-Type: application/json' \ +--data-raw '{ + "scope": "CLUSTER" +}' +---- diff --git a/modules/ROOT/pages/selective-user-access.adoc b/modules/ROOT/pages/selective-user-access.adoc index 42cccbf41..a6ce63cb8 100644 --- a/modules/ROOT/pages/selective-user-access.adoc +++ b/modules/ROOT/pages/selective-user-access.adoc @@ -75,7 +75,7 @@ If *Block non-embed full app access* is turned on in *All Orgs*, it will be appl For ThoughtSpot releases 10.5.0.cl or earlier, if you have embedded ThoughtSpot using Visual Embed SDK v1.22.0 or later, the `blockNonEmbedFullAppAccess` property in the SDK is set to `true` by default. Due to this, your application users cannot access or navigate to the ThoughtSpot application experience outside the context of your app. -You can turn on the selective user access feature by going to *Admin* > *Early access features* > *Selective User Access* and editing the status to *Enabled*. +You can turn on the selective user access feature by going to *Admin settings* > *Application Settings* > *Administration* > *Selective User Access* and editing the status to *Enabled*. The selective user access granted through the *Security Settings* overrides the `blockNonEmbedFullAppAccess` SDK settings. It is highly recommended that you switch to selective user access for better security and uninterrupted operations. Support for the SDK `blockNonEmbedFullAppAccess` will end soon. diff --git a/modules/ROOT/pages/spotter-apis.adoc b/modules/ROOT/pages/spotter-apis.adoc index 84cb5009c..cfcd7b5a2 100644 --- a/modules/ROOT/pages/spotter-apis.adoc +++ b/modules/ROOT/pages/spotter-apis.adoc @@ -66,9 +66,9 @@ xref:spotter-apis.adoc#_send_queries_to_a_conversation_session_with_spotter_agen __Available on ThoughtSpot Cloud instances from 10.15.0.cl onwards__. |Data literacy and guided analysis a| -//* `POST /api/rest/2.0/ai/data-source-suggestions` + -//xref:spotter-apis.adoc#_get_data_source_suggestions[Returns a list of relevant data sources], such as Models, based on a query and thus helping users and agents choose the most appropriate data source for analytics. + -//__Available on ThoughtSpot Cloud instances from 10.15.0.cl onwards__. +* `POST /api/rest/2.0/ai/data-source-suggestions` + +xref:spotter-apis.adoc#_get_data_source_suggestions[Returns a list of relevant data sources], such as Models, based on a query and thus helping users and agents choose the most appropriate data source for analytics. + +__Available on ThoughtSpot Cloud instances from 10.15.0.cl onwards__. * `POST /api/rest/2.0/ai/relevant-questions/`] + xref:spotter-apis.adoc#_get_relevant_questions[Decomposes a user query] into relevant sub-questions. Guides users to explore data more deeply for a comprehensive analysis. + @@ -160,43 +160,6 @@ If the API request is successful, a conversation identifier is created. Note the ---- -//// -The following AI API endpoints allow you to initiate a conversation session with Spotter: - -If the API request is successful, the following data is sent in the API response: - -* `session_identifier` + -GUID of the Answer session. -* `generation_number` + -Number assigned to the Answer session. -* `message_type` -Type of response received for the query. For example, `TSAnswer` (ThoughtSpot Answer). -* `visualization_type` + -The data format of the generated Answer; for example, a chart or table. When you download this Answer, the data will be exported in the format indicated by the `visualization_type`. -* `tokens` + -Tokens generated from the natural language search query specified in the API request. These tokens can be used as input to the `/api/rest/2.0/ai/conversation/create` endpoint to set the context for a conversation session. - -[NOTE] -==== -Note the session ID and generation number. To export the result generated from this API call, send these attributes in the `POST` request body to the `/api/rest/2.0/report/answer` endpoint. -==== - -[source,JSON] ----- -[{ - "session_identifier": "57784fa1-10fa-431d-8d82-a1657d627bbe", - "generation_number": 2, - "message_type": "TSAnswer", - "visualization_type": "Undefined", - "tokens": "[product], [region] = [region].'west', sort by [sales] descending" -}] ----- - -== Conversational analytics with Spotter agent -Spotter agent is an advanced, agentic version of Spotter, which supports context-aware interactions, data literacy features, and follow-up conversations for deeper analytics. Spotter agent can be used for complex reasoning and agentic interactions in an orchestrated framework. - -//// - === Send a query to a conversation session To send a question to an ongoing conversation session or ask follow-up questions to , send a `POST` request body with conversation ID and query text to the `POST /api/rest/2.0/ai/conversation/{conversation_identifier}/converse` API endpoint. @@ -1027,7 +990,7 @@ The following example shows the response text contents for the `answer` message The session ID and generation number serve as the data context for the Answer. You can use this information to create a new conversation session using `/api/rest/2.0/ai/agent/conversation/create`, or download the answer via the `/api/rest/2.0/report/answer` API endpoint. [#process_results] -== Process results generated from Spotter APIs +== Processing results generated from Spotter APIs To export or download the Answer data generated by the Spotter APIs, use the xref:data-report-v2-api.adoc#exportSpotterData[Answer report] API. [NOTE] @@ -1036,9 +999,6 @@ Using tokens generated by the Spotter API in a xref:data-report-v2-api.adoc#_sea ==== == Data literacy and query assistance -The query assistance APIs help users who may need assistance with exploring and analyzing data effectively. - -//// The query assistance APIs help users find the appropriate dataset for a given query string, suggest what questions can be asked, and return example questions. These APIs are specifically designed to improve data literacy for users who may not be familiar with the underlying data, making it easier for them to explore and analyze data effectively. === Get data source suggestions @@ -1049,7 +1009,7 @@ The `POST /api/rest/2.0/ai/data-source-suggestions` API provides relevant data s [width="100%" cols="2,4"] [options='header'] -|===== +|==== |Parameter| Description |`metadata_context` a| Required. Specify one of the following attributes to set the metadata context: @@ -1069,6 +1029,7 @@ __Optional__ | __Integer__. Sets a limit on the number of sub-questions to retur __Optional__| __Boolean__. When set to `true`, disables cache and forces fresh computation. |`ai_context` + __Optional__. a| Additional context to guide the response. Define the following attributes as needed: +|==== ==== Example request @@ -1125,8 +1086,6 @@ The data source ID, name, and description for each recommended data source. * `reasoning` + Reason provided by the LLM to explain why each data source was recommended. -//// - === Get relevant questions The `/api/rest/2.0/ai/relevant-questions/` API endpoint breaks down a user-submitted query into relevant sub-questions. It accepts the original query and optional additional context, then generates a set of related questions to help users explore their data comprehensively. diff --git a/modules/ROOT/pages/spottercode-integration.adoc b/modules/ROOT/pages/spottercode-integration.adoc new file mode 100644 index 000000000..bfdf97347 --- /dev/null +++ b/modules/ROOT/pages/spottercode-integration.adoc @@ -0,0 +1,139 @@ += Integrate SpotterCode with your IDE +:toc: true +:toclevels: 2 + +:page-title: SpotterCode integration gude +:page-pageid: integrate-SpotterCode +:page-description: This document provides a comprehensive, step-by-step approach to integrating SpotterCode with your development environment + +Connecting your IDE to ThoughtSpot's SpotterCode is easy. All you need is the SpotterCode MCP Server URL. This guide will walk you through the process of adding SpotterCode to your IDE. + +== Before you begin + +* Ensure that your IDE is AI-native and supports chat sessions with AI models. +* Ensure that you have the necessary permissions to configure MCP servers on your IDE. +* Ensure that the latest version of Node.js is installed in your environment. This is required for building embedding code with the SDK. +* Ensure that you have access to a ThoughtSpot instance and can view the objects and resources that you want to embed or access via the REST API. + +== Integrate SpotterCode with Cursor + +. To add the MCP server URL to your Cursor settings, go to **Cursor Settings** > **Tools and MCP**. Cursor opens the `mcp.json` file. +. Add the SpotterCode MCP Server URL as a remote MCP server. For information about configuring MCP servers in Cursor, refer to the link:https://cursor.com/docs/context/mcp[Cursor Documentation, window=_blank]. ++ +[source,JSON] +---- +{ + "mcpServers": { + "SpotterCode": { + "url": "https://spottercode.thoughtspot.app/mcp" + } + } +} +---- +. Click *Save* and close the `mcp.json` file. This will install the SpotterCode MCP server and tools for the AI models on Cursor to execute. + +== Integrate SpotterCode with Visual Studio Code + +Although you can configure the MCP server in Visual Studio Code, to start a chat session with the AI agent, you'll need GitHub Copilot or a similar extension. + +To add an MCP Server to Visual Studio Code, you can use the Extensions view, the `MCP: Add Server` command via command palette, or directly edit the `mcp.json` file in your workspace configuration. + +[source,JSON] +---- +{ + "servers": { + "SpotterCode": { + "url": "https://spottercode.thoughtspot.app/mcp", + "type": "http" + } + } +} +---- + +After you add the MCP server URL, the SpotterCode MCP server will be available in the Extensions view. For more information about configuring MCP servers in Visual Studio Code, refer to link:https://code.visualstudio.com/docs/copilot/customization/mcp-servers[Visual Studio Code Documentation, window=_blank]. + +== Integrate SpotterCode with Claude Code +To enable SpotterCode in Claude Code, you can add the SpotterCode MCP server URL using the `claude mcp add` command via Claude CLI. If you are using Claude Desktop, you can add the URL directly to the Claude configuration JSON file: + +[source,JSON] +---- +{ + "mcpServers": { + "SpotterCode": { + "url": "https://spottercode.thoughtspot.app/mcp", + } + } +} +---- + +For more information about adding MCP servers to Claude Code, see link:https://code.claude.com/docs/en/mcp[Claude Code Documentation, window=_blank]. + +== Verify the integration + +To verify the integration: + +. Open your application project in your IDE. ++ +If the integration is successful, you'll see SpotterCode in the MCP servers list. + +. Verify the available SpotterCode skills. ++ +For example, Cursor shows the MCP skills of MCP connectors in the **Tools & MCP** page. Check if the xref:spottercode.adoc#_supported_skills[SpotterCode MCP skills] are listed under SpotterCode. As you hover over each skill, you can view the description and input schema used for agentic interactions. You can also disable the MCP skills that you don't want the AI model to use. + ++ +[div videoContainer] +-- +video::./images/cursor_mcp-skills.mp4[width=100%,options="autoplay,loop"] +-- + +. Initiate a chat session and ask a question related to ThoughtSpot embedding, REST APIs, or the SDKs. ++ +In the following example, a chat session with Cursor AI is initiated with the prompt, "I want to embed a ThoughtSpot Liveboard in my React application. Use the available tools to get this information and generate the embed code". Notice how the AI agent uses the SpotterCode skills to get the required information: ++ +[div videoContainer] +-- +video::./images/cursor-chat-session.mp4[width=100%,options="autoplay,loop"] +-- + +. Verify that the AI Agent is able to discover SpotterCode skills and is using these skills to generate a response. +. Review the response returned for your prompt and verify the results. ++ +The following example shows how Cursor AI scaffolds the embed code using the SpotterCode skills. Notice that the AI agent identifies and lists the minimum configuration settings, such as the ThoughtSpot host URL, Liveboard ID, and authentication attributes, required to complete the embedding. + ++ +[div videoContainer] +-- +video::./images/cursor-chat-session2.mp4[width=100%,options="autoplay,loop"] +-- +. When you are prompted to provide additional information, specify these details to continue with the embedding as shown in the following example: + ++ +[div videoContainer] +-- +video::./images/cursor-lb-embed.mp4[width=100%,options="autoplay,loop"] +-- +. Try additional prompts such as adding custom styles, hiding UI menu actions, and more. + +== Additional resources + +* For prompt examples, see xref:spottercode-prompt-guide.adoc#_prompt_examples[Prompt examples and best practices]. +* For troubleshooting tips and workarounds, refer to the xref:spottercode-prompt-guide.adoc#_troubleshooting_errors[Troubleshooting] section. + + +//// +. If your IDE shows the step-by-step explanation of how the Agent how the AI reached its conclusion, you may see the following parameters. These parameters show the input schema of the MCP request to SpotterCode. +* `query` - User's request or question. For example, `how do I embed Liveboard`. +* `version` - Version of the SDK to use. Default is `latest`. +* `topK` - How many relevant documents to return for the query. Default is 5. The agent may increase or decreased the number to get the right answer. +* `symbolName` - Limiting search to a specific item, for example, `LiveboardEmbed`. +* `apiName` - The API node for finding request/response details. +* `additionalDocs` - To include more documentation for extra context, such as Java or TypeScript SDK guidance. + +//// + + + + + + + diff --git a/modules/ROOT/pages/spottercode-prompt-guide.adoc b/modules/ROOT/pages/spottercode-prompt-guide.adoc new file mode 100644 index 000000000..e68e51c06 --- /dev/null +++ b/modules/ROOT/pages/spottercode-prompt-guide.adoc @@ -0,0 +1,158 @@ += SpotterCode prompting guide +:toc: true +:toclevels: 2 + +:page-title: How to use SpotterCode +:page-pageid: spottercode-prompting-guide +:page-description: This document provides best practices, prompt examples and troubleshooting guidance. + +Prompting is an essential step when building embed code for ThoughtSpot integration or when exploring ThoughtSpot REST APIs using SpotterCode. + +This guide provides prompting guidance and best practices to help you get the best results for a variety of use cases. + +== Best practices and recommendations + +* Provide clear, direct, and specific instructions. If you want a code sample as the output and nothing else, specify this in your prompt. +* Avoid multiple task requests in a single prompt. Break down your questions and precisely explain what you want. +* For precise results, use ThoughtSpot terminology, such as Liveboard, Spotter, visualization, and full application embedding. +* To receive specific answers and narrow down your request, mention the SpotterCode skill in instructions. For example, ask `How do I embed a ThoughtSpot page in my app? Use the available SpotterCode tools and skills to get this information`. +* Provide contextual information when asking a question and directing the AI model to perform an action. For example, describe the end goal of the task. If an action must be performed sequentially, use numbered lists or bullet points to ensure the AI agent completes the task as intended. +* Review each response thoroughly. For best results, use the advanced AI models. +* Do not include sensitive or confidential data in prompts. +* Provide additional details and clarifications in the next prompt if you are not getting the desired response. +* Do not rely on SpotterCode to infer business logic that isn’t explicitly defined in the documentation or the SDK. + +== Prompt examples + +For accurate and consistent responses, improve your prompts. + +=== Embedding ThoughtSpot +Refer to the prompt examples in the following table for ThoughtSpot embedding use cases: + +[width="100%" cols="4,4" role="copy-cell-table prompt-guidance-table"] +[options='header'] +|===== +|Vague prompt|Clear prompt +|How do I embed ThoughtSpot?| I want to embed full ThoughtSpot application in my app. Use the available tools to get this information and generate the embed code. +|I want to use ThoughtSpot in my app.| I want to embed a ThoughtSpot Liveboard in my React application. Use the available tools to get this information and generate the embed code. +|Show me how to use the SDK. | I want to embed ThoughtSpot Spotter Search and AI analytics in my application. Use the 'get-visual-embed-sdk-reference' and 'get-developer-docs-reference' tools to get the information and code samples. +|Give me code for embedding analytics. | Provide an example of embedding the full ThoughtSpot application using AppEmbed. +|How do I add Search? | How do I use the SearchEmbed component to embed a search page with a pre-selected data source? +a| +Tell me how to start the SDK in my app. + +Show me how to use the SDK | How do I initialize the ThoughtSpot Visual Embed SDK in a React application? +|What is the embed code for Liveboard? a| Use the SpotterCode tools and generate the embed code for a Liveboard in a React application + +Give me a code sample for embedding a ThoughtSpot Liveboard using the Visual Embed SDK. +|How do I add a chart in my app?| How do I embed a single chart or table from a ThoughtSpot Liveboard in my application? +|How do I use runtime filters? | Show a code example for embedding a Liveboard with two runtime filters: one for 'Region' set to 'Midwest' and one for 'item type' set to 'Jackets', using the Visual Embed SDK. +|Add an event hook to Liveboard. | Generate a React component that uses the ThoughtSpot embed SDK to display a Liveboard and add an event to trigger filter updates. +|Can I customize the embed?| Fetch the documentation for the LiveboardEmbed class and summarize the available customization options. +a|How do I update my code? + + +Update to new version +|Update my embed code using the latest Visual Embed SDK version and highlight any breaking changes from the documentation. +a| Show me an example with filters + + +Add filters to my embed +a| +* List all supported runtime filter operators and provide code examples for each using the SDK. +* Show how to apply an OR condition in runtime filters for product names containing 'bag' or 'jackets' in the embed code. +* Explain how to embed a Liveboard with a date filter using epoch time format, and show a code sample. +|Give me code for embedding analytics | Provide a code snippet to embed Spotter and pass a search query string as a prop +a| Change the Liveboard layout + +Make my embed dynamic +a| Show how to customize the Liveboard breakpoint width and explain the impact. + +Show me how to customize the layout of charts in the embedded Liveboard. +|Add custom styles to buttons| Change the background color of the Call To Action (CTA) buttons in the embed view to Cerulean blue (#2A52BE). +|===== + +=== ThoughtSpot REST APIs + +If using ThoughtSpot REST APIs in application workflows, consider using the examples listed in the following table: + +[width="100%" cols="4,4" role="copy-cell-table prompt-guidance-table"] +[options='header'] +|===== +|Vague prompt|Clear prompt +|How do I get the dashboards via API| How do I get a list of my Liveboards via ThoughtSpot REST API? +a| Show me how to connect to the API + + +Show me how to use the API a| +Show a cURL example for authenticating to ThoughtSpot REST API v2.0 using OAuth + + +Generate a POST request to /api/rest/2.0/metadata/search, including required headers and body. +|How do I add a user using API? a| +How do I create a new user with admin privileges via REST API? Provide the endpoint, method, and sample payload. +|Get data from a chart via API| Generate a REST API request example to fetch data from a specific chart in a Liveboard. +|What do I need to include in my API request? | What headers are required for a REST API call to ThoughtSpot? List and explain each. +|How do I see new actions in my app? | How do get a list of custom actions added in my embed via REST API? +|===== + +== Troubleshooting errors +This section lists the common error scenarios, root causes, and recommended actions for troubleshooting errors related to SpotterCode integration. If the error persists, contact ThoughtSpot Support for further assistance. + +=== SpotterCode is not responding or failing to load + +Possible causes:: +- SpotterCode is not installed or enabled. +- Incorrect MCP Server URL or errors in the MCP configuration file. +- SpotterCode server is not reachable. + +Recommended actions:: +- Ensure the SpotterCode is properly installed and enabled in your IDE. +- Verify whether the SpotterCode MCP server is reachable. If the server is not reachable, contact ThoughtSpot Support. +- Verify whether your organization's network/firewall settings are blocking communication. +- Exit and restart your application and try connecting again. + +=== Unable to start a chat with SpotterCode + +Possible causes:: +- Development environment non-AI-native or not AI-enabled. + +Recommended actions:: +- If your IDE is not AI-native, try installing an extension, such as Copilot. +- Check if your environment has access to AI models. +- Start a chat session and specify the Agent to use SpotterCode skills. If the issue persists, contact your application administrator. + +=== Slow response time + +Possible causes:: + +- The prompt is complex, involves multiple actions, or includes a broader context, resulting in a longer search and processing time. +- High server load or network latency can further delay the response. + +Recommended actions:: +- Make your prompt as specific as possible. Specify the SDK version, the exact component, and the desired output. For best results, break down complex requests into smaller, sequential prompts. Refer to xref:spottercode-prompt-guide.adoc#_prompt_examples[prompt examples] and xref:spottercode-prompt-guide.adoc#_best_practices_and_recommendations[best practices] for tips. +- Try using a different AI model and review. +- Reset the chat session and try it again. + +=== Incorrect or irrelevant response + +Possible causes:: +- The AI Agent is not using the right skills or the input schema of the MCP skills efficiently. +- The prompt input is complex or ambiguous. + +Recommended actions:: +- Check the response generation flow to see the query parameters used by the AI Agent in its MCP request. +- Refine your query to be more specific. Refer to the best practices and Prompt examples recommended by ThoughtSpot. +- Choose a different AI model and review the results. + +=== Errors in code samples due to version mismatch + +Possible causes:: +- SpotterCode used a different version for code generation. +- No version was specified in the prompt. + +Recommended actions:: +- SpotterCode uses the latest version of the SDK by default. If you'd like to use a different version, specify the version in your prompt. +- Review API and SDK changelog in the documentation for feature deprecation and breaking changes. + +=== SDK client context mismatch + +Possible causes:: +SpotterCode couldn't determine the SDK content for your application or client. + +Recommended actions:: +Although the AI Agent on your IDE is capable of finding relevant information for your project context, we recommend stating the client environment and required SDK client library clearly in the prompt. + diff --git a/modules/ROOT/pages/spottercode.adoc b/modules/ROOT/pages/spottercode.adoc new file mode 100644 index 000000000..b37ed7906 --- /dev/null +++ b/modules/ROOT/pages/spottercode.adoc @@ -0,0 +1,94 @@ += SpotterCode +:toc: true +:toclevels: 2 + +:page-title: SpotterCode +:page-pageid: SpotterCode +:page-description: Use SpotterCode to accelerate code generation and the process of embedding and integrating ThoughtSpot. + +ThoughtSpot’s SpotterCode is an AI-powered MCP tool that streamlines and speeds up the process of embedding ThoughtSpot content and integrating ThoughtSpot REST APIs in your application workflows. + +== What is SpotterCode? +SpotterCode connects your integrated development environment (IDE) to a ThoughtSpot-hosted MCP server. It empowers AI-native IDEs with tools and documentation lookup capabilities, providing direct access to ThoughtSpot SDKs, REST API documentation, code samples, and developer guides. The AI agents in the IDE can use these skills to assist developers in embedding ThoughtSpot content and integrating REST API workflows into their applications. + +[IMPORTANT] +==== +SpotterCode is an add-on tool available with the link:https://www.thoughtspot.com/pricing[ThoughtSpot Analytics and ThoughtSpot Embedded offerings, window=_blank]. If you have a ThoughtSpot Analytics license with an active ThoughtSpot Embedded subscription, you can integrate SpotterCode using the SpotterCode MCP Server URL in your coding application. +==== + +== Who should use SpotterCode? +SpotterCode is intended for developers and technical teams integrating ThoughtSpot content and workflows into their applications using Visual Embed SDK and REST APIs, with a particular focus on those working in AI-native IDEs such as Cursor. + +When integrated, SpotterCode offers the following advantages: + +* Empowers your IDE with the documentation lookup and provides direct access to authoritative information on embedding ThoughtSpot or integrating REST API workflows in your development projects. + +* Accelerates the process of embedding and integration by providing code samples, SDK skills, and custom styling directly in the IDE. + +* Enables developers to build context-aware and deployment-ready code tailored to their project structure, thereby reducing manual effort and errors. + +* Reduces operational strain by rapidly generating boilerplate code required for embedding ThoughtSpot in your application. + +[NOTE] +==== +SpotterCode is an acceleration tool designed to help developers streamline the process of integrating ThoughtSpot into their projects. It does not replace the Visual Embed SDK or the foundational knowledge required for embedding or application integration. +==== + +== Supported IDEs + +The initial version of SpotterCode supports the following IDEs: + +* Cursor AI +* Visual Studio Code with GitHub Copilot +* Claude Code + +== Supported skills +SpotterCode provides the following skills to the AI agent on your IDE: + +* `get-visual-embed-sdk-reference` + +A documentation lookup skill that accesses Visual Embed SDK documentation and generates code samples for embedding ThoughtSpot content, including supported embed types, authentication, configuration, customization, event hooks, and code samples. + +* `get-rest-api-reference` + +Provides REST API specifications, endpoints, request/response formats, authentication flows, CRUD operations, and SDKs for TypeScript and Java. + +* `get-developer-docs-reference` + +Provides access to documentation on embedding, UI customization, deployment, security, and best practices. + +== Limitations + +- Responses from SpotterCode are determined by the features and parameters currently supported in the Visual Embed SDK, REST API, and official ThoughtSpot Developer documentation. SpotterCode cannot generate code or solutions that rely on unsupported or undocumented features. +- SpotterCode can generate code samples for the most common use cases. Scenarios that require advanced customization or highly specialized workflows may require manual intervention or additional coding beyond what SpotterCode provides. +- SpotterCode does not influence how the Spotter feature in your ThoughtSpot embed infers semantic modeling. SpotterCode is not intended for querying data models or interpreting definitions such as measures and attributes in your metadata objects. +- The behavior of the IDE agent, including tool selection and reasoning, is not controlled by SpotterCode. + +== Next steps + +++++ +
+ + + + +
+ +++++ + + + diff --git a/modules/ROOT/pages/variables.adoc b/modules/ROOT/pages/variables.adoc index 0cd67412f..dafd73e9c 100644 --- a/modules/ROOT/pages/variables.adoc +++ b/modules/ROOT/pages/variables.adoc @@ -35,7 +35,6 @@ Formula variables can be set for an Org, user, or Model and can be used in RLS r The Variable API allows administrators to define formula variables for the `VARCHAR`, `BIGINT`, `INT`, `FLOAT`, `DOUBLE`, `BOOLEAN`, `DATE`, `DATE_TIME`, and `TIME` data types. - === APIs for Variable creation and management The following REST API endpoints are available for variable creation and management: @@ -51,10 +50,12 @@ xref:variables.adoc#_get_details_of_variables[Retrieves the variables available xref:variables.adoc#_delete_a_variable[Deletes the variable] specified in the API request. +//// [NOTE] ==== Variable operations through the REST API are in beta. To enable this feature on your instance, contact ThoughtSpot Support. ==== +//// == Before you begin diff --git a/modules/ROOT/pages/webhooks-lb-schedule.adoc b/modules/ROOT/pages/webhooks-lb-schedule.adoc index eec7e3d5a..fa439c172 100644 --- a/modules/ROOT/pages/webhooks-lb-schedule.adoc +++ b/modules/ROOT/pages/webhooks-lb-schedule.adoc @@ -1,18 +1,20 @@ -= Webhooks for Liveboard schedule events [beta betaBackground]^Beta^ += Webhooks for Liveboard schedule events :toc: true :toclevels: 3 -:page-title: Webhooks for Liveboard Schedueld Jobs +:page-title: Webhooks for Liveboard Scheduled Jobs :page-pageid: webhooks-lb-schedule :page-description: Configure Webhooks and send alerts to specific communication channels +[beta betaBackground]^Beta^ + To provide flexibility and programmatic control for users who want to customize notifications and automate workflows based on Liveboard scheduling events, ThoughtSpot provides the ability to configure a webhook communication channel. By configuring a webhook, users can send notifications automatically to a target application whenever a scheduled Liveboard job is triggered in ThoughtSpot. Webhook support for Liveboard schedule events is available only on ThoughtSpot Cloud instances running 10.14.0.cl or later. This feature is currently in beta and is not enabled by default. To enable this feature on your instance, contact ThoughtSpot Support. == Overview -If you have scheduled a Liveboard job to receive a daily report via email, you can configure ThoughtSpot to send the report directly to a webhook endpoint and create your own custom emails or workflow. +If you have scheduled a Liveboard job to receive a daily report via email, you can configure ThoughtSpot to send the report directly to a webhook endpoint and create your own custom emails or workflows. To automate sending scheduled Liveboard notifications to a webhook endpoint, the following configuration is required: @@ -36,10 +38,10 @@ In the current release: ==== == Get started -The webhooks setup for Liveboard Schedule events involves the following steps: +The webhook setup for Liveboard schedule events includes the following steps: -* xref:webhooks-lb-schedule.adoc#_configure_webhook_communication_channel[Configuring a webhook communication channel at the cluster or Org level]. -* xref:webhooks-lb-schedule.adoc#_configure_a_webhook_for_liveboard_schedule_event[Creating a webhook to listen to the Liveboard schedule events]. +* xref:webhooks-lb-schedule.adoc#_configure_a_webhook_communication_channel[Configuring a webhook communication channel at the cluster or Org level]. +* xref:webhooks-lb-schedule.adoc#_configure_a_webhook[Creating a webhook to listen to Liveboard schedule events]. * xref:webhooks-lb-schedule.adoc#_verify_the_webhook_payload[Verifying the webhook payload]. === Before you begin @@ -51,14 +53,14 @@ If your instance has Role-based Access Control (RBAC) enabled, you need the foll ** `APPLICATION_ADMINISTRATION` (*Can Manage Application settings*) to create and view communication channels. ** `CAN_MANAGE_WEBHOOKS` (*Can manage webhooks*) to create and manage webhooks. * Ensure that the REST APIs for setting communication channel preference and configuring webhooks are enabled on your instance. If the APIs are not available on your instance, contact ThoughtSpot Support. -* To allow outbound traffic from the ThoughtSpot to the webhook endpoint, add the webhook destination URL to the xref:security-settings.adoc#csp-connect-src[CSP connect-src] allowlist in ThoughtSpot. +* To allow outbound traffic from ThoughtSpot to the webhook endpoint, add the webhook destination URL to the xref:security-settings.adoc#csp-connect-src[CSP connect-src] allowlist in ThoughtSpot. * Ensure that your destination application has a callback URL to accept HTTP POST requests from ThoughtSpot. * If you plan to use OAuth authentication, make sure you have the OAuth credentials and authorization URL of your application. * If you plan to use an API key for authentication, ensure that you have a valid API key. === Configure a webhook communication channel -To create a webhook communication channel for the Liveboard Schedule event, use the channel preference REST API. +To create a webhook communication channel for the Liveboard schedule event, use the channel preference REST API. ==== Create a webhook communication channel @@ -70,12 +72,12 @@ To create the webhook communication channel and set messaging preferences, send [options='header'] |===== |Parameter|Description | -.3+| `cluster_preferences` 2+|__Array of strings__. Sets default preferences for all Orgs in the instance. You must specify the following parameters: +.3+| `cluster_preferences` 2+|__Array of objects__. Sets default preferences for all Orgs in the instance. You must specify the following parameters: -|`event_type` +| `event_type` a|__String__. Type of the event for which communication channels are configured. For Liveboard schedule event, set the parameter value as `LIVEBOARD_SCHEDULE`. -|`channels` a| +| `channels` a| __Array of strings__. Communication channel for the event type specified in the request. Valid values are: + * `EMAIL` @@ -83,12 +85,12 @@ __Array of strings__. Communication channel for the event type specified in the To create a webhook channel for the Liveboard schedule event, specify `WEBHOOK`. -.5+| `org_preferences` 2+|__Array of strings__. By default, preferences configured at the cluster level will apply to all Orgs in the instance. To override the default preferences for your Org, set the Org-specific preferences: +.5+| `org_preferences` 2+|__Array of objects__. By default, preferences configured at the cluster level apply to all Orgs in the instance. To override the default preferences for your Org, set Org-specific preferences: | `org_identifier` a| __String__. Name or ID of the Org. | `preferences` a| -__Array of strings__. Define the following parameters to set communication channel preferences for the Org. If the preferences are not set, the Org will inherit the default preferences applied at the cluster level. +__Array of objects__. Define the following parameters to set communication channel preferences for the Org. If preferences are not set, the Org inherits the default preferences applied at the cluster level. * `event_type` + __String__. Type of the event for which communication channels are configured. For Liveboard schedule event, set the parameter value as `LIVEBOARD_SCHEDULE`. @@ -103,9 +105,9 @@ To set up a webhook channel for the Liveboard schedule event, specify `WEBHOOK`. | `operation` a|__String__. Type of operation. The following options are available: ** `REPLACE` - To replace default preferences. -** `RESET` - To restore default preferences. For reset operation, you'll also need to specify the event type. Note that this operation will remove any Org-specific overrides and restores the default preferences configured at the cluster level. +** `RESET` - To restore default preferences. For reset operation, you'll also need to specify the event type. Note that this operation removes any Org-specific overrides and restores the default preferences configured at the cluster level. -|`reset_events` a|__Array of strings__. For RESET operations, specify the event type to reset. Note that the reset operation removes Org-specific configuration for the events specified in `reset_events`. +| `reset_events` a|__Array of strings__. For `RESET` operations, specify the event type to reset. Note that the reset operation removes Org-specific configuration for the events specified in `reset_events`. ||| |===== @@ -313,11 +315,11 @@ To create a webhook for the Liveboard schedule event, send a `POST` request to t |Parameter|Description | `name` a|__String__. Name of the webhook. | `description` + -__Optional__ a|__String__. Description text for the webhook +__Optional__ a|__String__. Description text for the webhook. | `url` a|__String__. The fully qualified URL of the listening endpoint where the webhook payload will be sent. The webhook endpoint to which you want to send notifications. -|`url_params` a| A JSON map of key-value pairs of parameters to add as a GET query params in the webhook URL. +| `url_params` a| A JSON map of key-value pairs to append as query parameters in the webhook URL. | `events` a|__Array of strings__. List of events to subscribe to. Specify the event as `LIVEBOARD_SCHEDULE`. -|`authentication` a| +| `authentication` a| Defines authentication method and credentials that ThoughtSpot will use when sending HTTP requests to the webhook endpoint. @@ -331,8 +333,8 @@ Authentication methods with username and password. Authentication token to authenticate and authorize requests. * `OAUTH2` + OAuth credentials to authorize API requests. Specify client ID, client secret key, and authorization URL. -If the registered webhook has Oauth authentication enabled, `Authorization: Bearer ` is sent in the request header. -|`signature_verification` + +If the registered webhook has OAuth authentication enabled, `Authorization: Bearer ` is sent in the request header. +| `signature_verification` + __Optional__ a| Signature verification parameters for the webhook endpoint to verify the authenticity of incoming requests. This typically involves ThoughtSpot signing the webhook payload with a secret, and your webhook endpoint validating this signature using the shared secret. If using signature verification, specify the following parameters. @@ -366,7 +368,7 @@ curl -X POST \ ], "authentication": { "BEARER_TOKEN": "Bearer {AUTH_TOKEN}" - } + }, "description": "Webhook for Liveboard schedule" }' ---- @@ -390,7 +392,7 @@ If the webhook creation is successful, the API returns the following response: "events": [ "LIVEBOARD_SCHEDULE" ], - "authentication": BEARER_TOKEN, + "authentication": "BEARER_TOKEN", "signature_verification": null, "creation_time_in_millis": 1761050197164, "modification_time_in_millis": 1761050197164, @@ -406,7 +408,7 @@ If the webhook creation is successful, the API returns the following response: To view the properties of a webhook or get a list of webhooks configured on your ThoughtSpot instance, send a `POST` request to the `/api/rest/2.0/webhooks/search` API endpoint. -To get specific information, define the following parameters. If the API request is sent without any parameters in the request body, ThoughtSpot returns the webhooks configured for the Org contexts in ThoughtSpot. +To get specific information, define the following parameters. If the API request is sent without any parameters in the request body, ThoughtSpot returns the webhooks configured for the Org context in ThoughtSpot. ===== Request parameters @@ -418,7 +420,7 @@ To get specific information, define the following parameters. If the API request __Optional__ |__String__. ID or name of the Org. | `webhook_identifier` + __Optional__ | __String__. ID or name of the webhook. -|`event_type` + +| `event_type` + __Optional__| __String__. Type of webhook event to filter by. For Liveboard schedule events, specify `LIVEBOARD_SCHEDULE`. |Pagination settings a| If fetching multiple records, specify the following parameters to paginate API response: + @@ -427,7 +429,7 @@ __Integer__. Specifies the starting point (index) from which records should be r * `record_size` + __Integer__. Specifies the number of records to return in the response. Default is 50. | `sort_options` + -__Optional__| Enables sorting of the API response by a specific field in ascending or descending order. Specify the `field_name` and define the desired sort order. +__Optional__| Enables sorting of the API response by a specific field in ascending or descending order. Specify the `field_name` and define the desired sort order. | |===== @@ -515,7 +517,7 @@ Query parameters to append to the endpoint URL. * `events` + Events subscribed to the webhook. In the current release, ThoughtSpot supports only the `LIVEBOARD_SCHEDULE` event. * `authentication` + -Authentication method and credentials that ThoughtSpot will use when sending HTTP requests to the webhook endpoint +Authentication method and credentials that ThoughtSpot will use when sending HTTP requests to the webhook endpoint. * `signature_verification` + Signature verification parameters for the webhook endpoint to verify the authenticity of incoming requests. @@ -554,7 +556,7 @@ Specify the name or ID of the webhook to delete. [options='header'] |===== |Parameter|Description -|`webhook_identifiers` |__Array of strings__. ID of name of the webhooks to delete. +| `webhook_identifiers` |__Array of strings__. ID or name of the webhooks to delete. || |===== @@ -614,13 +616,13 @@ If the API request is successful, the webhook is deleted, and the API returns th === Verify the webhook payload -After a webhook channel is configured for Liveboard schedule events and a webhook is created for these events at the Org level, it's applied to all Liveboard schedules in an Org. +After a webhook channel is configured for Liveboard schedule events and a webhook is created for these events at the Org level, it is applied to all Liveboard schedules in an Org. When a Liveboard schedule event is triggered based on the conditions defined in the schedule, the webhook sends the payload with the following schema to the configured endpoint. Based on the Liveboard job settings, the payload includes metadata properties such as webhook communication channel ID, recipient details, Liveboard schedule details, event properties, and a link to the Liveboard. For testing purposes, you can use a URL from the link:https://webhook.site/[Webhook site, window=_blank] as a webhook endpoint and check the payload when the Liveboard schedule event is triggered. -==== Contents of the webhook playload +==== Contents of the webhook payload The Webhook payload uses a specific schema structure that determines the contents of the payload delivered to the webhook endpoint. The payload contains metadata about the event, the source, the actor, the target object, and event-specific data. The payload is typically sent as a form field named `payload` in a `multipart/form-data` request, with optional file attachments. @@ -652,16 +654,16 @@ The `WebhookPayload` schema defines the structure for webhook event notification | `timestamp` | string | Timestamp of when the event occurred. | Yes | `eventType` | string | Type of event that triggered the webhook payload. For example, `LIVEBOARD_SCHEDULE`. | Yes | `schemaVersion` | string | Schema version. | Yes -| `source` | object |Source endpoint that triggered the event. Includes the parameters defined in the xref:webhooks-lb-schedule.adoc#_webhooksourceinfo[WebhookSourceInfo] schema. | Yes +| `source` | object | Source endpoint that triggered the event. Includes the parameters defined in the xref:webhooks-lb-schedule.adoc#_webhooksourceinfo[WebhookSourceInfo] schema. | Yes | `actor` | object | Actor that initiated the event. For more information, see xref:webhooks-lb-schedule.adoc#_webhookactorinfo[WebhookActorInfo]. | Yes | `metadataObject` | object | Metadata object details. For more information, see xref:webhooks-lb-schedule.adoc#_webhooktargetobjectinfo[WebhookTargetObjectInfo]. | Yes -| `data` | object |Data specific to the Liveboard schedule event. For more information, see xref:webhooks-lb-schedule.adoc#_liveboardscheduledata[LiveboardScheduleData]. | Yes +| `data` | object | Data specific to the Liveboard schedule event. For more information, see xref:webhooks-lb-schedule.adoc#_liveboardscheduledata[LiveboardScheduleData]. | Yes |||| |===== ===== WebhookSourceInfo -The `WebhookSourceInfo` schema defines the properties of source application instance that triggered the webhook event. +The `WebhookSourceInfo` schema defines the properties of the source application instance that triggered the webhook event. [width="100%" cols="1,1,3,1"] [options='header'] @@ -685,9 +687,9 @@ The `WebhookActorInfo` schema defines the properties of the entity that initiate | Field | Type | Description | Required? | `actorType` | string | Initiator of the event such as the API client or user. The default actor type is `SYSTEM`. | Yes -| `id` | string a| Unique identifier such as GUID or object ID).For system-generated responses, the `id` will be set as `null`. | No -| `name` | string a| Name of the actor that initiated the event. For system-generated responses, the `name` will be set as `null`. | No -| `email` | string a| Email of the actor that initiated the event. For system-generated responses, the `name` will be set as `null`. | No +| `id` | string a| Unique identifier such as a GUID or object ID. For system-generated responses, the `id` is set to `null`. | No +| `name` | string a| Name of the actor that initiated the event. For system-generated responses, the `name` is set to `null`. | No +| `email` | string a| Email of the actor that initiated the event. For system-generated responses, the `email` is set to `null`. | No |||| |===== @@ -709,7 +711,7 @@ The `WebhookTargetObjectInfo` schema defines the object for which the event is g ===== LiveboardScheduleData -The `WebhookTargetObjectInfo` schema defines event-specific data for Liveboard schedule events, including schedule details, recipients, and additional context. +The `LiveboardScheduleData` schema defines event-specific data for Liveboard schedule events, including schedule details, recipients, and additional context. [width="100%" cols="1,1,3,1"] [options='header'] @@ -717,8 +719,8 @@ The `WebhookTargetObjectInfo` schema defines event-specific data for Liveboard s | Field | Type | Description | Required | `scheduleDetails` | object | Details of the Liveboard schedule that triggered the event. This includes the schedule ID, object type, and output format. For more information, see xref:webhooks-lb-schedule.adoc#_scheduledetails[ScheduleDetails]. | Yes -| `recipients` | array | Details of the ThoughtSpot users, groups, and email addresses of the external users who are configured as subscribers of the Liveboard schedule notifications and recipients of the webhook payload. For more information, xref:webhooks-lb-schedule.adoc#_recipientinfo[RecipientInfo]. | Yes -| `viewInfo` | object | Information about the Liveboard view. Applicable if the Liveboard Schedule event is triggered for a personalized view of the Liveboard. For more information, xref:webhooks-lb-schedule.adoc#_viewinfo[ViewInfo]. | No +| `recipients` | array | Details of ThoughtSpot users, groups, and email addresses of external users configured as subscribers to Liveboard schedule notifications and recipients of the webhook payload. For more information, see xref:webhooks-lb-schedule.adoc#_recipientinfo[RecipientInfo]. | Yes +| `viewInfo` | object | Information about the Liveboard view. Applicable if the Liveboard schedule event is triggered for a personalized view of the Liveboard. For more information, see xref:webhooks-lb-schedule.adoc#_viewinfo[ViewInfo]. | No | `aiHighlights` | string | AI Highlights information. Applicable if AI highlights feature is enabled for the visualizations on the Liveboard. | No | `msgUniqueId` | string | Unique message identifier. Unique ID of the webhook payload message. This ID can be used for traceability and deduplication on the receiving end. | No | `channelID` | string | The communication channel ID used for event dissemination. | No @@ -740,12 +742,12 @@ The `ScheduleDetails` schema defines the properties of the schedule that trigger | `creationTime` | string | Timestamp of when the schedule was created. | No | `description` | string | Description of the schedule. | No | `authorId` | string | ID of the user that scheduled the Liveboard job. | No -| `viewInfo` | object | Information about the Liveboard view. Applicable if the Liveboard Schedule event is triggered for a personalized view of the Liveboard. For more information, xref:webhooks-lb-schedule.adoc#_viewinfo[ViewInfo]. | No +| `viewInfo` | object | Information about the Liveboard view. Applicable if the Liveboard schedule event is triggered for a personalized view of the Liveboard. For more information, see xref:webhooks-lb-schedule.adoc#_viewinfo[ViewInfo]. | No | `userIds` | array | IDs of the ThoughtSpot users that are subscribed to the scheduled Liveboard notifications. | No | `groupIds` | array | IDs of the ThoughtSpot groups that are subscribed to the scheduled Liveboard notifications.| No | `runId` | string | Schedule run ID of the Liveboard job. | No | `exportRequest` | object | Details of the file export request. If the scheduled notification includes PDF attachment, the `exportRequest` includes details of the Liveboard and PDF page attributes. | No -| `fileFormat` | string | File format for export. The schedule notification generally include PDF attachments. | No +| `fileFormat` | string | File format for export. The schedule notification generally includes PDF attachments. | No | `status` | string | Status of the schedule. | No | `emailIds` | array | Email IDs of users subscribed to Liveboard job schedule. | No |||| @@ -765,7 +767,7 @@ The `RecipientInfo` schema defines the object properties of the recipients of th * `USER` - For ThoughtSpot users * `EXTERNAL_EMAIL` - For external recipients | Yes -| `id` | string | IDs of the ThoughtSpot user and groups that are subscribed to the Liveboard schedule. | No +| `id` | string | IDs of ThoughtSpot users and groups that are subscribed to the Liveboard schedule. | No | `name` | string | Name of the recipient. | No | `email` | string | Email address of the recipient. | Yes | `locale`| string | Locale of the recipient. For example, `en_US`. | No @@ -1013,11 +1015,14 @@ Along with the JSON payload, if the Liveboard schedule is configured to send a P The payload also includes file attachments in the file format specified in the Liveboard schedule. The file format can be PDF, CSV, or XLSX. -== Additional resources - -* link:https://docs.thoughtspot.com/cloud/latest/liveboard-schedule[Scheduling Liveboard jobs, window=_blank] -* +++Liveboard schedule REST APIs+++ +=== Response after webhook delivery +The webhook endpoint must respond with an HTTP 2xx status code to confirm successful receipt and processing of the request. The receiving server must send a 2xx response within 5 seconds of the webhook delivery. +If your server takes longer than 5 seconds to respond, returns a 4xx error, or times out, ThoughtSpot may still deliver the Liveboard data and file. However, the notification status will be recorded as `FAILED` in the ThoughtSpot notification history and request will be retried. +To ensure a timely response, we recommend processing webhook payloads asynchronously. Your server can immediately return a 2xx response upon receipt of the webhook and then handle the payload in the background without blocking subsequent webhook deliveries. +== Additional resources +* link:https://docs.thoughtspot.com/cloud/latest/liveboard-schedule[Scheduling Liveboard jobs, window=_blank] +* +++Liveboard schedule REST APIs+++ diff --git a/modules/ROOT/pages/whats-new.adoc b/modules/ROOT/pages/whats-new.adoc index d7955f3a7..de63695b2 100644 --- a/modules/ROOT/pages/whats-new.adoc +++ b/modules/ROOT/pages/whats-new.adoc @@ -8,23 +8,65 @@ This page lists new features, enhancements, and deprecated functionality in ThoughtSpot Embedded instances. +== Version 26.3.0.cl + +The ThoughtSpot Cloud 26.3.0.cl version is now available for ThoughtSpot Embedded instances. For information about the new features and enhancements introduced in this release, see link:https://developers.thoughtspot.com/docs/26.3.0.cl?pageid=whats-new[26.3.0.cl Developer Documentation, window=_blank]. + == Version 26.2.0.cl -The ThoughtSpot Cloud 26.2.0.cl version is now available for ThoughtSpot Embedded instances. For information about the new features and enhancements introduced in this release, see link:https://developers.thoughtspot.com/docs/26.2.0.cl?pageid=whats-new[26.2.0.cl Developer Documentation, window=_blank]. +=== SpotterCode extension for IDEs [earlyAccess eaBackground]#Early Access# + +ThoughtSpot introduces SpotterCode, an AI-powered Model Context Protocol (MCP) extension for Integrated Development Environments (IDEs) such as Cursor, Visual Studio Code, and Claude Code. When integrated, SpotterCode enables the AI agent in the IDE to access ThoughtSpot SDKs and API documentation resources and provide in-context coding assistance to developers embedding ThoughtSpot content within their applications. + +SpotterCode is available as an Early Access feature and can be integrated with development environments that support MCP servers and tools. For more information, see xref:spottercode.adoc[SpotterCode], xref:spottercode-integration.adoc[Integrating SpotterCode in IDEs], and xref:spottercode-prompt-guide.adoc[SpotterCode prompting guide]. + +=== Spotter 3 experience [earlyAccess eaBackground]#Early Access# +You can now embed the Spotter 3 experience, which introduces several new capabilities, agentic analytics, and enhanced user experience. Spotter 3 is an Early Access feature and is disabled by default on ThoughtSpot embedded instances. + +For more information, see xref:embed-ai-analytics.adoc[Embed AI Search and Analytics] and xref:embed-spotter.adoc[Spotter embedding documentation]. + +=== Rate limits for REST APIs +To prevent excessive requests from reaching application servers and ensure API stability and service quality for REST API users, ThoughtSpot enforces rate limits on public API requests per client IP. These limits are applied globally at the cluster level for all public API requests, including calls to both REST API v1 and v2 endpoints. +//Administrators can adjust these limits for their ThoughtSpot deployments as needed. + +For more information, see xref:about-rest-apis.adoc#_rate_limits_for_api_requests[Rate limits for REST APIs]. + +=== Security settings via REST APIs +Security settings that ensure data security and a seamless embedded user experience can now be configured through REST APIs v2. Administrators and developers can configure allowlists for: + +* Content Security Policy (CSP) +* Cross-origin Resource Sharing (CORS) +* Authentication attributes +* Access control settings + +For more information, see xref:security-settings.adoc[Security Settings]. + +=== WebSocket support for external tools +ThoughtSpot supports secure WebSocket (`wss://`) endpoints for external tool script integrations, for example, tools that open WebSocket connections from the browser. + +To allow a WebSocket host, add the corresponding `wss://` URL to both your CSP allowlists. Only hosts explicitly listed with the `wss://` protocol are permitted. Existing `https://` entries in the allowlists remain unchanged and continue to function as expected. + +For more information, see xref:3rd-party-script.adoc#_allow_websocket_endpoints[External tools and script integration]. + +=== Visual Embed SDK +For information about the new features and enhancements introduced in Visual Embed SDK version 1.45.0, see the xref:api-changelog.adoc[Visual Embed changelog]. + +=== REST API v2 +For information about REST API v2 enhancements, see the xref:rest-apiv2-changelog.adoc[REST API v2.0 changelog]. == Version 10.15.0.cl === Theme Builder Theme Builder is now generally available (GA) and will be rolled out to all ThoughtSpot instances in customer deployments over the next few weeks. -When this feature is enabled on your instance, you can access it from the *Develop* page on your ThoughtSpot and use it to customize styles and UX themes directly within the product. +When this feature is enabled on your instance, you can access it from the *Develop* page in ThoughtSpot and use it to customize styles and UX themes directly within the product. For more information, see xref:theme-builder.adoc[Theme Builder]. === V3 navigation and home page experience The new V3 navigation and home page experience is now generally available (GA) and can be enabled on ThoughtSpot embedded instances. -The default UI experience in full application embedding remains classic (V1) experience until further notice. Developers embedding the full ThoughtSpot application can enable the V3 experience in their applications by setting the appropriate configuration options in their embed code. +The default UI experience in full application embedding remains the classic (V1) experience until further notice. Developers embedding the full ThoughtSpot application can enable the V3 experience in their applications by setting the appropriate configuration options in their embed code. For more information, see xref:full-app-customize.adoc[Customizing full application embedding]. @@ -37,9 +79,9 @@ For more information, see xref:abac_rls-variables.adoc[ABAC via RLS with variabl === Spotter APIs ThoughtSpot introduces new REST APIs for the following Spotter workflows: //* To get data source suggestions based on a user's query -* To send queries to a conversation session with Spotter agent -* To set natural language (NL) instructions on a Model to coach the Spotter system -* To fetch NL instructions configured on a Model +* To send queries to a conversation session with the Spotter agent +* To set natural language (NL) instructions on a model to coach the Spotter system +* To fetch NL instructions configured on a model For more information, see xref:spotter-apis.adoc[Spotter APIs]. @@ -47,6 +89,9 @@ For more information, see xref:spotter-apis.adoc[Spotter APIs]. You can now intercept API calls from the embedded ThoughtSpot application using the `interceptUrls` attribute in the Visual Embed SDK. This feature lets you control API requests in your embedding application and use embed events to modify, block, or handle requests before they are sent to the backend. For more information, see xref:api-intercept.adoc[Intercept API calls and search requests]. +=== Icon customization enhancements +You can now replace or customize the chart switcher toggle and icons in the Charts drawer on an Answer or visualization page using SVG sprites. Previously, these icons were fixed to ThoughtSpot defaults and were not configurable. In the new version, these icons are available as SVG components and can be replaced by developers through the xref:customize-icons.adoc[icon customization framework] as needed. + === Mobile Embed SDK The SDKs for embedding ThoughtSpot components in mobile apps are now Generally Available (GA). For more information about the SDKs and how to embed a ThoughtSpot component in a mobile app, see xref:mobile-embed.adoc[Mobile embed documentation]. @@ -61,7 +106,7 @@ For information about REST API v2 enhancements, see xref:rest-apiv2-changelog.ad == Version 10.14.0.cl === Code based custom actions -ThoughtSpot now enables developers to define custom action in their embed code through the Visual Embed SDK. This enhancement enables code based customization of actions for Liveboards, Visualizations, Answers, and Spotter. With this functionality, developers can add custom actions that show up as new menu options in one of the following UI elements: +ThoughtSpot now enables developers to define custom actions in their embed code through the Visual Embed SDK. This enhancement enables code-based customization of actions for Liveboards, Visualizations, Answers, and Spotter. With this functionality, developers can add custom actions that show up as new menu options in one of the following UI elements: * the primary menu bar * the **More** options menu image:./images/icon-more-10px.png[the more options menu] @@ -74,11 +119,11 @@ Key characteristics of code-based custom actions: * Can be assigned to Liveboards. * Can be conditionally displayed based on the presence of a specific column in a visualization. -For more information, see xref:code-based-custom-actions.adoc[Code based custom actions]. +For more information, see xref:code-based-custom-actions.adoc[Code-based custom actions]. === Webhooks for Liveboard schedule events [beta betaBackground]^Beta^ -You can now configure a xref:webhooks-lb-schedule.adoc[webhook for Liveboard schedule events] to automate notifications to external applications. This feature allows you to send Liveboard reports directly to a webhook endpoint and create your own custom emails or workflow. +You can now configure a xref:webhooks-lb-schedule.adoc[webhook for Liveboard schedule events] to automate notifications to external applications. This feature allows you to send Liveboard reports directly to a webhook endpoint and create your own custom emails or workflows. This feature is currently in beta and is not enabled by default. To enable it on your instance, contact ThoughtSpot Support. @@ -92,13 +137,13 @@ The `HostEvent.UpdateParameters` event in the Visual Embed SDK now includes the Before this enhancement, the Parameter chip display behavior was inconsistent across embed types when the Parameter values were updated via `HostEvent.UpdateParameters` requests. With the new change, the `isVisibleToUser` attribute in `HostEvent.UpdateParameters` is set to `false` by default for all embed types. -With the new enhancement, the embedded pages that previously kept the parameter chip visible after an override via `HostEvent.UpdateParameters` will now hide it unless the `isVisibleToUser` attribute is explicitly set to `true`. + +With the new enhancement, the embedded pages that previously kept the parameter chip visible after an override via `HostEvent.UpdateParameters` will now hide it unless the `isVisibleToUser` attribute is explicitly set to `true`. + This behavior may introduce a breaking change if your current implementation relies on the previous default chip visibility behavior. To retain chip visibility, developers must update their embedding implementation to pass `isVisibleToUser: true` in their `HostEvent.UpdateParameters` requests. For more information, see xref:runtime-parameters.adoc#_show_or_hide_parameter_chips_in_embedded_sessions[Runtime Parameter overrides]. === Pre-rendering enhancements -Pre-rendering now provides enhanced flexibility and granular control over for rendering embedded ThoughtSpot components. For more information, see xref:prerender.adoc[Pre-rendering ThoughtSpot Embed components]. +Pre-rendering now provides enhanced flexibility and granular control over rendering embedded ThoughtSpot components. For more information, see xref:prerender.adoc[Pre-rendering ThoughtSpot Embed components]. === Visual Embed SDK @@ -187,6 +232,9 @@ You can now create a visual group of Answers and note tiles on an embedded Liveb The Liveboard styling and grouping feature is disabled by default on embedded apps. To enable this feature on your embed, set `isLiveboardStylingAndGroupingEnabled` to `true` in the SDK and contact ThoughtSpot Support. +[NOTE] +The `isLiveboardStylingAndGrouping` attribute is now replaced with `isLiveboardMasterpiecesEnabled`. + When this feature is enabled, you can use the following CSS variables in the Visual Embed SDK to style your Liveboard elements: * `--ts-var-liveboard-layout-background` diff --git a/modules/tutorials/pages/rest-api/rest-api-intro.adoc b/modules/tutorials/pages/rest-api/rest-api-intro.adoc index 84ce54ee8..50cc0aa39 100644 --- a/modules/tutorials/pages/rest-api/rest-api-intro.adoc +++ b/modules/tutorials/pages/rest-api/rest-api-intro.adoc @@ -4,7 +4,7 @@ :page-title: ThoughtSpot REST API tutorials :page-pageid: rest-api__intro -:page-description: This lesson covers the security setup necessary to embed ThoughtSpot into TSE applications. +:page-description: Hands-on tutorial for using ThoughtSpot REST API V2.0 with Python and JavaScript. This tutorial is a hands-on guide to practically working with the ThoughtSpot V2.0 REST API. @@ -15,18 +15,18 @@ Once completed, you will be able to use the ThoughtSpot V2.0 REST API via Python 1. xref:rest-api_lesson-01.adoc[REST API Overview] 2. xref:rest-api_lesson-02.adoc[Simple Python implementation] 3. xref:rest-api_lesson-03.adoc[Complex REST API Workflows] -4. xref:rest-api_lesson-04.adoc[Browser JavaScript REST API implementation] +4. xref:rest-api_lesson-04.adoc[Browser JavaScript REST API implementation] // 5. TypeScript SDK -== Pre-requisites for the tutorial +== Prerequisites for the tutorial Your setup must have the following applications and tools installed: * Chrome or Firefox * Python 3.8 or higher * link:https://code.visualstudio.com/[Visual Studio Code, window=_blank] or link:https://www.jetbrains.com/pycharm/[PyCharm, window=_blank] -* link:https://github.com/thoughtspot/thoughtspot_rest_api_v1_python[The `thoughtspot_rest_api_v1` GitHub repo, window=_blank] library (capable of REST API V1 and V2.0) in your local Python environment +* link:https://github.com/thoughtspot/thoughtspot_rest_api_python[The `thoughtspot_rest_api` GitHub repository, window=_blank] (supports REST API V1 and V2.0) in your local Python environment -Download the entire link:https://github.com/thoughtspot/tse-api-tutorial[tse-api-tutorial directory^] as a ZIP file from GitHub, then unzip on your system: +Download the entire link:https://github.com/thoughtspot/tse-api-tutorial[tse-api-tutorial repository, window=_blank] as a ZIP file from GitHub, then unzip it on your system: [.widthAuto] [.bordered] diff --git a/modules/tutorials/pages/rest-api/rest-api_lesson-02.adoc b/modules/tutorials/pages/rest-api/rest-api_lesson-02.adoc index 84678bf43..3f551f338 100644 --- a/modules/tutorials/pages/rest-api/rest-api_lesson-02.adoc +++ b/modules/tutorials/pages/rest-api/rest-api_lesson-02.adoc @@ -11,7 +11,7 @@ We'll use the files from the link:https://github.com/thoughtspot/tse-api-tutoria . Open your IDE + Visual Studio Code will be used in all images and instructions. -The files for this lesson are `api_training_python_1_begin.py` and `api_training_python_1_end.py` +The files for this lesson are `api_training_python_1_begin.py` and `api_training_python_1_end.py`. . Open up your command line or terminal environment as well. [NOTE] @@ -24,7 +24,7 @@ Please adjust all Python commands according to your own environment. == 01 - Imports and variables At the top of `api_training_python_1_begin.py`, there is a set of *imports* and *variables* that configure the overall script. -=== Import Requests library +=== Import Requests library To issue HTTP commands in a given programming language, you must use a library that sends and receives HTTP. For this lesson, we'll use link:https://requests.readthedocs.io/en/latest/[Requests, window=_blank], the most commonly used high-level HTTP library for Python. @@ -38,11 +38,11 @@ import json ---- ==== Install requests package -If you followed the prerequisites and installed the link:https://github.com/thoughtspot/thoughtspot_rest_api_v1_python[thoughtspot_rest_api_v1 package, window=_blank] using your command line or terminal: +If you followed the prerequisites and installed the link:https://github.com/thoughtspot/thoughtspot_rest_api_python[thoughtspot_rest_api package, window=_blank] using your command line or terminal: [code,bash] ---- -pip install thoughtspot_rest_api_v1 +pip install thoughtspot_rest_api ---- The `requests` package should have automatically been installed along with the other requirements. @@ -57,7 +57,7 @@ pip install requests --upgrade === Set global variables It is very convenient to declare global variables at the beginning of a script so that they can be reused throughout. -The URL of the ThoughtSpot instance is always necessary to send a REST API command, and if the instance has Orgs enabled, you need to send the `org_id` when you request a login token. We'll set those as global variables along with the `api_version` (which hasn't changed ever at this point). +The URL of the ThoughtSpot instance is always necessary to send a REST API command, and if the instance has Orgs enabled, you need to send the `org_id` when you request a login token. We'll set those as global variables along with the `api_version` (which has remained unchanged so far). [,python] ---- @@ -82,13 +82,13 @@ api_headers = { } ---- -== 02 - Use a Session object +== 02 - Use a Session object -Rather than set the full configuration of each HTTP request you make, you can construct a `Session` object from the `requests` library, which an open HTTP connection and maintains settings like headers and cookies between individual HTTP actions. +Rather than setting the full configuration for each HTTP request, you can construct a `Session` object from the `requests` library, which keeps an open HTTP connection and maintains settings like headers and cookies between individual HTTP actions. You send HTTP commands by calling the `.get()`, `.post()`, `.put()` and `.delete()` methods of the `Session` object. -All of those methods will return a Response object, which you assign to a variable to do further processing. This will look something the following: +All of those methods return a Response object, which you assign to a variable for further processing. This will look something like the following: [,python] ---- @@ -109,7 +109,7 @@ resp = requests_session.post(url=url, json=json_post_data) ---- == 03 - Authenticate into ThoughtSpot REST API -There are two ways of establishing authentication with ThoughtSpot's REST API, `cookie-based` with session cookies and `cookieless` using a bearer token in the headers. +There are two ways to establish authentication with ThoughtSpot's REST API: `cookie-based` with session cookies, and `cookieless` using a bearer token in the headers. For backend scripts, we prefer the bearer token approach: @@ -123,8 +123,8 @@ In the REST API V2.0 Playground: . Go to *Authentication* > *Get Full Access Token*. . Specify the parameters. -. Copy the JSON body from the right side of the Playground, Python Dict uses the same syntax, but you must update the booleans to be *uppercase*. -. Replace any of the hard-coded values with the *global variables* you declared so that you can change your requests in an easy way at the top of your script and make sure the values change in all the necessary places: +. Copy the JSON body from the right side of the Playground. Python dicts use the same syntax, but you must update booleans to be *uppercase*. +. Replace any hard-coded values with the *global variables* you declared so that you can easily update requests at the top of your script and ensure those values change everywhere they are used: + [,python] ---- @@ -146,7 +146,7 @@ json_post_data = { We expect a JSON response on success, which you can access using the `.json()` method of the `Response` object. + -From the Playground, we can see that there is `token` property in the response. +From the Playground, we can see that there is a `token` property in the response. . Create a variable for the `token` value to use in the headers as the Bearer token. + @@ -178,7 +178,7 @@ Almost all REST API endpoints other than the token requests require authenticati You need to update the `Session` object with this new header while keeping the original ones. -Use the `token` variable from above to form the exact header to update the original `api_headers` Dict, then use the `.headers.update()` method of the `Session` object: +Use the `token` variable from above to form the exact header to update the original `api_headers` dict, then use the `.headers.update()` method of the `Session` object: [,python] ---- @@ -203,7 +203,7 @@ Python code raises `link:https://docs.python.org/3/tutorial/errors.html[Exceptio If an `Exception` is raised and is not *handled*, the script exits and displays the message provided with the Exception and other details of what failed. -A `try...except block` encloses a set of lines that may result in a known `Exception` in the `try` portion, and then the `except` line defines which `Exception` type to listen for and how to proceed if the `Exception` is thrown. +A `try...except` block encloses a set of lines that may result in a known `Exception` in the `try` portion, and then the `except` line defines which `Exception` type to listen for and how to proceed if the `Exception` is thrown. Every HTTP request can potentially result in an error, and we don't want to continue within the script as planned if the expected action on the ThoughtSpot server did not complete correctly. @@ -227,7 +227,7 @@ The `requests` library does not raise an `Exception` when an HTTP request comple However, as you saw in the previous lesson, HTTP responses include a *Status Code* that indicates if the requested action was a *Success* or an *Error*. -To cause `Exceptions` if the response does not include a *Success* status code, call the `Response.raise_for_status()` method for each call, which will throw the specifc `requests.exceptions.HTTPError` `Exception` when a 400 series or 500 status code is returned: +To raise `Exceptions` when the response does not include a *Success* status code, call the `Response.raise_for_status()` method for each call, which throws the specific `requests.exceptions.HTTPError` `Exception` when a 400 series or 500 status code is returned: [source,python] ---- @@ -269,14 +269,14 @@ json_post_data = { } try: - # requests returns back Response object + # requests returns a Response object resp = requests_session.post(url=url, json=json_post_data) - # This method causes Python Exception to throw if status not 2XX + # This method raises a Python exception if status is not 2XX resp.raise_for_status() - # Retrieve the JSON body of response and convert into Dict - # Some endpoints returns 204 not 200 for success, with no body, will error if you call .json() method + # Retrieve the JSON body of the response and convert it into a dict + # Some endpoints return 204 instead of 200 for success, with no body, which errors if you call .json() resp_json = resp.json() # You can just print(resp_json) to see the Python Dict diff --git a/modules/tutorials/pages/rest-api/rest-api_lesson-03.adoc b/modules/tutorials/pages/rest-api/rest-api_lesson-03.adoc index e3944dbe8..a201ea354 100644 --- a/modules/tutorials/pages/rest-api/rest-api_lesson-03.adoc +++ b/modules/tutorials/pages/rest-api/rest-api_lesson-03.adoc @@ -8,27 +8,27 @@ == Get started The files for this tutorial are `api_training_python_2_begin.py` and `api_training_python_2_end.py`. -You must have installed the `thoughtspot_rest_api_v1` library per the prerequisites at the beginning into the Python environment you are using. Despite the name, the library has components for interacting with both the V1 and V2.0 ThoughtSpot REST APIs. +You must have installed the `thoughtspot_rest_api` library in the Python environment you are using, based on the tutorial prerequisites. Despite the name, the library has components for interacting with both the V1 and V2.0 ThoughtSpot REST APIs. [NOTE] ==== -* You'll need a ThoughtSpot account with administrator privileges to complete the following tutorial. -* We'll create a "Tag" and a "Group" and delete these at the end of the tutorial. +* You'll need a ThoughtSpot account with administrator privileges to complete the following tutorial. +* We'll create a "Tag" and delete it at the end of the tutorial. ==== == 01 - Use ThoughtSpot REST API library -The link:https://github.com/thoughtspot/thoughtspot_rest_api_v1_python[thoughtspot_rest_api_v1 library^] was originally created because the V1 ThoughtSpot REST API is uniformly structured, so a library with an implementation of each endpoint was created as a "reference" on how to format and send each request correctly. +The link:https://github.com/thoughtspot/thoughtspot_rest_api_python[thoughtspot_rest_api library^] was originally created because the V1 ThoughtSpot REST API is uniformly structured, so a library with an implementation of each endpoint was created as a reference for formatting and sending each request correctly. The V2.0 REST API is simple enough to implement in any language. We've just completed the initial steps in Python in the previous lesson. The V2.0 portion of the library implements the repeated standard steps everyone would have to do for themselves each time, and issues can be reported to and fixed in the library once for everyone. -The library encapsulates logic around constructing REST API requests correctly, so that you don’t have to rewrite code. +The library encapsulates logic around constructing REST API requests correctly, so that you don't have to rewrite code. -Endpoints are defined properly, along with HTTP request details and response handling. +Endpoints are defined properly, along with HTTP request details and response handling. -=== Import thoughtspot_rest_api_v1 library -Rather than helper functions like in JavaScript, the *thoughtspot_rest_api_v1* library provides two *classes* that represent the entire set of the two REST API versions: `TSRestApiV1` & `TSRestApiV2`. +=== Import thoughtspot_rest_api library +Rather than helper functions like in JavaScript, the `thoughtspot_rest_api` library provides two *classes* that represent the two REST API versions: `TSRestApiV1` and `TSRestApiV2`. *Classes* define how to build *Objects*, which combine data (called properties) and functions (called methods). @@ -38,7 +38,7 @@ To get started, let's import all of the classes from the library and then create [,python] ---- -from thoughtspot_rest_api_v1 import * +from thoughtspot_rest_api import * username = 'username' password = 'password' @@ -48,11 +48,11 @@ ts: TSRestApiV2 = TSRestApiV2(server_url=server) ---- == 02 - Authentication -The `TSRestApiV2` object doesn’t automatically log in a user. You must explicitly request an authentication token and set the `TSRestApiV2.bearer_token` property: +The `TSRestApiV2` object doesn't automatically log in a user. You must explicitly request an authentication token and set the `TSRestApiV2.bearer_token` property: [,python] ---- -from thoughtspot_rest_api_v1 import * +from thoughtspot_rest_api import * username = 'username' password = 'password' @@ -87,17 +87,17 @@ You'll notice that we've already accomplished everything we did in the previous All of the methods of the `TSRestApiV2` class are named after their equivalent REST endpoints, with an underscore character `_` replacing the forward slashes `/` from the URLs. -For example, `/users/search` endpoint is accessed via `TSRestApiV2.users_search()` method. +For example, the `/users/search` endpoint is accessed via the `TSRestApiV2.users_search()` method. If everything is installed and configured properly in your IDE, you should get auto-complete on the available endpoints as you type: image:images/tutorials/rest-api/autocomplete-in-ide.png[Autocomplete in IDE, width=475, height=229] -For endpoints that have only a few strictly defined arguments, the method will define Python arguments to match the endpoint’s arguments: +For endpoints that have only a few strictly defined arguments, the method will define Python arguments to match the endpoint's arguments: `users_delete(user_identifier:str)` -Endpoints with lots of request options simply take a `request=` argument, which expects a Python Dict matching the JSON request you see in the REST API Playground: +Endpoints with many request options simply take a `request=` argument, which expects a Python Dict matching the JSON request you see in the REST API Playground: image:images/tutorials/rest-api/json-request-format.png[JSON request format in Playground, width=521, height=445] @@ -131,9 +131,9 @@ We'll walk through the process of determining the steps for a sample task, and t Our example task is to *find all Liveboards and Answers with a name that includes '(Sample)' and tag them with the tag called 'Tutorial Test'*. === Define steps -It’s easiest to program by defining the exact requirements, breaking down those requirements into logical steps, and then writing the code accordingly. +It's easiest to program by defining the exact requirements, breaking them down into logical steps, and then writing the code accordingly. -Let’s split the task into discrete steps: +Let's split the task into discrete steps: 1. Find all Liveboards and Answers with a name that includes '(Sample)' 2. Add a tag called 'Tutorial Test' to all of the items @@ -153,7 +153,7 @@ Even this basic step opens up new questions as to what our exact requirements ar # 1. Find all Liveboards and Answers with a name that includes '(Sample)' # Get all of the items with names including '(Sample)' -# Is this a case-sensitive or insensitive operation? Are we finding anywhere in the name or just at start or end? +# Is this a case-sensitive or case-insensitive operation? Are we finding anywhere in the name or just at start or end? # 2. Add a tag to each item called 'Tutorial Test' @@ -199,7 +199,7 @@ The second task is: `Tags` have their own section in the Playground - `/tags/search` will help us find a tag by a particular name. -Look at the description of `tag_identifier` parameter of the request: "Name or Id of the tag". Almost every `_identifier` argument within the API works this way - it can take an object's *GUID* or the *name* property. +Look at the description of the `tag_identifier` parameter in the request: "Name or Id of the tag". Almost every `_identifier` argument within the API works this way - it can take an object's *GUID* or the *name* property. Our comments remind us to consider the situation where the `Tutorial Test` tag does not exist. @@ -235,7 +235,7 @@ search_request = { "type": "ANSWER" }, { - "name_pattern": "Sample)", + "name_pattern": "(Sample)", "type": "LIVEBOARD" } ], @@ -257,16 +257,16 @@ Remember the note about case-sensitivity? We can use Python's string methods to [,python] ---- -# Create List to hold the final set of Answers + Liveboards we want to tag and share -final_list_of_objs =[] +# Create a list to hold the final set of Answers + Liveboards we want to tag and share +final_list_of_objs = [] # Iterate through the results from the API response to double-check that the name value matches exactly for item in metadata_resp: m_name = item["metadata_name"] m_id = item["metadata_id"] - # Python string find is Case-Sensitive + # Python string find is case-sensitive if m_name.find("(Sample)") != -1: - final_list_of_objs.append(item) # We'll add the whole object to the new List + final_list_of_objs.append(item) # We'll add the whole object to the new list # optional print to command line to see what happened print(json.dumps(final_list_of_objs, indent=2)) @@ -274,10 +274,10 @@ print(json.dumps(final_list_of_objs, indent=2)) Next, we'll find the tag to apply using the `/tags/search` endpoint. -You'll notice that the autocomplete for the `TSRestApiV2.tags_search()` method shows defined arguments rather than a generic `request` argument. +You'll notice that the autocomplete for the `TSRestApiV2.tags_search()` method shows defined arguments rather than a generic `request` argument. When an endpoint has very few possibilities, the library often has the full set of arguments available directly. -image:images/tutorials/rest-api/tags-search-autocomplete.png[Assign tag, width=504, height=158] +image:images/tutorials/rest-api/tags-search-autocomplete.png[Tags search autocomplete, width=504, height=158] [source,python] ---- @@ -287,7 +287,7 @@ image:images/tutorials/rest-api/tags-search-autocomplete.png[Assign tag, width=5 # What if there is no tag called 'Tutorial Test'? # -# Find the Tag Identifer so we can assign +# Find the Tag Identifier so we can assign it # Create new Tag if it doesn't exist # try: @@ -318,7 +318,7 @@ else: Finally, we'll take the tag ID and the objects whose names matched and apply the tag. -Let's go back to the Playground to copy the request. Remember that the `metadata` section is not a simple array, but an array of objects: +Let's go back to the Playground to copy the request. Remember that the `metadata` section is not a simple array, but an array of objects: [,python] ---- @@ -344,10 +344,10 @@ We'll need to create the data structure that the `metadata` parameter needs by i try: # When we copied from the Playground, the format of the `metadata` section is an array of objects, - # which needs to be a List of Dicts in Python syntax [ {"identifier": metadata_id}, ...] - + # which needs to be a list of Dicts in Python syntax [ {"identifier": metadata_id}, ...] + tag_metadata_section = [] - # Iterate through each object and make the Dict in create format + # Iterate through each object and construct the Dict in the correct format for obj in final_list_of_objs: tag_metadata_section.append({"identifier" : obj['metadata_id']}) @@ -356,7 +356,7 @@ try: "tag_identifiers": [tag_id] } - assign_resp = ts.tags_assign(requst=assign_req) + assign_resp = ts.tags_assign(request=assign_req) except requests.exceptions.HTTPError as e: print("Error from the API: ") print(e) @@ -366,12 +366,12 @@ except requests.exceptions.HTTPError as e: == 05 - Conclusion -After completing these lessons, you should be very capable at using the REST API V2.0 Playground and the link:https://github.com/thoughtspot/thoughtspot_rest_api_v1_python[thoughtspot_rest_api_v1 library^] to retrieve and process the results of the `/search` endpoints and then issue other commands using the IDs of objects. +After completing these lessons, you should be very capable at using the REST API V2.0 Playground and the link:https://github.com/thoughtspot/thoughtspot_rest_api_python[thoughtspot_rest_api library^] to retrieve and process the results of the `/search` endpoints and then issue other commands using the IDs of objects. By moving hard-coded values into variables, you can develop reusable scripts to accomplish tasks that otherwise would require a lot of manual effort. -There are many link:https://github.com/thoughtspot/thoughtspot_rest_api_v1_python/tree/main/examples_v2[existing examples^] of workflows that can be pieced together to accomplish any number of administration and integration tasks. +There are many link:https://github.com/thoughtspot/thoughtspot_rest_api_python/tree/main/examples_v2[existing examples^] of workflows that can be pieced together to accomplish any number of administration and integration tasks. ''' -xref:rest-api_lesson-02.adoc[< Back: 02 - Simple Python Implementation of V2.0 REST API]| xref:rest-api_lesson-04.adoc[Next: 04 - Browser JavaScript REST API implementation >] +xref:rest-api_lesson-02.adoc[< Back: 02 - Simple Python implementation of V2.0 REST API] | xref:rest-api_lesson-04.adoc[Next: 04 - Browser JavaScript REST API implementation >] diff --git a/scripts/Converter/index.ts b/scripts/Converter/index.ts index 05a35fb45..8742111e2 100644 --- a/scripts/Converter/index.ts +++ b/scripts/Converter/index.ts @@ -758,7 +758,7 @@ class TypeDocParser { let content = ''; if (node.indexSignature?.parameters) { content += 'Index Signature Parameters\n\n'; - node.indexSignature.parameters + content += node.indexSignature.parameters .map(this.convertTypeDocNode) .join('\n\n'); } else if (node.signatures) { @@ -771,7 +771,11 @@ class TypeDocParser { }); } else if (node.children) { content += 'Parameters\n\n'; - content += node.children.map(this.convertTypeDocNode).join('\n\n'); + content += node.children + .map((child) => + this.handleParameterNode(child as ParameterNode), + ) + .join('\n\n'); } return content; diff --git a/src/components/DevDocTemplate/index.tsx b/src/components/DevDocTemplate/index.tsx index 03d1b953e..c432d67b2 100644 --- a/src/components/DevDocTemplate/index.tsx +++ b/src/components/DevDocTemplate/index.tsx @@ -337,6 +337,7 @@ const DevDocTemplate: FC = (props) => { const customStyles = { overlay: { background: 'rgba(50,57,70, 0.9)', + zIndex: 10, }, content: { top: '50px', diff --git a/src/components/Document/helper.tsx b/src/components/Document/helper.tsx index 1e5050a85..a1351b3fc 100644 --- a/src/components/Document/helper.tsx +++ b/src/components/Document/helper.tsx @@ -51,6 +51,44 @@ export const customizeDocContent = () => { wrapperDiv.appendChild(buttonElement); tag.parentElement.appendChild(wrapperDiv); }); + /* Add copy buttons to marked table cells */ + document + .querySelectorAll('.copy-cell-table table, table.copy-cell-table') + .forEach((table) => { + (table as HTMLElement) + .querySelectorAll('tbody tr td:nth-child(2)') + .forEach((cell) => { + const cellElement = cell as HTMLElement; + if (cellElement.querySelector('.tableCopyButton')) { + return; + } + cellElement.classList.add('tableCopyCell'); + const contentWrapper = document.createElement('div'); + contentWrapper.classList.add('tableCopyContent'); + while (cellElement.firstChild) { + contentWrapper.appendChild(cellElement.firstChild); + } + cellElement.appendChild(contentWrapper); + const buttonElement = document.createElement('button'); + buttonElement.setAttribute('class', 'tableCopyButton'); + buttonElement.setAttribute( + 'aria-label', + t('CODE_COPY_BTN_HOVER_TEXT'), + ); + buttonElement.setAttribute( + 'title', + t('CODE_COPY_BTN_HOVER_TEXT'), + ); + enableCopyToClipboard(buttonElement, contentWrapper); + const imageElement = document.createElement('span'); + imageElement.innerHTML = getHTMLFromComponent( + , + 'copyIcon', + ); + buttonElement.appendChild(imageElement); + cellElement.appendChild(buttonElement); + }); + }); /* To highlight code snippets */ document.querySelectorAll('pre code').forEach((block) => { hljs.highlightBlock(block as HTMLElement); diff --git a/src/components/Document/index.scss b/src/components/Document/index.scss index 06623644c..ff4d74ec1 100644 --- a/src/components/Document/index.scss +++ b/src/components/Document/index.scss @@ -165,6 +165,7 @@ background-color: var(--table-header-color); position: sticky; top: 0; + z-index: 2; } td { @@ -179,6 +180,34 @@ margin: 3px 0; } } + .tableCopyCell { + position: relative; + padding-right: calc(#{$padding-md} + 54px); + + .tableCopyButton { + position: absolute; + top: 6px; + right: 6px; + border: 0; + background: transparent; + padding: 2px; + opacity: 0; + visibility: hidden; + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 12px; + color: var(--secondary-color); + } + + &:hover .tableCopyButton, + .tableCopyButton:focus, + .tableCopyButton:focus-visible { + opacity: 1; + visibility: visible; + } + } tr { border-bottom: 1px solid var(--border-color-tr); @@ -191,6 +220,24 @@ } } + .prompt-guidance-table table td, + table.prompt-guidance-table td { + padding-right: $padding-xs; + } + + .prompt-guidance-table table td.tableCopyCell, + table.prompt-guidance-table td.tableCopyCell { + padding-right: calc(#{$padding-xs} + 52px); + } + + .prompt-guidance-table table .tableCopyCell .tooltiptext, + table.prompt-guidance-table .tableCopyCell .tooltiptext { + color: #2770ef; + font-size: $font-size-table; + font-family: $font-family-doc; + font-weight: $font-weight-normal; + } + h2 { diff --git a/src/configs/doc-configs.js b/src/configs/doc-configs.js index 96855667b..a1aae27ed 100644 --- a/src/configs/doc-configs.js +++ b/src/configs/doc-configs.js @@ -19,11 +19,11 @@ module.exports = { 'is now available. Read about the new features and enhancements.', // Swap this between: // - Pre-GA: release-specific URL (full http(s) URL), ex: - // 'https://developers.thoughtspot.com/docs/26.2.0.cl?pageid=whats-new' + // 'https://developers.thoughtspot.com/docs/26.3.0.cl?pageid=whats-new' // - GA: ' /docs/whats-new' //linkHref: '/docs/whats-new', - linkHref: '/docs/26.2.0.cl?pageid=whats-new', - linkText: 'Version 26.2.0.cl', + linkHref: '/docs/26.3.0.cl?pageid=whats-new', + linkText: 'Version 26.3.0.cl', openInNewTab: true, }, TYPE_DOC_PREFIX: 'typedoc', @@ -48,9 +48,22 @@ module.exports = { }, VERSION_DROPDOWN: [ { - label: '10.15.0.cl', + label: '26.2.0.cl', link: ' ', subLabel: 'Cloud (Latest)', + iframeUrl: 'https://developer-docs-26-2-0-cl.vercel.app/docs/', + }, + { + label: '26.3.0.cl', + link: '26.3.0.cl', + subLabel: 'Cloud (Coming soon)', + iframeUrl: 'https://developer-docs-26-3-0-cl.vercel.app/docs/', + }, + { + label: '10.15.0.cl', + link: '10.15.0.cl', + subLabel: 'Cloud', + iframeUrl: 'https://developer-docs-10-15-0-cl.vercel.app/docs/', }, { label: '10.14.0.cl', @@ -76,12 +89,6 @@ module.exports = { subLabel: 'Software', iframeUrl: 'https://visual-embed-sdk-10-1.vercel.app/docs/', }, - { - label: '26.2.0.cl', - link: '26.2.0.cl', - subLabel: 'Coming soon', - iframeUrl: 'https://developer-docs-26-2-0-cl.vercel.app/docs/', - }, ], CUSTOM_PAGE_ID: { API_PLAYGROUND: 'restV2-playground', diff --git a/static/doc-images/images/agents-mcp-server-arch.png b/static/doc-images/images/agents-mcp-server-arch.png new file mode 100644 index 000000000..fc21c959c Binary files /dev/null and b/static/doc-images/images/agents-mcp-server-arch.png differ diff --git a/static/doc-images/images/answer-chart-toggle-custom.png b/static/doc-images/images/answer-chart-toggle-custom.png new file mode 100644 index 000000000..b293cd446 Binary files /dev/null and b/static/doc-images/images/answer-chart-toggle-custom.png differ diff --git a/static/doc-images/images/answer-chart-toggle.png b/static/doc-images/images/answer-chart-toggle.png new file mode 100644 index 000000000..1316574a7 Binary files /dev/null and b/static/doc-images/images/answer-chart-toggle.png differ diff --git a/static/doc-images/images/chart-selection-icon-custom.png b/static/doc-images/images/chart-selection-icon-custom.png new file mode 100644 index 000000000..334465ec9 Binary files /dev/null and b/static/doc-images/images/chart-selection-icon-custom.png differ diff --git a/static/doc-images/images/chart-selection-icon.png b/static/doc-images/images/chart-selection-icon.png new file mode 100644 index 000000000..f8dfa07e9 Binary files /dev/null and b/static/doc-images/images/chart-selection-icon.png differ diff --git a/static/doc-images/images/cursor-chat-response.mp4 b/static/doc-images/images/cursor-chat-response.mp4 new file mode 100644 index 000000000..dcfe07340 Binary files /dev/null and b/static/doc-images/images/cursor-chat-response.mp4 differ diff --git a/static/doc-images/images/cursor-chat-session.mp4 b/static/doc-images/images/cursor-chat-session.mp4 new file mode 100644 index 000000000..89224a63b Binary files /dev/null and b/static/doc-images/images/cursor-chat-session.mp4 differ diff --git a/static/doc-images/images/cursor-chat-session2.mp4 b/static/doc-images/images/cursor-chat-session2.mp4 new file mode 100644 index 000000000..059fd226b Binary files /dev/null and b/static/doc-images/images/cursor-chat-session2.mp4 differ diff --git a/static/doc-images/images/cursor-chat.mp4 b/static/doc-images/images/cursor-chat.mp4 new file mode 100644 index 000000000..059fd226b Binary files /dev/null and b/static/doc-images/images/cursor-chat.mp4 differ diff --git a/static/doc-images/images/cursor-lb-embed.mp4 b/static/doc-images/images/cursor-lb-embed.mp4 new file mode 100644 index 000000000..3ff19ae31 Binary files /dev/null and b/static/doc-images/images/cursor-lb-embed.mp4 differ diff --git a/static/doc-images/images/cursor_mcp-skills.mp4 b/static/doc-images/images/cursor_mcp-skills.mp4 new file mode 100644 index 000000000..a79d95c9b Binary files /dev/null and b/static/doc-images/images/cursor_mcp-skills.mp4 differ diff --git a/static/doc-images/images/favoritesV3.png b/static/doc-images/images/favoritesV3.png new file mode 100644 index 000000000..d70b3d0c4 Binary files /dev/null and b/static/doc-images/images/favoritesV3.png differ diff --git a/static/doc-images/images/homepageV3vsV2.png b/static/doc-images/images/homepageV3vsV2.png new file mode 100644 index 000000000..11f0e44a8 Binary files /dev/null and b/static/doc-images/images/homepageV3vsV2.png differ diff --git a/static/doc-images/images/mcp-skills.png b/static/doc-images/images/mcp-skills.png new file mode 100644 index 000000000..e9dabc46c Binary files /dev/null and b/static/doc-images/images/mcp-skills.png differ diff --git a/static/doc-images/images/rd-icon-chart-column.svg b/static/doc-images/images/rd-icon-chart-column.svg new file mode 100644 index 000000000..9f0cd2ecf --- /dev/null +++ b/static/doc-images/images/rd-icon-chart-column.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/doc-images/images/rd-icon-chart-type-settings.svg b/static/doc-images/images/rd-icon-chart-type-settings.svg new file mode 100644 index 000000000..40dc85ef4 --- /dev/null +++ b/static/doc-images/images/rd-icon-chart-type-settings.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/static/doc-images/images/spotter-embed-legacy.png b/static/doc-images/images/spotter-embed-legacy.png new file mode 100644 index 000000000..45fe13945 Binary files /dev/null and b/static/doc-images/images/spotter-embed-legacy.png differ diff --git a/static/doc-images/images/spotter3-leagcy-interface-automode.png b/static/doc-images/images/spotter3-leagcy-interface-automode.png new file mode 100644 index 000000000..3e05cf10b Binary files /dev/null and b/static/doc-images/images/spotter3-leagcy-interface-automode.png differ diff --git a/static/doc-images/images/spotter3-legacy-interface.png b/static/doc-images/images/spotter3-legacy-interface.png new file mode 100644 index 000000000..581f1aaeb Binary files /dev/null and b/static/doc-images/images/spotter3-legacy-interface.png differ diff --git a/static/doc-images/images/spotter3-new-interface.png b/static/doc-images/images/spotter3-new-interface.png new file mode 100644 index 000000000..cd9b1676b Binary files /dev/null and b/static/doc-images/images/spotter3-new-interface.png differ diff --git a/static/doc-images/images/spotter3-new-interface_auto-mode.png b/static/doc-images/images/spotter3-new-interface_auto-mode.png new file mode 100644 index 000000000..b8ce7a452 Binary files /dev/null and b/static/doc-images/images/spotter3-new-interface_auto-mode.png differ diff --git a/static/doc-images/images/spottercode-embed.png b/static/doc-images/images/spottercode-embed.png new file mode 100644 index 000000000..746765437 Binary files /dev/null and b/static/doc-images/images/spottercode-embed.png differ diff --git a/static/doc-images/images/spottercode-prompt-response.png b/static/doc-images/images/spottercode-prompt-response.png new file mode 100644 index 000000000..ef7fab6a8 Binary files /dev/null and b/static/doc-images/images/spottercode-prompt-response.png differ diff --git a/static/doc-images/images/spottercode-response-2.png b/static/doc-images/images/spottercode-response-2.png new file mode 100644 index 000000000..925061ce0 Binary files /dev/null and b/static/doc-images/images/spottercode-response-2.png differ diff --git a/static/doc-images/images/spottercode-response.png b/static/doc-images/images/spottercode-response.png new file mode 100644 index 000000000..205a7da7e Binary files /dev/null and b/static/doc-images/images/spottercode-response.png differ diff --git a/static/doc-images/images/spottercode-response3.png b/static/doc-images/images/spottercode-response3.png new file mode 100644 index 000000000..f9ffc704a Binary files /dev/null and b/static/doc-images/images/spottercode-response3.png differ diff --git a/static/doc-images/images/spottercode-response4.png b/static/doc-images/images/spottercode-response4.png new file mode 100644 index 000000000..6c34fca98 Binary files /dev/null and b/static/doc-images/images/spottercode-response4.png differ diff --git a/static/doc-images/images/spottercode-skill-selection.png b/static/doc-images/images/spottercode-skill-selection.png new file mode 100644 index 000000000..c16a1d8f2 Binary files /dev/null and b/static/doc-images/images/spottercode-skill-selection.png differ diff --git a/static/doc-images/images/trendingv2andv3.png b/static/doc-images/images/trendingv2andv3.png new file mode 100644 index 000000000..a2e4f8c82 Binary files /dev/null and b/static/doc-images/images/trendingv2andv3.png differ diff --git a/static/doc-images/images/watchlistv3andv2.png b/static/doc-images/images/watchlistv3andv2.png new file mode 100644 index 000000000..d1776ccc9 Binary files /dev/null and b/static/doc-images/images/watchlistv3andv2.png differ diff --git a/static/svgs/rd-icon-chart-column.svg b/static/svgs/rd-icon-chart-column.svg new file mode 100644 index 000000000..3258520ae --- /dev/null +++ b/static/svgs/rd-icon-chart-column.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/static/svgs/rd-icon-chart-type-settings.svg b/static/svgs/rd-icon-chart-type-settings.svg new file mode 100644 index 000000000..d04c6d8e0 --- /dev/null +++ b/static/svgs/rd-icon-chart-type-settings.svg @@ -0,0 +1,6 @@ + + + + + +